Welcome to the POVHerm Web Site!


October 6, 1997...POVHERM 1.1 shipping now! November 12, 1998...POVHERM 1.2 (the infamous semicolon warning fix) AVAILABLE

I have developed a POV Hermite curve generator. POVHerm takes a data file and generates a POV include file which gives the points along the curve.

Hermite Curves are pretty neat because unlike B-Spline curves, the curve intersects every control point. Associated with each control point is a vector to which the curve is tangent at the control point. The magnitude of the vector in each of the X,Y, and Z directions indicates the distance between subsequent points along the curve for each coordinate. These distances are smoothed between this control point and the next one by a smoothing function.

These properties of Hermite curves make them really ideal for camera flights. Using two curves, one for the camera position and one for the 'look_at' coordinate make helicopter camera work very easy in POV. I had originally developed this in POV 2.2, but since that was before the '#switch', I had the program generate a new '.CAM' file for each point, then copied each subsequent camera file (1.cam,2.cam,3.cam, etc.) to a standard name (like mt.cam) in a batch file, and called POV again. That's MUCH easier now since I am using a #switch statement in an include file and all the points are in there.

The data files have one control point/vector/frame count per line. The control points are X,Y,Z and the vector is DX,DY,DZ, and the frame count is an integer. Here's an example:
XYZDXDYDZFrame Count
-1800408020-3020
-6030370-10020
-30030-1000

An actual data file example (note all numbers except the last CAN have decimals):


-180  0 40      80   20  -30     20
 -60 30  3      70  -10    0     20
 -30  0  3       0  -10    0      0

Here's a picture of the generated points (the blue spheres)(the red ones are another curve in the same picture)(also the 'land' is a height field with a small piece of the Mandelbrot set used as a mountain - from Fractint FYI)

Here's the generated include file (called MT2VPT.INC):


// POVHerm 1.2 - now using HERMITE_VEC instead of HERMITE_X,Y,Z (adding semicolons!)
// Echoing 3 Control Points
// -180.000000 0.000000 40.000000   80.000000 80.000000 80.000000   20
// -60.000000 30.000000 3.000000   70.000000 70.000000 70.000000   20
// -30.000000 0.000000 3.000000   0.000000 0.000000 0.000000   0

#switch(HERMITE_FRAME)
    #case (0)
        #declare HERMITE_VEC = <-180.000000,0.000000,40.000000>;
        #break;
    #case (1)
        #declare HERMITE_VEC = <-175.686249,1.143750,38.377998>;
        #break;
    #case (2)
        #declare HERMITE_VEC = <-170.789993,2.550000,36.534000>;
        #break;
    #case (3)
        #declare HERMITE_VEC = <-165.378754,4.181250,34.500999>;
        #break;
    #case (4)
        #declare HERMITE_VEC = <-159.519989,6.000000,32.312000>;
        #break;
    #case (5)
        #declare HERMITE_VEC = <-153.281250,7.968750,30.000000>;
        #break;
    #case (6)
        #declare HERMITE_VEC = <-146.729996,10.050000,27.598000>;
        #break;
    #case (7)
        #declare HERMITE_VEC = <-139.933746,12.206251,25.139000>;
        #break;
    #case (8)
        #declare HERMITE_VEC = <-132.959991,14.400002,22.655998>;
        #break;
    #case (9)
        #declare HERMITE_VEC = <-125.876251,16.593752,20.181999>;
        #break;
    #case (10)
        #declare HERMITE_VEC = <-118.749992,18.750004,17.749998>;
        #break;
    #case (11)
        #declare HERMITE_VEC = <-111.648735,20.831251,15.392997>;
        #break;
    #case (12)
        #declare HERMITE_VEC = <-104.639992,22.800003,13.143996>;
        #break;
    #case (13)
        #declare HERMITE_VEC = <-97.791237,24.618753,11.035995>;
        #break;
    #case (14)
        #declare HERMITE_VEC = <-91.169991,26.250004,9.101996>;
        #break;
    #case (15)
        #declare HERMITE_VEC = <-84.843735,27.656252,7.374997>;
        #break;
    #case (16)
        #declare HERMITE_VEC = <-78.879982,28.800003,5.887996>;
        #break;
    #case (17)
        #declare HERMITE_VEC = <-73.346230,29.643753,4.673996>;
        #break;
    #case (18)
        #declare HERMITE_VEC = <-68.309982,30.150002,3.765997>;
        #break;
    #case (19)
        #declare HERMITE_VEC = <-63.838734,30.281252,3.196998>;
        #break;
    #case (20)
        #declare HERMITE_VEC = <-60.000000,30.000000,3.000000>;
        #break;
    #case (21)
        #declare HERMITE_VEC = <-56.452835,29.313311,3.000000>;
        #break;
    #case (22)
        #declare HERMITE_VEC = <-53.173931,28.329203,3.000000>;
        #break;
    #case (23)
        #declare HERMITE_VEC = <-50.154541,27.082664,3.000000>;
        #break;
    #case (24)
        #declare HERMITE_VEC = <-47.385918,25.608688,3.000000>;
        #break;
    #case (25)
        #declare HERMITE_VEC = <-44.859306,23.942265,3.000000>;
        #break;
    #case (26)
        #declare HERMITE_VEC = <-42.565971,22.118385,3.000000>;
        #break;
    #case (27)
        #declare HERMITE_VEC = <-40.497158,20.172035,3.000000>;
        #break;
    #case (28)
        #declare HERMITE_VEC = <-38.644115,18.138210,3.000000>;
        #break;
    #case (29)
        #declare HERMITE_VEC = <-36.998104,16.051901,3.000000>;
        #break;
    #case (30)
        #declare HERMITE_VEC = <-35.550373,13.948096,3.000000>;
        #break;
    #case (31)
        #declare HERMITE_VEC = <-34.292171,11.861788,3.000000>;
        #break;
    #case (32)
        #declare HERMITE_VEC = <-33.214756,9.827965,3.000000>;
        #break;
    #case (33)
        #declare HERMITE_VEC = <-32.309376,7.881618,3.000000>;
        #break;
    #case (34)
        #declare HERMITE_VEC = <-31.567286,6.057735,3.000000>;
        #break;
    #case (35)
        #declare HERMITE_VEC = <-30.979734,4.391313,3.000000>;
        #break;
    #case (36)
        #declare HERMITE_VEC = <-30.537979,2.917339,3.000000>;
        #break;
    #case (37)
        #declare HERMITE_VEC = <-30.233273,1.670800,3.000000>;
        #break;
    #case (38)
        #declare HERMITE_VEC = <-30.056862,0.686691,3.000000>;
        #break;
    #case (39)
        #declare HERMITE_VEC = <-30.000000,0.000002,3.000000>;
        #break;
    #else
        #error "Invalid Hermite Frame"
