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:
X | Y | Z | DX | DY | DZ | Frame Count |
---|---|---|---|---|---|---|
-180 | 0 | 40 | 80 | 20 | -30 | 20 |
-60 | 30 | 3 | 70 | -10 | 0 | 20 |
-30 | 0 | 3 | 0 | -10 | 0 | 0 |
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
#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> }
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...
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!