This is 3DLDF.info, produced by makeinfo version 4.5 from 3DLDF.texi.

This is the 3DLDF User and Reference Manual, edition 1.1.5 for 3DLDF
1.1.5.  This manual was last updated on 14 January 2004.  3DLDF is a
GNU package for three-dimensional drawing with MetaPost output.  The
author is Laurence D. Finston.

   Copyright (C) 2003, 2004 Laurence D. Finston.

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License,
     Version 1.2 or any later version published by the Free Software
     Foundation; with no Invariant Sections, no Front-Cover Texts, and
     no Back-Cover Texts.  A copy of the license is included in the
     section entitled "GNU Free Documentation License".
   
INFO-DIR-SECTION GNU packages
START-INFO-DIR-ENTRY
* 3DLDF: (3DLDF).            3D drawing with MetaPost output.
END-INFO-DIR-ENTRY


File: 3DLDF.info,  Node: Endianness,  Next: Register Width,  Prev: System Information,  Up: System Information

Endianness
==========

 - Function: signed short get_endianness ([const bool VERBOSE =
          `false'])
     Returns the following values:

    0
          if the processor is little-endian.

    1
          if the processor is big-endian.

    -1
          if the endianness cannot be determined.


     It is called by `is_little_endian()' and `is_big_endian()'.

     If VERBOSE is `true', messages are printed to standard output.

     This function has been adapted from Harbison, Samuel P., and
     Guy L. Steele Jr.  `C, A Reference Manual', pp. 163-164.  This
     book has the clearest explanation of endianness that I've found so
     far.

     This is the C++  code:

          signed short
          System::get_endianness(const bool verbose)
          {
            union {
              long Long;
              char Char[sizeof(long)];
            } u;
            u.Long = 1;
            if (u.Char[0] == 1)
              {
                if (verbose)
                  cout << "Processor is little-endian."
                       << endl << endl << flush;
                return 0;
              }
            else if (u.Char[sizeof(long) - 1] == 1)
              {
                if (verbose)
                  cout << "Processor is big-endian."
                       << endl << endl << flush;
                return 1;
              }
            else
              {
                cerr << "ERROR! In System::get_endianness():\n"
                     << "Can't determine endianness. Returning -1"
                     << endl << endl << flush;
                return -1;
              }
          }

 - Function: bool is_big_endian ([const bool VERBOSE = `false'])
     Returns `true' if the processor is big-endian, otherwise `false'.
     If VERBOSE is `true', messages are printed to standard output.

 - Function: bool is_little_endian ([const bool VERBOSE = `false'])
     Returns `true' if the processor is little-endian, otherwise
     `false'.  If VERBOSE is `true', messages are printed to standard
     output.


File: 3DLDF.info,  Node: Register Width,  Next: Get Second Largest Real,  Prev: Endianness,  Up: System Information

Register Width
==============

 - Function: unsigned short get_register_width (void)
     Returns the register width of the CPU of the system on which 3DLDF
     is being run.  This will normally be either 32 or 64 bits.

     This is the C++  code:

          return (sizeof(void*) * CHAR_BIT);

     This assumes that an address will be the same size as the
     processor's registers, and that `CHAR_BIT' will be the number of
     bits in a byte.  These are reasonable assumptions that apply to
     all architectures I know about.

     This function is called by `is_32_bit()' and `is_64_bit()'.

 - Function: bool is_32_bit (void)
     Returns `true' if the CPU of the system on which 3DLDF is being run
     has a register width of 32 bits, otherwise `false'.

 - Function: bool is_64_bit (void)
     Returns `true' if the CPU of the system on which 3DLDF is being run
     has a register width of 64 bits, otherwise `false'.


File: 3DLDF.info,  Node: Get Second Largest Real,  Prev: Register Width,  Up: System Information

Get Second Largest Real
=======================

 - Template function: template <class Real> Real get_second_largest
          (Real MAX_VAL, [bool VERBOSE = `false'])
 - Template specialization: float get_second_largest (float, bool)
 - Template specialization: double get_second_largest (double, bool)
     `get_second_largest' returns the second largest floating point
     number of the type specified the template paramater REAL.  If
     VERBOSE is `true', messages are printed to standard output.

     This function is used for setting the value of `MAX_REAL'.  *Note
     Global Constants and Variables::.

     `get_second_largest' depends on there being an unsigned integer
     type with the same length as REAL.  This should always be the case
     for `float' and `double', but may not be `long double'.

     MAX_VAL should be the largest number of type REAL on a given
     architecture.  The GNU C++  compiler GCC 3.3 does not currently
     supply the `numeric_limits' template, so it is necessary to pass
     one of the macros `FLT_MAX' or `DBL_MAX' explicitly, depending on
     which specialization you use(1).  When and if GCC supplies the
     `numeric_limits' template, I will eliminate the MAX_REAL argument.

   ---------- Footnotes ----------

   (1) If your system supplies an unsigned integer type with the same
length as `long double', then you can instantiate
`get_second_largest<long double>()' and call `get_second_largest<long
double>(LDBL_MAX)'.  However, I doubt that this amount of precision
would be worthwhile.  If it ever were required, 3DLDF would have to be
changed in other ways, too.  In particular, it would have to use more
precise trigonometric functions for rotations.  *Note Accuracy::.


File: 3DLDF.info,  Node: Color Reference,  Next: Input and Output,  Prev: System Information,  Up: Top

Color Reference
***************

   Class `Color' is defined in `colors.web'.

* Menu:

* Color Data Members::
* Color Constructors and Setting Functions::
* Color Operators::
* Modifying Colors::
* Showing Colors::
* Querying Colors::
* Defining and Initializing Colors::
* Namespace Colors::


File: 3DLDF.info,  Node: Color Data Members,  Next: Color Constructors and Setting Functions,  Prev: Color Reference,  Up: Color Reference

Data Members
============

 - Variable: string name
     The name of the `Color'.

 - Variable: bool use_name
     If `true', `name' is written to `out_stream' when the `Color' is
     used for drawing or filling.  Otherwise, the RGB (red-green-blue)
     values are written to `out_stream'.

 - Variable: bool on_free_store
     `true', if the `Color' has been created by `create_new<Color>()',
     which allocates memory for the `Color' on the free store.
     Otherwise `false'.  `Colors' should only ever be dynamically
     allocated by using `create_new<Color>()'.  *Note Color
     Reference;;Constructors and Setting Functions: Color Constructors
     and Setting Functions.

 - Variable: real red_part
 - Variable: real green_part
 - Variable: real blue_part
     The RGB (red-green-blue) values of the `Color'.  A `real' value r
     is valid for these variables if and only if 0 <= r <= 1.


File: 3DLDF.info,  Node: Color Constructors and Setting Functions,  Next: Color Operators,  Prev: Color Data Members,  Up: Color Reference

Constructors and Setting Functions
==================================

 - Default constructor: void Color (void)
     Creates a `Color' and initializes its `red_part', `green_part',
     and `blue_part' to 0.  `use_name' and `on_free_store' are set to
     `false'.

 - Copy constructor: void Color (const Color& C, [const string N = "",
          [const bool U = `true']])
     Creates a `Color' and makes it a copy of C.  If N is not the empty
     string and U is `true', `use_name' is set to `true'.  Otherwise,
     its set to `false'.

 - Constructor: void Color (const string N, const unsigned short R,
          const unsigned short G, const unsigned short B, [const bool U
          = `true'])
     Creates a `Color' with name N.  Its `red_part', `green_part', and
     `blue_part' are set to r/255.0, g/255.0, and b/255.0, respectively.
     `use_name' is set to U.

 - Setting function: void set (const string N, const unsigned short R,
          const unsigned short G, const unsigned short B, [const bool U
          = `false'])
     Corresponds to the constructor above, except that U is `false' by
     default.

 - Constructor: void Color (const real R, const real G, const real B)
     Creates an unnamed `Color' using the `real' values R, G, and B for
     its `red_part', `green_part', and `blue_part', respectively.

 - Setting function: void set (const real R, const real G, const real B)
     Corresponds to the constructor above.

 - Template specializations: Color* create_new<Color> (const Color* C)
 - : Color* create_new<Color> (const Color& C)
     Pseudo-constructors for dynamic allocation of `Colors'.  They
     create a `Color' on the free store and allocate memory for it using
     `new(Color)'.  They return a pointer to the new `Color'.

     If C is a non-zero pointer or a reference, the new `Color' will be
     a copy of C.  If the new object is not meant to be a copy of an
     existing one, `0' must be passed to `create_new<Color>()' as its
     argument.  *Note Dynamic Allocation of Shapes::, for more
     information.

     This function is used in the drawing and filling functions for
     `Path' and `Solid'.  `Point::drawdot()' should be changed to use
     it too, but I haven't gotten around to doing this yet.


File: 3DLDF.info,  Node: Color Operators,  Next: Modifying Colors,  Prev: Color Constructors and Setting Functions,  Up: Color Reference

Operators
=========

 - Assignment operator: void operator= (const Color& C)
     Sets `name' to the empty `string', `use_name' to `false', and
     `red_part', `green_part', and `blue_part' to C.`red_part',
     C.`green_part', and C.`blue_part', respectively.

 - `const' operator: bool operator== (const Color& C)
     Equality operator.  Returns `true', if the `red_parts',
     `green_parts', and `blue_parts' of `*this' and C are equal,
     otherwise `false'.  The `names' and `use_names' are not compared.

 - `const' operator: bool operator!= (const Color& C)
     Inequality operator.  Returns `false', if the `red_parts',
     `green_parts', and `blue_parts' of `*this' and C are equal,
     otherwise `true'.  The  `names' and `use_names' are not compared.

 - Non-member function: ostream& operator<< (ostream& O, const Color& C)
     Output operator.  Writes the MetaPost code for the `Color' to
     `out_stream' when a `Picture' is output.  This occurs when the
     `Color' has been used as an argument to drawing or filling
     functions.

     If `use_name' is `true', `name' is written to `out_stream'.
     Otherwise, "(`red_part', `green_part', `blue_part')" is written to
     `out_stream'.


File: 3DLDF.info,  Node: Modifying Colors,  Next: Showing Colors,  Prev: Color Operators,  Up: Color Reference

Modifying
=========

 - Function: void set_name (const string S)
     Sets `name' to S.  `use_name' is not reset.

 - Function: void set_use_name (const bool B)
     Sets `use_name' to B.

 - Function: void modify (const real R, [const real G = 0, [const real
          B = 0]])
     Adds R, G, and B to `red_part', `green_part', and `blue_part',
     respectively.  Following the addition, if `red_part',
     `green_part', and/or `blue_part' is greater than 1, it is reduced
     to 1.  If it is less than 0, it is increased to 0.

 - Function: void set_red_part (const real Q)
 - Function: void set_green_part (const real Q)
 - Function: void set_blue_part (const real Q)
     Let p stand for `red_part', `green_part', or `blue_part',
     depending upon which function is used.  If 0 <= q <= 1, p is set
     to q.  If q < 0, p is set to 0.  If q > 1, p is set to 1.


File: 3DLDF.info,  Node: Showing Colors,  Next: Querying Colors,  Prev: Modifying Colors,  Up: Color Reference

Showing
=======

 - `const' function: void show ([string TEXT = ""])
     Prints information about the `Color' to standard output.  If TEXT
     is not the empty `string', prints TEXT on a line of its own.
     Otherwise, it prints "Color:".  Then it prints `name', `use_name',
     `red_part', `green_part', and `blue_part'.


File: 3DLDF.info,  Node: Querying Colors,  Next: Defining and Initializing Colors,  Prev: Showing Colors,  Up: Color Reference

Querying
========

 - `const' function: bool is_on_free_store (void)
     Returns `on_free_store'.  This will only be true, if the `Color'
     was created by `create_new<Color>()'.  *Note Color Reference;
     Constructors and Setting Functions: Color Constructors and Setting
     Functions.

 - Inline `const' function: real get_red_part ([bool DECIMAL = `false'])
 - Inline `const' function: real get_green_part ([bool DECIMAL =
          `false'])
 - Inline `const' function: real get_blue_part ([bool DECIMAL =
          `false'])
     These functions return the `red_part', `green_part', or
     `blue_part' of the `Color', respectively.  If DECIMAL is `false'
     (the default), the actual `real' value of the "part" is returned.
     Otherwise, the corresponding whole number n such that 0 <= n <= 255
     is returned.

 - `const' function: bool get_use_name (void)
     Returns `use_name'.

 - Inline `const' function: string get_name (void)
     Returns `name'.


File: 3DLDF.info,  Node: Defining and Initializing Colors,  Next: Namespace Colors,  Prev: Querying Colors,  Up: Color Reference

Defining and Initializing Colors
================================

 - `const' function: void define_color_mp ()
     Writes MetaPost code to `out_stream', in order to define objects of
     type  `color' within MetaPost, and set their `redparts',
     `greenparts', and `blueparts'.

 - Static function: void initialize_colors (void)
     Calls `define_color_mp()' (described above) for the `Colors' that
     are defined in `namespace Colors' (*note Namespace Colors::).


File: 3DLDF.info,  Node: Namespace Colors,  Prev: Defining and Initializing Colors,  Up: Color Reference

Namespace Colors.
=================

 - Constant: const Color red
 - Constant: const Color green
 - Constant: const Color blue
 - Constant: const Color cyan
 - Constant: const Color yellow
 - Constant: const Color magenta
 - Constant: const Color orange_red
 - Constant: const Color violet_red
 - Constant: const Color pink
 - Constant: const Color green_yellow
 - Constant: const Color orange
 - Constant: const Color violet
 - Constant: const Color purple
 - Constant: const Color blue_violet
 - Constant: const Color yellow_green
 - Constant: const Color black
 - Constant: const Color white
 - Constant: const Color gray
 - Constant: const Color light_gray
     These constant `Colors' can be used in drawing and filling
     commands.

 - Constant: const Color default_background
     The default background color.  Equal to `white' per default.

 - Pointer: const Color* background_color
     Points to `default_background' by default.

 - Pointer: const Color* default_color
     Points to `black' by default.

 - Pointer: const Color* help_color
     Points to `green' by default.

   The following vectors of pointers to `Color' can be used in the
drawing and filling functions for `Solid' (*note Solid Reference;
Drawing and Filling: Drawing and Filling Solids.).

 - Vector: const vector <const Color*> default_color_vector
     Contains one pointer, namely `default_color'.

 - Vector: const vector <const Color*> help_color_vector
     Contains one pointer, namely `help_color'.

 - Vector: const vector <const Color*> background_color_vector
     Contains one pointer, namely `background_color'.


File: 3DLDF.info,  Node: Input and Output,  Next: Shape Reference,  Prev: Color Reference,  Up: Top

Input and Output
****************

* Menu:

* I/O Global Variables::
* I/O Functions::


File: 3DLDF.info,  Node: I/O Global Variables,  Next: I/O Functions,  Prev: Input and Output,  Up: Input and Output

Global Variables
================

 - Variable: ifstream in_stream
     Intended for inputting files of input code.  However, 3DLDF does
     not currently have a routine for reading input code.  `in_stream'
     is currently attached to the file `ldfinput.ldf' by
     `initialize_io()' (*note I/O Functions::).  `in_stream' is read in
     character-by-character in `main()', however this serves no useful
     purpose as yet.

 - Variable: ofstream out_stream
     Used for writing the file of MetaPost code, which is 3DLDF's
     output.  Currently attached to the file `subpersp.mp' by
     `initialize_io()' (*note I/O Functions::).

 - Variable: ofstream tex_stream
     TeX code can be written to a file through `tex_stream', if
     desired.  3DLDF makes no use of it itself.  Currently attached to
     `subpersp.tex' by `initialize_io()' (*note I/O Functions::).


File: 3DLDF.info,  Node: I/O Functions,  Prev: I/O Global Variables,  Up: Input and Output

I/O Functions
=============

 - Function: void initialize_io (string IN_STREAM_NAME, string
          OUT_STREAM_NAME, string TEX_STREAM_NAME, char* PROGRAM_NAME)
     Opens files with names specified by the first three arguments, and
     attaches them to the file streams `in_stream', `out_stream', and
     `tex_stream', respectively.  Comments are written at the beginning
     of the files, containing their names, a datestamp, and the name of
     the program used to generate them.

 - Function: void write_footers (void)
     Writes code at the end of the files attached to `in_stream',
     `out_stream', and `tex_stream', before the streams are closed.
     Currently, they write comments containing local variable lists for
     use in Emacs.

 - Inline function: void beginfig (unsigned short I)
     Writes "`beginfig(I)'" to `out_stream'.

 - Inline function: void endfig ([unsigned short I = 0])
     Writes "`endfig()'" to `out_stream'.  The argument I is "syntactic
     sugar";  it's ignored by `endfig()', but may help the user keep
     track of what figure is being ended.


File: 3DLDF.info,  Node: Shape Reference,  Next: Transform Reference,  Prev: Input and Output,  Up: Top

Shape Reference
***************

   Class `Shape' is defined in `shapes.web'.

   `Shape' is an "abstract class", which means that all of its member
functions are pure virtual functions, and that it's only used as a base
class, i.e., no objects of type `Shape' may be declared.

   All of the "drawable" types in 3DLDF, `Point', `Path', `Ellipse',
etc., are derived from `Shape'.

   Deriving all of the drawable types from `Shape' makes it possible to
handle objects of different types in the same way.  This is especially
important in the `Picture' functions, where objects of various types
(but all derived from `Shape') are accessed through pointers to
`Shape'.  *Note Picture Reference::.

* Menu:

* Shape Data Members::
* Shape Operators::
* Copying Shapes::
* Modifying Shapes::
* Affine Transformations for Shapes::
* Applying Transformations to Shapes::
* Clearing Shapes::
* Querying Shapes::
* Showing Shapes::
* Outputting Shapes::


File: 3DLDF.info,  Node: Shape Data Members,  Next: Shape Operators,  Prev: Shape Reference,  Up: Shape Reference

Data Members
============

 - Protected static constants: signed short DRAWDOT
 - : signed short DRAW
 - : signed short FILL
 - : signed short FILLDRAW
 - : signed short UNDRAWDOT
 - : signed short UNDRAW
 - : signed short UNFILL
 - : signed short UNFILLDRAW
     Values used in the `output()' functions of the classes derived from
     `Shape'.  For example, in `Path', if the data member
     `fill_draw_value' = `DRAW', then the MetaPost command `draw' is
     written to `out_stream' when that `Path' is output.


File: 3DLDF.info,  Node: Shape Operators,  Next: Copying Shapes,  Prev: Shape Data Members,  Up: Shape Reference

Operators
=========

 - Pure virtual function: Transform operator*= (const Transform& T)


File: 3DLDF.info,  Node: Copying Shapes,  Next: Modifying Shapes,  Prev: Shape Operators,  Up: Shape Reference

Copying
=======

 - `const' pure virtual function: Shape* get_copy (void)
     Copies an object, allocating memory on the free store for the copy,
     and returns a pointer to `Shape' for accessing the copy.

     Used in the drawing and filling functions for copying the `Shape',
     and putting a pointer to the copy onto the `vector<Shape*> shapes'
     of the `Picture'.


File: 3DLDF.info,  Node: Modifying Shapes,  Next: Affine Transformations for Shapes,  Prev: Copying Shapes,  Up: Shape Reference

Modifying
=========

 - Pure virtual function: bool set_on_free_store (bool B = `true')
     Sets the data member `on_free_store' to B.  All classes derived
     from `Shape' must therefore also have a data member
     `on_free_store'.

     This function is used in the template function `create_new<type>'.
     *Note Dynamic Allocation of Shapes::, for more information.



File: 3DLDF.info,  Node: Affine Transformations for Shapes,  Next: Applying Transformations to Shapes,  Prev: Modifying Shapes,  Up: Shape Reference

Affine Transformations
======================

 - Pure virtual functions: Transform rotate (const real X, const real
          Y, const real Z)
 - : Transform scale (real X, real Y, real Z)
 - : Transform shear (real XY, real XZ, real YX, real YZ, real ZX, real
          ZY)
 - : Transform shift (real X, real Y, real Z)
 - : Transform rotate (const Point& P0, const Point& P1, const real R)
     *Note Point Reference; Affine Transformations: Affine
     Transformations for Points.


File: 3DLDF.info,  Node: Applying Transformations to Shapes,  Next: Clearing Shapes,  Prev: Affine Transformations for Shapes,  Up: Shape Reference

Applying Transformations
========================

 - Pure virtual function: void apply_transform (void)
     Applies the `Transform' stored in the `transform' data member of
     the `Points' belonging to the `Shape' to their
     `world_coordinates'.  The `transforms' are subsequently reset to
     the identity `Transform'.


File: 3DLDF.info,  Node: Clearing Shapes,  Next: Querying Shapes,  Prev: Applying Transformations to Shapes,  Up: Shape Reference

Clearing
========

 - Pure virtual function: void clear (void)
     The precise definition of this function will depend on the nature
     of the derived class.  In general, it will call the destructor on
     dynamically allocated objects belonging to the `Shape', and
     deallocate the memory they occupied.


File: 3DLDF.info,  Node: Querying Shapes,  Next: Showing Shapes,  Prev: Clearing Shapes,  Up: Shape Reference

Querying
========

 - `const' pure virtual function: bool is_on_free_store (void)
     Returns `true' if the object was allocated on the free store,
     otherwise `false'.


File: 3DLDF.info,  Node: Showing Shapes,  Next: Outputting Shapes,  Prev: Querying Shapes,  Up: Shape Reference

Showing
=======

 - `const' pure virtual function: void show ([string TEXT = "", [char
          COORDS = 'w', [const bool DO_PERSP = `true', [const bool
          DO_APPLY = `true', [Focus* F = 0, [const unsigned short PROJ
          = 0, [const real FACTOR = 1]]]]]]])
     Prints information about an object to standard output.  See the
     descriptions of `show()' for the classes derived from `Shape' for
     more information.