#end // switch HERMITE_FRAME

And here's the HERM1.POV file that generated the picture:
#include "colors.inc"
#include "landscap.inc"
camera
    {
    location <-220,-50,80>
    direction <0,0,1>
    sky <0,0,1>
    look_at <-50,0,0>
    }
object
    {
    height_field { gif "mandcross.gif" }
    rotate <90,0,0>
    texture{ Landscape scale 1.1 } /* before scale<> so texture gets scaled same size */
    scale <400,400,5>
    translate <-200,200,0>
    rotate <0,0,0>
    finish{ambient 0.5}
    }

light_source
    {
    <-5000,-2000,5000>
    color rgb < 0.8, 0.7, 1.0>
    rotate <0,0,-clock>
    }

#declare HERMITE_FRAME = 0

#while (HERMITE_FRAME < 40)

    #include "mt2vpt.inc"
    sphere
        {
        HERMITE_VEC 1
        pigment{ color Blue }
        }

    #include "mt2look.inc"
    sphere
        {
        HERMITE_VEC 1
        pigment{ color Red }
        }

    #declare HERMITE_FRAME = HERMITE_FRAME+1

#end // while

Using the Blue points as viewpoints for a camera and the Red points as a look_at coordinate, you get the following animation:


Here's the POV code for MT2.POV:


#include "colors.inc"
#include "landscap.inc"
#include "textures.inc"
#include "stones.inc"

#include "planet.inc" // just a PinkAlabaster sphere...

#declare HERMITE_FRAME = clock-1
#include "mt2vpt.inc"
#declare vpt=HERMITE_VEC
#include "mt2look.inc"
#declare lookat=HERMITE_VEC

camera
    {
    location vpt
    direction <0,0,1>
    sky <0,0,1>
    look_at lookat
    focal_point lookat
    aperture 0.4     // a nice compromise
    blur_samples 20      // more samples, higher quality image
    }


object
    {
    height_field { gif "mandcross.gif" }
    rotate <90,0,0>
    texture{ Landscape scale 1.1 } /* before scale<> so texture gets scaled same size */
    scale <400,400,5>
    translate <-200,200,0>
    rotate <0,0,0>
    finish{ambient 0.5}
    }

light_source
    {
    <-5000,-2000,5000>
    color rgb < 0.8, 0.7, 1.0>
    rotate <0,0,-clock>
    }

The MT2.INI file has the clock run from 1 to 40.



POVHERM 1.0 used HERMITE_X,HERMITE_Y,HERMITE_Z. Since I almost always used it as an entire vector, I changed this to HERMITE_VEC. If you want the individual components, you can always use HERMITE_VEC.x,etc.
POVHerm 1.2 has a fix for the semicolon warning from POV 3.1.
Here is a Zipped DOS executable (POVHERM 1.2).
---usage: povherm [inputfile] [outputfile]
If the input file and output file are not specified, you will be prompted for them.
Here is the C++ source code.

This source should compile on any C++ compiler. I used Borland C++ and MS Visual C++, but I haven't done anything Borland, MS, or DOS specific.

Sorry, no documentation as yet, but you can save this HTML file since it really contains just about all I can tell you.

Alan Langford as a windows version which will probably make my program completely obsolete, but I only created it because there was a need (mine!) and so (since we're both giving the programs away!) there's no competition! Here's the text/links of the email he posted to the IRTC mailing list...



For those of you on Win 95/98/NT platforms who generate Hermite curves, I
have the results of my latest time-wasting project available for download
and test.

WinHerm is a Hermite curve generator (think of it as POVHerm for Windows)
that all started because I didn't like the semicolon warnings on files
generated by POVHerm 1.1... go figure.

Download it from http://www.ambitonline.com/ftp/WinHerm050.exe It's about 3.8Mb.


---
Alan Langford
Raytracing and Rants Website: (sorry it's gone...5-Jan-2000)

Further questions? Email Emory Stagmer.Enjoy!

I'm working on some other animations, and if you want those files, email me. The canyon fly-through is coming along nicely!


1