  MATH.INC
Sean O'Malley
 March, 1999
-------------
Mathematical Function Include for POV-Ray 3.0+
(Requires use of macros and arrays.)

CONTENTS
--------
1) Purpose
2) How to Use
   - Defining variables
   - Including MATH.INC
   - Placing the math object
3) Tips
4) The Author

Purpose
-------
This include allows you to easily create and manipulate graphs with
all the mathematical and visual power of the POV-Ray engine.  The graphs
created are currently limited to functions based on two variables in a
user-defined range.  Specifically, this will draw a graph of the
function z = f(x,y) over the range of (minx,maxx) on the X axis and
(miny,maxy) on the Y axis at certain increments (see "How to Use" and
"Defining Variables" below).  This is excellent for teaching purposes,
animation, and to show the effects of changing constants in certain
functions.  Of course, more common objects can be made out of some
functions and included generally in most ray-traced art.

Render the sample scene/animation to see what this looks like.

How to Use
----------
Like most (okay, all) POV-Ray includes, this requires three steps;
see below this section for in-depth information:

1) Define the required constants and the equation to use inside your
   POV file. (Variables listed below.)
2) Include MATH.INC by typing #include "math.inc" after the constants
   section.
3) Place the math object created by MATH.INC.  IMPORTANT: Keep in mind
   that MATH.INC was programmed with Z being up.  Depending on if you
   use this with a modelling program or with plain POV-Ray code, you
   may need to rotate this so it's facing in the right direction!

Example files are included in the archive this came with for reference.

1) Defining variables
---------------------
The most important thing is defining the variables for MATH.INC to
process.  Defining these is "required," but MATH.INC also has built-in
defaults and will also give a warning if one of the variables wasn't
defined before including MATH.INC.  The way to define a variable is
to just type, for example:

 #define minx = -4;

The list of variables currently supported is:

 1) minx       - The minimum X value.
 2) miny       - The minimum Y value.
 3) maxx       - The maximum X value.
 4) maxy       - The maximum Y value.
 5) graph_size - Not actually the size of the graph, but the resolution.
                 The larger this is, the more smooth and accurate the
                 graph will be, but parse time will be longer and more
                 triangles will be required. (For example, a graph size
                 of 15 will make a 15x15 matrix of values, which will create
                 a mesh of 225 squares, or 450 triangles.)
 6) smooth_graph - Set to true or false.  If you want a more graphing-
                calculator/Mathematica-looking graph, set this to false
                (the default).  If you're going to use the graph as part
                of a ray-traced scene, you'll definitely want to set this
                to true.  If true, MATH.INC will use a bit more memory and
                take a bit longer to process, but the resulting graph is
                dramatically better-looking than the non-smoothed-graph.
                If the graph still isn't smooth enough, increase the graph_size.
 7) domath -
     This is a macro that needs to be defined, and it will determine
     the mathematical function to graph. (If undefined, I believe the
     default equation is a 3-D bell curve or something. :)  This needs
     to look something like this:

     #macro domath(a,b)
      sin(a+b)
     #end

    This macro is the same as z = sin(x + y) and produces a wavy
    graph.  I used "a" and "b" because x and y are reserved to POV-Ray
    and I didn't want to confuse it, but use any letters you want as
    long as the macro is called domath!  The macro will be called
    by MATH.INC when it needs to figure out Z, so try not to confuse
    it or POV-Ray will crash.

 A sample definition:

  #define minx = -4;
  #define maxx = 4;
  #define miny = -4;
  #define maxy = 4;
  #define graph_size = 15;
  #define smooth_graph = true;

  #macro domath(a,b)
   sin(a+b)
  #end

 After you include MATH.INC and place and scale the object, you'll have
 a flag-looking thing.  (Actually the sine of the sum of X and Y over
 the area -4 to +4 on the X and Y axes.)

 OPTIONAL VARIABLES:

 I noticed that after I made the original version of this that the graph
 would scoot all over the place if the mesh wasn't centered over the origin.
 To fix this, the graph will now automatically center unless told otherwise.
 I made it optional because if, for example, you're using MATH.INC to produce
 actual graphs with a grid or axis lines, you may want the graph to reflect
 actual X and Y values instead of recentered values.  To change it so it
 is not recentered automatically, define one or more of these variables
 before including MATH.INC:

  #define centerxy = false;
  #define centerz = true;

 The defaults are centerxy is true, centerz is false.  "centerxy" centers
 the graph over the X/Y origin, and defaults as true.  "centerz" takes
 the average of all Z values and scoots the graph up or down in an attempt
 to center it.  This may not be very useful, so it defaults to false.
 "centerz" only works if smooth_graph is true.

2) Including MATH.INC
---------------------
 On a line after all the variables have been defined, simply put

  #include "math.inc"

 Make sure MATH.INC is either in POV-Ray's path or in the directory
 including the POV file which uses it, or POV-Ray will inform you that
 it can't find it.

3) Placing the object
---------------------
 After including MATH.INC, a triangular mesh object will be created
 called math_object.  To place it, simply put:

  object { math_object }

 I could have set MATH.INC to place the object itself, but you'll
 definitely want to make changes to the shape, size, or texture.
 (Or put it into a CSG!)  This way, you can make it twice its normal
 size just by doing this:

  object { math_object scale 2 }

Tips
----
 *- To make interesting 3-D graphs of 2-D functions, try "spinning" them
 around the origin (this was how I made a 3-D bell curve!).  Included
 in MATH.INC is a macro called "mydistance" which can be used to
 measure the distance from a certain point to the origin.  This is
 useful for making curves that look like droplets, and for 3-D
 representations of 2-D curves.

 *- Make some quick and easy mountains or height fields by mixing trig 
 functions together with random numbers from POV-Ray.

 *- Scale the Z axis up or down to accentuate or flatten the graph.

 *- Interesting animations can be made by modifying the area of the
 curve that's drawn without changing the location of the actual
 math_object.  Ripples, flags, etc, or just for exploring a function
 in detail. (Or change the area that's drawn AND the location for your
 own solitons?)

 *- Euler's constant (e) is defined by MATH.INC, as is a macro for
 squaring a number (mysqr).  I used them during testing, but they're
 infinitely useful.  Well, sorta.

 *- Highly complex graphs may need a larger graph_size value.

 *- Use a non-smoothed graph to make faceted objects like gems.

The Author
----------
 This was written by Sean O'Malley in March, 1999.  It's based on a
 Pascal program also written by me which does the same thing, only
 producing DXF files.  (I also have one which graphs polar and 3-D
 curves using cylinders, but that's another story.)  While it's easy
 to incorporate DXFs into modelling programs, they can't be animated.
 So I wrote this in POV's language.

 Thanks to Chris Colefax for convincing me that I did need to stick
 the whole graph into an array first for the graph smoothing routine.
 There is no lazy way out, I guess.

 Web page: http://www.geocities.com/~ffrog
 E-mail addresses: ffrog@geocities.com
                   frog@star2.opsys.com

 Questions and comments welcome, especially from those who know more
 about POV-Ray then I do.  (There *must* be a better way to program
 this.)

                                      - Sean O'Malley