File: 3DLDF.info,  Node: Outputting Shapes,  Prev: Showing Shapes,  Up: Shape Reference

Outputting
==========

 - Pure virtual function: void output (void)
     Called by `Picture::output()' for writing MetaPost code to
     `out_stream' for a `Shape' pointed to by a pointer on the
     `vector<Shape*> shapes' belonging to the `Picture'.  Such a
     `Shape' will have been created by a drawing or filling function.

 - Pure virtual function: vector<Shape*> extract (const Focus& F, const
          unsigned short PROJ, real FACTOR)
     Called in `Picture::output()'.  It determines whether a `Shape'
     can be output.  If it can, and an `output()' function for the type
     of the `Shape' exists, a `vector<Shape*>' containing a pointer to
     the `Shape' is returned.

     On the other hand, it is possible to define a type derived from
     `Shape', without an `output()' function of its own, and not
     derived from a type that has one.  It may then consist of one or
     more objects of types that do have `output()' functions.  In this
     case, the `vector<Shape*>' returned by `extract()' will contain
     pointers to all of these subsidiary `Shapes', and
     `Picture::output()' will treat them as independent objects.  In
     particular, if any one of them cannot be projected using the
     arguments passed to `Picture::output()', this will have no effect
     on whether the others are outputted or not.

     Currently, there are no `Shapes' without an `output()' function,
     either belonging to the class, or inherited.  However, it's useful
     to be able to define `Shapes' in this way, so that they can be
     tested without having to define an `output()' function first.

 - Pure virtual function: bool set_extremes (void)
     Sets the values of `projective_extremes' for the `Shape'.  This is
     needed in `Picture::output()' for determining the order in which
     objects are output.

 - `const' pure virtual functions: real get_minimum_z (void)
 - : real get_maximum_z (void)
 - : real get_mean_z (void)
     These functions return the minimum, maximum, and mean z-value
     respectively of the projected `Points' belonging to the `Shape',
     i.e., from `projective_extremes'.  The values for the `Shapes' on
     the `Picture' are used for determining the order in which they are
     output

 - `const' pure virtual function: const valarray<real> get_extremes
          (void)
     Returns `projective_extremes'.

 - Pure virtual function: void suppress_output (void)
     Sets `do_output' to `false'.  This function is called in
     `Picture::output()', if a `Shape' on a `Picture' cannot be output
     using the arguments passed to `Picture::output()'.

 - Pure virtual function: void unsuppress_output (void)
     Sets `do_output' to `true'.  Called in `Picture::output()' after
     `output()' is called on the `Shapes'.  This way, output of
     `Shapes' that couldn't be output when `Picture::output()' was
     called with a particular set of arguments won't necessarily be
     suppressed when `Picture::output()' is called again with different
     arguments.

   f


File: 3DLDF.info,  Node: Transform Reference,  Next: Label Reference,  Prev: Shape Reference,  Up: Top

Transform Reference
*******************

   Class `Transform' is defined in `transfor.web'.  `Point' is a
`friend' of `Transform'.

* Menu:

* Transform Data Members::
* Transform Global Variables and Constants::
* Transform Constructors ::
* Transform Operators::
* Matrix Inversion::
* Setting Values Transforms::
* Querying Transforms::
* Returning Information for Transforms::
* Showing Transforms::
* Affine Transformations for Transforms::
* Alignment with an Axis for Transforms::
* Resetting Transforms::
* Cleaning Transforms::


File: 3DLDF.info,  Node: Transform Data Members,  Next: Transform Global Variables and Constants,  Prev: Transform Reference,  Up: Transform Reference

Data Members
============

 - Private variable: Matrix matrix
     A 4 X 4

     matrix of `real' representing the actual transformation matrix.


File: 3DLDF.info,  Node: Transform Global Variables and Constants,  Next: Transform Constructors,  Prev: Transform Data Members,  Up: Transform Reference

Global Variables and Constants
==============================

 - Variable: Transform user_transform
     Currently has no function.  It is intended to be used for
     transforming the coordinates of `Points' between the world
     coordinate system (WCS) and a user coordinate system (UCS), when
     routines for managing user coordinate systems are implemented.

 - Constant: `const' Transform INVALID_TRANSFORM
     Every member of `matrix' in `INVALID_TRANSFORM' is equal to
     `INVALID_REAL'.

 - Constant: `const' Transform IDENTITY_TRANSFORM
     Homogeneous coordinates and `Transforms' are unchanged by
     multiplication with `IDENTITY_TRANSFORM'.  `matrix' is an identity
     matrix:
          1 0 0 0
          0 1 0 0
          0 0 1 0
          0 0 0 1
     *Note Transforms::.


File: 3DLDF.info,  Node: Transform Constructors,  Next: Transform Operators,  Prev: Transform Global Variables and Constants,  Up: Transform Reference

Constructors
============

 - Default constructor: void Transform (void)
     Creates a `Transform' containing the identity matrix.

 - Constructor: void Transform (real R)
     Creates a `Transform' and sets all of the elements of MATRIX to R.
     Currently, this constructor is never used, but who knows? Maybe
     someday it will be useful for something.

 - Constructor: void Transform (real R0_0, real R0_1, real R2, real
          R0_2, real R0_3, real R1_0, REAL R1_1, real R1_2, REAL R1_3,
          real R2_0, real R2_1, real R2_2, real R2_3, real R3_0, real
          R3_1, real R3_2, real R3_3)
     Each of the sixteen `real' arguments is assigned to the
     corresponding element of MATRIX: `matrix[0][0] = r0_0',
     `matrix[0][1] = r0_1', etc.  Useful for specifying a
     transformation matrix completely.


File: 3DLDF.info,  Node: Transform Operators,  Next: Matrix Inversion,  Prev: Transform Constructors,  Up: Transform Reference

Operators
=========

 - Assignment operator: Transform operator= (const Transform& T)
     Sets *THIS to T and returns T.  Returning *THIS would, of course,
     have exactly the same effect.

 - Operator: real operator*= (real R)
     Multiplication with assignment by a scalar.  This operator
     multiplies each element E of `matrix' by the scalar R.  The return
     value is `r'.  This makes it possible to chain invocations of this
     function: For a_x, b_x, c_x, ..., p_x in R , x in N

          Transform T0(a_0, b_0, c_0, d_0,
                       e_0, f_0, g_0, h_0,
                       i_0, j_0, k_0 l_0,
                       m_0, n_0, o_0, p_0);
          Transform T1(a_1, b_1, c_1, d_1,
                       e_1, f_1, g_1, h_1,
                       i_1, j_1, k_1 l_1,
                       m_1, n_1, o_1, p_1);
          Transform T2(a_2, b_2, c_2, d_2,
                       e_2, f_2, g_2, h_2,
                       i_2, j_2, k_2 l_2,
                       m_2, n_2, o_2, p_2);
          real r = 5;

     Let M_0, M_1, and M_2 stand for `T0.matrix', `T1.matrix', and
     `T2.matrix' respectively:

          M_0 =
          a_0 b_0 c_0 d_0
          e_0 f_0 g_0 h_0
          i_0 j_0 k_0 l_0
          m_0 m_0 o_0 p_0
          
          M_1 =
          a_1 b_1 c_1 d_1
          e_1 f_1 g_1 h_1
          i_1 j_1 k_1 l_1
          m_1 m_1 o_1 p_1
          
          M_2 =
          a_2 b_2 c_2 d_2
          e_2 f_2 g_2 h_2
          i_2 j_2 k_2 l_2
          m_2 m_2 o_2 p_2

          T0 *= T1 *= T2 *= r;

     Now,
          M_0 =
          5a_0 5b_0 5c_0 5d_0
          5e_0 5f_0 5g_0 5h_0
          5i_0 5j_0 5k_0 5l_0
          5m_0 5m_0 5o_0 5p_0
          
          M_1 =
          5a_1 5b_1 5c_1 5d_1
          5e_1 5f_1 5g_1 5h_1
          5i_1 5j_1 5k_1 5l_1
          5m_1 5m_1 5o_1 5p_1
          
          M_2 =
          5a_2 5b_2 5c_2 5d_2
          5e_2 5f_2 5g_2 5h_2
          5i_2 5j_2 5k_2 5l_2
          5m_2 5m_2 5o_2 5p_2

     This function is not currently used anywhere, but it may turn out
     to be useful for something.

 - `const' operator: Transform operator* (const real R)
     Multiplication of a `Transform' by a scalar without assignment.
     The return value is a `Transform' A.  If `this.matrix' has elements
     E_T, then `A.matrix' has elements E_A such that E_A = r * E_T

     for all E.

 - Operator: Transform operator*= (const Transform& T)
     Performs matrix multiplication on `matrix' and `t.matrix'.  The
     result is assigned to `matrix'.  T is returned, _not_ `*this'!
     This makes it possible to chain invocations of this function:

          Transform a;
          a.shift(1, 1, 1);
          Transform b;
          b.rotate(0, 90);
          Transform c;
          c.shear(5, 4);
          Transform d;
          d.scale(3, 4, 5);

     Let a_m, b_m, and c_m stand for `a.matrix', `b.matrix',
     `c.matrix', and `d.matrix' respectively:
          a_m =
          1        0        0        0
          0        1        0        0
          0        0        1        0
          1        1        1        1
          
          b_m =
           0.5      0.5        0.707      0
           0.146    0.854     -0.5        0
          -0.854    0.146      0.5        0
           0        0          0          1
          
          c_m =
           1       12       14        0
          10        1       15        0
          11       13        1        0
           0        0        0        1
          
          d_m =
          3        0        0        0
          0        4        0        0
          0        0        5        0
          0        0        0        1
     `a *= b *= c *= d;'
     `a', `b', and `c' are transformed by `d', which remains unchanged.

     Now,
          a_m =
          3        0        0        0
          0        4        0        0
          0        0        5        0
          3        4        5        1
          
          b_m =
           1.5     2       3.54  0
          -0.439   3.41   -2.5   0
          -2.56    0.586   2.5   0
           0       0       0     1
          
          c_m =
           3       48       70        0
          30        4       75        0
          33       52        5        0
           0        0        0        1
     d_m is unchanged.


 - `const' operator: Transform operator* (const Transform T)
     Multiplication of a `Transform' by another `Transform' without
     assignment.  The return value is a `Transform' whose `matrix'
     contains values that are the result of the matrix multiplication of
     `matrix' and `t.matrix'.


File: 3DLDF.info,  Node: Matrix Inversion,  Next: Setting Values Transforms,  Prev: Transform Operators,  Up: Transform Reference

Matrix Inversion
================

 - `const' function: Transform inverse (void)
 - Function: Transform inverse ([bool ASSIGN = `false'])
     Returns a `Transform' `T' with a `T.matrix' that is the inverse of
     `matrix'.  If ASSIGN==`true', then `matrix' is set to its inverse.

     In the `const' version, `matrix' remains unchanged.  The second
     should only ever be called with `true' as its ASSIGN argument.  If
     you're tempted call `inverse(false)', you might as well just leave
     out the argument, which issues a warning message, and calls the
     `const' version.


File: 3DLDF.info,  Node: Setting Values Transforms,  Next: Querying Transforms,  Prev: Matrix Inversion,  Up: Transform Reference

Setting Values
==============

 - Function: void set_element (const unsigned short ROW, const unsigned
          short COL, real R)
     Sets the element of `matrix' indicated by the arguments to R.

          Transform t;
          t.set_element(0, 2, -3.45569);
          t.show("t:");
          -| t:
                1       0   -3.46       0
                0       1       0       0
                0       0       1       0
                0       0       0       1


File: 3DLDF.info,  Node: Querying Transforms,  Next: Returning Information for Transforms,  Prev: Setting Values Transforms,  Up: Transform Reference

Querying
========

 - Function: bool is_identity (void)
     Returns `true' if `*this' is the identity `Transform', otherwise
     `false'.  This function has both a `const' and a non-`const'
     version.  In the non-`const' version, `clean()' is called on
     `*this' before comparing the elements of `matrix' with 1 (for the
     main diagonal) and 0 (for the other elements).  In the `const'
     version, `*this' is copied, `clean()' is called on the copy, and
     the elements of the copy's `matrix' are compared with 0 and 1.

 - `const' function: real get_element (const unsigned short ROW, const
          unsigned short COL)
     Returns the value stored in the element of `matrix' indicated by
     the arguments.

          Transform t;
          t.shift(1, 2, 3);
          t.scale(2.5, -1.2, 4);
          t.rotate(30, 15, 60);
          t.show("t:");
          -| t:
              1.21    2.09   0.647       0
             0.822  -0.654    0.58       0
             -2.18   0.224    3.35       0
             -3.69    1.45    11.8       1
          cout << t.get_element(2, 1);
          -| 0.224


File: 3DLDF.info,  Node: Returning Information for Transforms,  Next: Showing Transforms,  Prev: Querying Transforms,  Up: Transform Reference

Returning Information
=====================

 - Static function: real epsilon (void)
     Returns the positive `real' value of smallest magnitude \epsilon
     which an element of a `Transform' should contain.  An element of a
     `Transform' may also contain -\epsilon.

     The value \epsilon is used for in the function `clean()' (*note
     Transform Reference; Cleaning: Cleaning Transforms.).  It will
     also be used for comparing `Transforms', when I've added the
     equality operator `Transform::operator==()'.

     `epsilon()' returns different values, depending on whether `real'
     is `float' or `double': If `real' is `float' (the default),
     `epsilon()' returns 0.00001.  If `real' is `double', it returns
     0.000000001.

     Please note:  I haven't tested whether 0.000000001 is a good value
     yet, so users should be aware of this if they set `real' to
     `double'!(1) The way to test this is to transform two different
     `Transforms' t_1 and t_2 using different rotations in such a way
     that the end result should be the same for both `Transforms'.  Let
     \epsilon stand for the value returned by `epsilon()'.  If for all
     sets of corresponding elements E_1 and E_2 of t_1 and t_2, ||E_1|
     - |E_2|| \le \epsilon, then \epsilon is a good value.  It will be
     easier to test this when I've added `Transform::operator==()'.

     Rotation causes a significant loss of precision to due to the use
     of the `sin()' and `cos()' functions.  Therefore, neither
     `Transform::epsilon()' nor `Point::epsilon()' (*note Point
     Reference; Returning Information: Returning Information for
     Points.) can be as small as I'd like them to be.  If they are two
     small, operations that test for equality of `Transforms' and
     `Points' will return `false' for objects that should be equal.

   ---------- Footnotes ----------

   (1) For that matter, I haven't really tested whether 0.00001 is a
good value when `real' is `float'.


File: 3DLDF.info,  Node: Showing Transforms,  Next: Affine Transformations for Transforms,  Prev: Returning Information for Transforms,  Up: Transform Reference

Showing
=======

 - `const' function: void show ([string TEXT = ""])
     If the optional argument TEXT is used, and is not the empty
     `string' (""), TEXT is printed on a line of its own to the
     standard output first.  Otherwise, `"Transform:"' is printed on a
     line of its own to the standard output.  Then, the elements of
     `matrix' are printed to standard output.

          Transform t;
          t.show("t:");
          -| t:
                1       0       0       0
                0       1       0       0
                0       0       1       0
                0       0       0       1
          t.scale(1, 2, 3);
          t.shift(1, 1, 1);
          t.rotate(90, 90, 90);
          t.show("t:");
          -| t:
                0       0       1       0
                0       2       0       0
               -3       0       0       0
               -1       1       1       1



File: 3DLDF.info,  Node: Affine Transformations for Transforms,  Next: Alignment with an Axis for Transforms,  Prev: Showing Transforms,  Up: Transform Reference

Affine Transformations
======================

   The affine transformation functions use their arguments to create a
new `Transform' `t' (local to the function) representing the
appropriate transformation. Then, `*this' is multiplied by `t' and `t'
is returned.  Returning `t' instead of `*this' makes it possible to put
the affine transformation function at the end of a chain of invocations
of `Transform::operator*=()':

     Transform t0, t1, t2, t3;
     ...
     t0 *= t1 *= t2 *= t3.scale(2, 3.5, 9);

   `t0', `t1', and `t2' are all multiplied by the `Transform' with
     `matrix' =
     2   0    0  0
     0   3.5  0  0
     0   0    9  0
     0   0    0  1
   representing the scaling operation, _not_ `t3', which may represent
a combination of transformations.

 - Function: Transform scale (real X, [real Y = 1, [real Z = 1]])
     Creates a `Transform t' representing the scaling operation locally,
     multiplies `*this' by `t', and returns `t'.  A `Transform'
     representing scaling only, when applied to a `Point p', will cause
     its x-coordinate to be multiplied by X, its y-coordinate to be
     multiplied by Y, and its z-coordinate to be multiplied by Z.

          `Transform t;'
          `t.scale(X, Y, Z);'

          => `t.matrix' =
          x 0 0 0
          0 y 0 0
          0 0 z 0
          0 0 0 1

          Transform t;
          t.scale(12.5, 20, 1.3);
          t.show("t:");
          -| t:
             12.5       0       0       0
                0      20       0       0
                0       0     1.3       0
                0       0       0       1

 - Function: Transform shear (real XY, [real XZ = 0, [real YX = 0,
          [real YZ = 0, [real ZX = 0, [real ZY = 0]]]]])
     Creates a `Transform t' representing the shearing operation
     locally, multiplies `*this' by `t', and returns `t'.

     When applied to a `Point', shearing causes each coordinate to be
     modified according to the values of the other coordinates and the
     arguments to `shear':

          Point p(x,y,z);
          Transform t;
          t.shear(a, b, c, d, e, f);
          p *= t;

          => p = ((x + ay + bz), (y + cx + dz), (z + ex + fy))

          Transform t;
          t.shear(2, 3, 4, 5, 6, 7);
          t.show("t:");
          -| t:
                1       4       6       0
                2       1       7       0
                3       5       1       0
                0       0       0       1


 - Function: Transform shift (real X, [real Y = 0, [real Z = 0]])
 - Function: Transform shift (const Point& P)
     These functions create a `Transform t' representing the shifting
     operation locally, multiplies `*this' by `t', and returns `t'.

     The version with the argument `const Point&' P passes the updated
     x, y, and z-coordinates of P (from `world_coordinates') to the
     version with three `real' arguments.

     When a `Transform' representing a single shifting operation only
     is applied to a `Point', the X, Y, and Z arguments are added to
     the corresponding coordinates of the `Point':

          Point p(x,y,z);
          Transform t;
          t.shift(a, b, c);
          p *= t;

          => p = (x + a, y + b, z + c)

 - Function: Transform shift_times (real X, [real Y = 1, [real Z = 1]])
     Multiplies the corresponding elements of `matrix' by the `real'
     arguments, i.e., `matrix[3][0]' is multiplied by X, `matrix[3][1]'
     is multiplied by Y, and `matrix[3][2]' is multiplied by Z.
     Returns `*this'.

     Ordinary shifting is additive, so a special function is needed to
     multiply the elements of `matrix' responsible for shifting.  The
     effect of `shift_times()' is to modify a `Transform' representing
     a shifting operation such that the direction of the shift is
     maintained, while changing the distance.

     If the `Transform' represents other operations in addition to
     shifting, e.g., scaling and/or shearing, the effect of
     `shift_times()' may be unpredictable.(1)

          Transform t;
          t.shift(1, 2, 3);

          => `t.matrix' =
          1 0 0 0
          0 1 0 0
          0 0 1 0
          1 2 3 1

          t.shift_times(2, 2, 2);

          => `t.matrix' =
          1 0 0 0
          0 1 0 0
          0 0 1 0
          2 4 6 1

          Rectangle r[4];
          r[0].set(origin, 1, 1, 90);
          r[3] = r[2] = r[1] = r[0];
          Transform t;
          t.shift(1.5, 1.5);
          r[0] *= t;
          r[0].draw();
          t.shift_times(1.5, 1.5);
          r[1] *= t;
          r[1].draw();
          t.shift_times(1.5, 1.5);
          r[2] *= t;
          r[2].draw();
          t.shift_times(1.5, 1.5);
          r[3] *= t;
          r[3].draw();

     [Figure 73 not displayed.]

          Cuboid c(origin, 1, 1, 1);
          c.draw();
          Transform t;
          t.rotate(30, 30, 30);
          t.shift(1, 0, 1);
          c *= t;
          c.draw();
          t.shift_times(1.5, 0, 1.5);
          c *= t;
          c.draw();
          t.shift_times(1.5, 0, 1.5);
          c *= t;
          c.draw();
          t.shift_times(1.5, 0, 1.5);
          c *= t;
          c.draw();
          t.shift_times(1.5, 0, 1.5);
          c *= t;
          c.draw();

     [Figure 74 not displayed.]


 - Function: Transform rotate (real X, [real Y = 0, [real Z = 0]])
     Rotation around the main axes.  Creates a `Transform t'
     representing the rotation, multiplies `*this' by `t', and returns
     `t'.

 - Function: Transform rotate (Point P0, Point P1, [const real ANGLE =
          180])
     Rotation around an arbitrary axis.  The `Point' arguments represent
     the end points of the axis, and ANGLE is the angle of rotation.
     Since 180 degrees  rotation is needed so often, 180 is the default
     for ANGLE.

 - Function: Transform rotate (const Path& P, [const real ANGLE = 180])
     Rotation around an arbitrary axis.  `Path' argument.  The `Path' P
     must be linear, i.e., `p.is_linear()' must return `true'.  *Note
     Path Reference; Querying: Querying Paths.

   ---------- Footnotes ----------

   (1) For a person, not in the sense of the program behaving
unpredictably.


File: 3DLDF.info,  Node: Alignment with an Axis for Transforms,  Next: Resetting Transforms,  Prev: Affine Transformations for Transforms,  Up: Transform Reference

Alignment with an Axis
======================

 - Function: Transform align_with_axis (Point P0, Point P1, [char AXIS
          = 'z'])
     Returns the `Transform' that would align the line through P0 and
     P1 with the major axis denoted by the AXIS argument.  The default
     is the z-axis.  This function is used in the functions that find
     intersections.

          Point P0(1, 1, 1);
          Point P1(2, 3, 4);
          P0.draw(P1);
          P0.dotlabel("$P_0$");
          P1.dotlabel("$P_1$");
          Transform t;
          t.align_with_axis(P0, P1, 'z');
          P0 *= P1 *= t;
          t.show("t:");
          -| t:
               0.949  -0.169   0.267       0
                   0   0.845   0.535       0
              -0.316  -0.507   0.802       0
              -0.632  -0.169    -1.6       1
          P0.show("P0:");
          -| P0: (0, 0, 0)
          P1.show("P1:");
          -| P1: (0, 0, 3.74)

     The following example shows how `align_with_axis()' can be used for
     putting plane figures into a major plane.

          default_focus.set(2, 3, -10, 2, 3, 10, 10);
          Circle c(origin, 3, 75, 25, 6);
          c.shift(2, 3);
          c.draw();
          Point n = c.get_normal();
          n.shift(c.get_center());
          Transform t;
          t.align_with_axis(c.get_center(), n, 'y');
          t.show("t:");
          -| t:
            0.686   0.379  -0.621       0
            0.543     0.3   0.784       0
            0.483  -0.875       0       0
               -3   -1.66   -1.11       1
          n *= c *= t;
          c.draw();
          c.show("c:");
          -| c:
          fill_draw_value == 0
          (1.31, 0, -0.728) .. (1.49, 0, -0.171) ..
          (1.44, 0, 0.413) .. (1.17, 0, 0.933) ..
          (0.728, 0, 1.31) .. (0.171, 0, 1.49) ..
          (-0.413, 0, 1.44) .. (-0.933, 0, 1.17) ..
          (-1.31, 0, 0.728) .. (-1.49, 0, 0.171) ..
          (-1.44, 0, -0.413) .. (-1.17, 0, -0.933) ..
          (-0.728, 0, -1.31) .. (-0.171, 0, -1.49) ..
          (0.413, 0, -1.44) .. (0.933, 0, -1.17) .. cycle;
          n.show("n:");
          -| n: (0, 1, 0)

     [Figure 75 not displayed.]



File: 3DLDF.info,  Node: Resetting Transforms,  Next: Cleaning Transforms,  Prev: Alignment with an Axis for Transforms,  Up: Transform Reference

Resetting
=========

 - Function: void reset (void)
     Resets MATRIX to the identity matrix.


File: 3DLDF.info,  Node: Cleaning Transforms,  Prev: Resetting Transforms,  Up: Transform Reference

Cleaning
========

 - Function: void clean (void)
     Sets elements in MATRIX whose absolute values are < `epsilon()' to
     0.


File: 3DLDF.info,  Node: Label Reference,  Next: Picture Reference,  Prev: Transform Reference,  Up: Top

Label Reference
***************

   Class `Label' is defined in `pictures.web'.  `Point' and `Picture'
are `friends' of `Label'.

   Labels can be included in drawings by using the `label()' and
`dotlabel()' functions, which are currently defined for the classes
`Point' and `Path', and the classes derived from them.  *Note Point
Reference; Labelling: Labelling Points, and *Note Path Reference;
Labelling: Labelling Paths.  They are currently not defined for
`Solid', and its derived classes.  I plan to add them for `Solid' soon.

   Users will normally never need to declare objects of type `Label',
access its data members or call its member functions directly.

   When `label()' or `dotlabel()' is invoked, one or more `Labels' is
allocated dynamically and pointers to the new `Labels' are placed onto
the `vector<Label*> labels' of a `Picture': `current_picture', by
default.  There are no explicitly defined constructors for `Label', nor
is it intended that `Labels' ever be created in any way other than
through `label()' or `dotlabel()'.  When a `Picture' is copied, the
`Labels' are copied, too, and when a `Picture' is cleared (using
`Picture::clear()') or destroyed, the `Labels' are deallocated and
destroyed.

* Menu:

* Label Data Members::
* Copying Labels::
* Outputting Labels::

