POV-Ray : Newsgroups : povray.binaries.scene-files : MyMaglev animation sequence generator Server Time
15 May 2024 14:25:21 EDT (-0400)
  MyMaglev animation sequence generator (Message 1 to 4 of 4)  
From: Jörg 'Yadgar' Bleimann
Subject: MyMaglev animation sequence generator
Date: 2 Jul 2009 20:15:42
Message: <4a4d4dae@news.povray.org>
The C++ source code attached here generates animations sequences of 
camera rides along maglev tracks, which in turn are generated according 
to small ASCII scripts describing connected rail segments. These track 
definition scripts (TDSs) are defined as follows:

<Type>,<length|bend angle>,<non-relevant|bend radius>, <CR>

"Type" can take on the values of either 0 (straight rail segment) or 1 
(bent segment). If "Type" is 0, then the second value is interpreted as 
length in POV units (1 POV unit equals 1 metre), otherwise it is 
interpreted as the angle of the bend, given in degrees. Positive values 
describe right turns, negative ones describe left turns.
If "Type" is 0, then the third value is not interpreted at all; 
otherwise it is interpreted as radius in POV units.

Every line is followed by \n (carriage return), but after the last value 
of the last line no comma follows.

Type is an integer, length/angle and radius are float variables.

A typical TDS:

0,8,0,
1,-80,10,
1,179,7,
1,31,7,
1,-30,8,
0,12,0

The third and fourth line show a special restriction: as bends are 
constructed as CSG difference objects from full-circle lathes, any bend 
greater than 180 degrees must be split up in two segments each shorter 
than 180 degrees, otherwise the segment will be rendered interrupted by 
gaps!

The C++ routine, called makemm ("make MyMaglev") is started from the 
Linux or Windows console (I compiled it only for 64-bit Linux) with 
seven parameters:

makemm <start_x> <start_y> <start_z> <direction> <speed> <frames per 
second> <camera height above track>

Example:

makemm 0 0 0 80 5 25 0.2

will generate a track which first segment starts centered at <start_x, 
start_y, start_z>, and is oriented into a direction of 80 degrees  (0 
being in positive direction along the z axis, 90 in positive direction 
along the x axis and so on), the camera moves at 5 metres/second using 
25 frames per second, at 0.2 POV units above the track.

You will be asked for the name of the TDS file and an output file, then 
the camera animation sequence is written.

After that, you append this to the existing scene "header":

// cabinrailway.pov
// Maglev commuter train and Personal Rail Cabin system, 60-cm gauge
// (c) 2009 by J�rg 'Yadgar' Bleimann (yaz### [at] gmxde)
// Thanks to:
// Martin (don### [at] onocom) for fixing the segment connection routine


// VARIABLES

#declare ani=1;  // animation flag


// TEXTURES

#declare T_Bright_Metal =
texture
{
   pigment
   {
     color rgb 0.85
   }
   finish
   {
     ambient 0.15
     diffuse 1
     brilliance 0.3
     phong 0.9
     phong_size 110
   }
} 


#declare T_Simple_Green =
   texture
   {
     pigment
     {
       color rgb <0, 0.7, 0>
     }
     finish
     {
       ambient 0.15
       diffuse 1
       brilliance 0.2
     }
   }




// OBJECTS

#macro StraightRail(le) // le: length in metres
   #local StraightOuterRounding =
   cylinder
   {
     <0.005, 0.495, 0>, <0.005, 0.495, 4>, 0.005
   }
   union
   {
     prism
     {
       linear_sweep
       linear_spline
       0, -le, 21
       <0, 0>, <0, 0.495>, <0.005, 0.495>, <0.005, 0.5>,
       <0.21, 0.5>, <0.225, 0.485>, <0.225, 0.315>, <0.21, 0.3>,
       <0.1, 0.3>, <0.1, 0.15>, <0.5, 0.15>, <0.5, 0.3>, <0.39, 0.3>,
       <0.375, 0.315>, <0.375, 0.485>, <0.39, 0.5>, <0.595, 0.5>,
       <0.595, 0.495>, <0.6, 0.495>, <0.6, 0>, <0, 0>
       rotate -x*90
     }
     object { StraightOuterRounding }
     object { StraightOuterRounding translate x*0.59 }
     texture { T_Bright_Metal }
     translate <-0.3, -0.45, 0>
   }
#end

#macro Straight_GroundCutout(le) // le: length in metres
   box
   {
     <0, 0, -0.0001>, <0.6, 0.451, le+0.0001>
     translate -x*0.3
   }
#end

#macro BendRail(rd, ang) // rd: bend central radius; ang: circle section 
angle (positive: right, negative: left);
   #local FullCircle =
   lathe
   {
     linear_spline
     21
     <rd-0.3, 0>, <rd-0.3, 0.495>, <rd-0.295, 0.495>, <rd-0.295, 0.5>,
     <rd-0.09, 0.5>, <rd-0.075, 0.485>, <rd-0.075, 0.315>, <rd-0.09, 0.3>,
     <rd-0.2, 0.3>, <rd-0.2, 0.15>, <rd+0.2, 0.15>, <rd+0.2, 0.3>, 
<rd+0.09, 0.3>,
     <rd+0.075, 0.315>, <rd+0.075, 0.485>, <rd+0.09, 0.5>, <rd+0.295, 0.5>,
     <rd+0.295, 0.495>, <rd+0.3, 0.495>, <rd+0.3, 0>, <rd-0.3, 0>
   }

   #local Bend_Subtraction_Block =
   box
   {
     <-(rd+0.31), -1, 0>, <rd+0.31, 1, rd+0.31>
   }

   #local BendOuterRounding =
   torus
   {
     rd+0.295, 0.005
   }

   #local BendInnerRounding =
   torus
   {
     rd-0.295, 0.005
   }

   #local BendOuterRounding =
   difference
   {
     object { BendOuterRounding }
     object
     {
       Bend_Subtraction_Block
       rotate y*ang
     }
     object { Bend_Subtraction_Block rotate y*180 }
   }

   #local BendInnerRounding =
   difference
   {
     object { BendInnerRounding }
     object
     {
       Bend_Subtraction_Block
       rotate y*ang
     }
     object { Bend_Subtraction_Block rotate y*180 }
   }

   union
   {
     difference
     {
       object { FullCircle }
       object
       {
         Bend_Subtraction_Block
         rotate y*ang
       }
       object { Bend_Subtraction_Block rotate y*180 }
     }
     object { BendOuterRounding translate y*0.495 }
     object { BendInnerRounding translate y*0.495 }
     texture { T_Bright_Metal }
     #if (ang >= 0)
       translate x*rd
     #else
       translate -x*rd
     #end
     translate -y*0.45
   }
#end

#macro Bend_GroundCutout (rd, ang) // rd: bend central radius; ang: 
circle section angle (positive: right, negative: left);
   #local FullCircle =
   difference
   {
     cylinder
     {
       0, <0, 0.451, 0>, rd+0.3
     }
     cylinder
     {
       <0, -0.001, 0>, <0, 0.452, 0>, rd-0.3
     }
   }

   #local Bend_Subtraction_Block =
   box
   {
     <-(rd+0.31), -1, 0>, <rd+0.31, 1, rd+0.31>
   }


   difference
   {
     object { FullCircle }
     object
     {
       Bend_Subtraction_Block
       rotate y*(ang+0.0001)
     }
     object { Bend_Subtraction_Block rotate y*180 }
     #if (ang >= 0)
       translate x*rd
     #else
       translate -x*rd
     #end
   }
#end




// ACTUAL SCENE

sky_sphere
{
   pigment
   {
     gradient y
     color_map
     {
       [0 rgb 1 ]
       [0.3 rgb 0.5 ]
     }
   }
}

light_source
{
   <0, 1000, -2000>
   color rgb 1
}

// INSERTION GENERATED WITH MAKEMM

// INSERTION BEGIN
#declare RailElements = array[6][3];
#declare i=0;
#declare ty =0;
#declare s = 0;
#declare r = 0;

#fopen RailData "railtest4.txt" read
   #while (defined(RailData))
     #read (RailData,ty,s, r)
     #declare RailElements[i][0] = ty;
     #declare RailElements[i][1] = s;
     #declare RailElements[i][2] = r;
     #declare i=i+1;
   #end
#fclose RailData

#declare trans_general = <0, 0, 0>;
#declare d_general = 0;

#declare i = 0; // loop counter
#declare trans = trans_general; // position of first rail segment 
(center of front side)
#declare d = d_general; // orientation (degrees) of first rail segment

#while (i < 6)
   #switch (RailElements[i][0])
     #case (0)
       object
       {
         StraightRail(RailElements[i][1])
         rotate y*d
         translate trans
         #declare trans = trans+vrotate(<0, 0, RailElements[i][1]>,<0, 
d, 0>);
       }
     #break
     #case (1)
       object
       {
         BendRail(RailElements[i][2], RailElements[i][1])
         rotate y*d
         translate trans
         // begin of Martin's code
         #declare dir= select(RailElements[i][1],1,-1,-1);
         #declare pt= vrotate(x*(RailElements[i][2])*dir, 
RailElements[i][1]*y)-x*RailElements[i][2]*dir;
         #declare trans= trans+vrotate(pt,y*d);
         // end of Martin's code
         #declare d = d+RailElements[i][1];
       }
     #break
   #end
   #declare i=i+1;
#end

#declare i=0;
#declare trans=trans_general; // position of first ground cutout segment 
(center of front side)
#declare d=d_general; // orientation (degrees) of first ground cutout 
segment

#declare Ground_Cutout =
union
{
   #while (i<6)
     #switch (RailElements[i][0])
       #case (0)
         object
         {
           Straight_GroundCutout(RailElements[i][1])
           rotate y*d
           translate trans
           #declare trans = trans+vrotate(<0, 0, RailElements[i][1]>,<0, 
d, 0>);
         }
       #break
       #case (1)
         object
         {
           Bend_GroundCutout(RailElements[i][2], RailElements[i][1])
           rotate y*d
           translate trans
           // begin of Martin's code
           #declare dir= select(RailElements[i][1],1,-1,-1);
           #declare pt= vrotate(x*(RailElements[i][2])*dir, 
RailElements[i][1]*y)-x*RailElements[i][2]*dir;
           #declare trans= trans+vrotate(pt,y*d);
           // end of Martin's code
           #declare d = d+RailElements[i][1];
         }
       #break
     #end
     #declare i=i+1;
   #end
}

difference
{
   plane
   {
     y, 0
     texture { T_Simple_Green }
   }
   object { Ground_Cutout translate -y*0.45 }
}

#declare speed = 5; // metres/second
#declare fps = 25; // animation frames per second

#if (ani)
   camera
   {
     #switch (clock)
       #range(0, 40) // track segment #1: 8 metres straight; total 
length = 8
         #declare loc = < 0, 0.2, 0 > + < 0, 0, 0> + < 0* (clock-0), 0, 
0.2 * (clock-0)>;
         #declare ldir = vrotate(<0, 0, 1>, y*0);
         location loc
         look_at loc+ldir
       #break
       #range(41, 110) // track segment #2: 80 degrees left turn; total 
length = 21.9626
         #declare loc = < 0, 0.2, 8 > + < -10, 0, 1.94115e-06 > + 10 * 
<sin(radians(0+90-0.214101-( 1.14592 * ( clock-41)))), 0, 
cos(radians(0+90-0.214101-( 1.14592 * ( clock-41))))>;
         #declare ldir = vrotate(<0, 0, 1>, 
y*(0-0.214101-(1.14592*(clock - 41))));
         location loc
         look_at loc+ldir
       #break
       #range(111, 220) // track segment #3: 179 degrees right turn; 
total length = 43.8316
         #declare loc = < -8.26352, 0.2, 17.8481 > + < 1.21554, 0, 
6.89365 > + 7 * <sin(radians(-80-90+1.07247+( 1.63702 * ( clock-111)))), 
0, cos(radians(-80-90+1.07247+( 1.63702 * ( clock-111))))>;
         #declare ldir = vrotate(<0, 0, 1>, 
y*(-80+1.07247+(1.63702*(clock - 111))));
         location loc
         look_at loc+ldir
       #break
       #range(221, 239) // track segment #4: 31 degrees right turn; 
total length = 47.619
         #declare loc = < -5.95294, 0.2, 31.6556 > + < -1.09504, 0, 
-6.91382 > + 7 * <sin(radians(99-90+0.103427+( 1.63702 * ( 
clock-221)))), 0, cos(radians(99-90+0.103427+( 1.63702 * ( clock-221))))>;
         #declare ldir = vrotate(<0, 0, 1>, 
y*(99+0.103427+(1.63702*(clock - 221))));
         location loc
         look_at loc+ldir
       #break
       #range(240, 260) // track segment #5: 30 degrees left turn; total 
length = 51.8078
         #declare loc = < -2.54847, 0.2, 30.104 > + < 5.1423, 0, 6.12836 
 > + 8 * <sin(radians(130+90-0.080288-( 1.43239 * ( clock-240)))), 0, 
cos(radians(130+90-0.080288-( 1.43239 * ( clock-240))))>;
         #declare ldir = vrotate(<0, 0, 1>, 
y*(130-0.080288-(1.43239*(clock - 240))));
         location loc
         look_at loc+ldir
       #break
       #range(261, 321) // track segment #6: 12 metres straight; total 
length = 63.8078
         #declare loc = < 1.20465, 0.2, 28.3539 > + < 0, 0, -0> + < 
0.196962* (clock-261), 0, -0.0347296 * (clock-261)>;
         #declare ldir = vrotate(<0, 0, 1>, y*100);
         location loc
         look_at loc+ldir
       #break
     #end
     angle 40
   }
#end


// end of code

And here the C++ source code:

// makemm version 0.1
// A utility to generate PoV-Ray scripts for animating camera rides 
along railroad tracks
// (C) 2009 by Jörg "Yadgar" Bleimann (yaz### [at] gmxde, 
http://www.khyberspace.de)
// Thanks to 0xdeadbeef for the implementation of the "explode" function


#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
#include <cmath>
using namespace std;

// begin code by 0xdeadbeef

template <typename to, typename from>
to convert(from const &src) {
   stringstream converter;
   to dest;

   converter << src;
   converter >> dest;

   if(!converter) {
     throw invalid_argument("Conversion failed");
   }

   return dest;
}



vector<string> explode (string const &line, char delim)
{
   istringstream in(line);
   vector<string> result;
   string token;

   while(getline(in, token, delim))
   {
     result.push_back(token);
   }

   return result;
}
// end code by 0xdeadbeef

int main(int argc, char* argv[])
{
   double x, y, z, d, sp;
   unsigned short fps; // animation frames per second
   double loc_y; // camera height above track

   x = atof(argv[1]);
   y = atof(argv[2]);
   z = atof(argv[3]);
   d = atof(argv[4]);
   sp = atof(argv[5]); // provisional version of makemm: constant speed 
of camera ride, to be replaced later on by a speed script, see also line 149
   fps = atoi(argv[6]);
   loc_y = atof(argv[7]);

   ifstream track;
   string track_name;

   cout << "Track script? ";
   cin >> track_name;

   track.open(track_name.c_str());

   if (!track)
   {
     cerr << track_name << " cannot be opened!\n";
     exit (-1);
   }

   ofstream anim;
   string anim_name;

   char ch;
   vector<char> buffer;
   unsigned short segments=0;

   while (track.get(ch))
   {
     buffer.push_back(ch);
     if (ch == '\n') segments++;
   };


   track.close();

   cout << "Animation script? ";
   cin >> anim_name;

   anim.open(anim_name.c_str());

   if (!anim)
   {
     cerr << anim_name << " cannot be opened!\n";
     exit (-1);
   }

   anim << "// INSERTION GENERATED WITH MAKEMM" << endl;
   anim << endl;
   anim << "// INSERTION BEGIN" << endl;
   anim << "#declare RailElements = array[" << segments << "][3];" << endl;
   anim << "#declare i=0;" << endl;
   anim << "#declare ty =0;" << endl;
   anim << "#declare s = 0;" << endl;
   anim << "#declare r = 0;" << endl;
   anim << endl;
   anim << "#fopen RailData \"" << track_name << "\" read" << endl;
   anim << "  #while (defined(RailData))" << endl;
   anim << "    #read (RailData,ty,s, r)" << endl;
   anim << "    #declare RailElements[i][0] = ty;" << endl;
   anim << "    #declare RailElements[i][1] = s;" << endl;
   anim << "    #declare RailElements[i][2] = r;" << endl;
   anim << "    #declare i=i+1;" << endl;
   anim << "  #end" << endl;
   anim << "#fclose RailData" << endl;
   anim << endl;
   anim << "#declare trans_general = <" << argv[1] << ", " << argv[2] << 
", " << argv[3] << ">;" << endl;
   anim << "#declare d_general = " << argv[4] << ";" << endl;
   anim << endl;
   anim << "#declare i = 0; // loop counter" << endl;
   anim << "#declare trans = trans_general; // position of first rail 
segment (center of front side)" << endl;
   anim << "#declare d = d_general; // orientation (degrees) of first 
rail segment" << endl;
   anim << endl;
   anim << "#while (i < " << segments << ")" << endl;
   anim << "  #switch (RailElements[i][0])" << endl;
   anim << "    #case (0)" << endl;
   anim << "      object" << endl;
   anim << "      {" << endl;
   anim << "        StraightRail(RailElements[i][1])" << endl;
   anim << "        rotate y*d" << endl;
   anim << "        translate trans" << endl;
   anim << "        #declare trans = trans+vrotate(<0, 0, 
RailElements[i][1]>,<0, d, 0>);" << endl;
   anim << "      }" << endl;
   anim << "    #break" << endl;
   anim << "    #case (1)" << endl;
   anim << "      object" << endl;
   anim << "      {" << endl;
   anim << "        BendRail(RailElements[i][2], RailElements[i][1])" << 
endl;
   anim << "        rotate y*d" << endl;
   anim << "        translate trans" << endl;
   anim << "        // begin of Martin's code" << endl;
   anim << "        #declare dir= select(RailElements[i][1],1,-1,-1);" 
<< endl;
   anim << "        #declare pt= vrotate(x*(RailElements[i][2])*dir, 
RailElements[i][1]*y)-x*RailElements[i][2]*dir;" << endl;
   anim << "        #declare trans= trans+vrotate(pt,y*d);" << endl;
   anim << "        // end of Martin's code" << endl;
   anim << "        #declare d = d+RailElements[i][1];" << endl;
   anim << "      }" << endl;
   anim << "    #break" << endl;
   anim << "  #end" << endl;
   anim << "  #declare i=i+1;" << endl;
   anim << "#end" << endl;
   anim << endl;
   anim << "#declare i=0;" << endl;
   anim << "#declare trans=trans_general; // position of first ground 
cutout segment (center of front side)" << endl;
   anim << "#declare d=d_general; // orientation (degrees) of first 
ground cutout segment" << endl;
   anim << endl;
   anim << "#declare Ground_Cutout =" << endl;
   anim << "union" << endl;
   anim << "{" << endl;
   anim << "  #while (i<" << segments << ")" << endl;
   anim << "    #switch (RailElements[i][0])" << endl;
   anim << "      #case (0)" << endl;
   anim << "        object" << endl;
   anim << "        {" << endl;
   anim << "          Straight_GroundCutout(RailElements[i][1])" << endl;
   anim << "          rotate y*d" << endl;
   anim << "          translate trans" << endl;
   anim << "          #declare trans = trans+vrotate(<0, 0, 
RailElements[i][1]>,<0, d, 0>);" << endl;
   anim << "        }" << endl;
   anim << "      #break" << endl;
   anim << "      #case (1)" << endl;
   anim << "        object" << endl;
   anim << "        {" << endl;
   anim << "          Bend_GroundCutout(RailElements[i][2], 
RailElements[i][1])" << endl;
   anim << "          rotate y*d" << endl;
   anim << "          translate trans" << endl;
   anim << "          // begin of Martin's code" << endl;
   anim << "          #declare dir= select(RailElements[i][1],1,-1,-1);" 
<< endl;
   anim << "          #declare pt= vrotate(x*(RailElements[i][2])*dir, 
RailElements[i][1]*y)-x*RailElements[i][2]*dir;" << endl;
   anim << "          #declare trans= trans+vrotate(pt,y*d);" << endl;
   anim << "          // end of Martin's code" << endl;
   anim << "          #declare d = d+RailElements[i][1];" << endl;
   anim << "        }" << endl;
   anim << "      #break" << endl;
   anim << "    #end" << endl;
   anim << "    #declare i=i+1;" << endl;
   anim << "  #end" << endl;
   anim << "}" << endl;
   anim << endl;
   anim << "difference" << endl;
   anim << "{" << endl;
   anim << "  plane" << endl;
   anim << "  {" << endl;
   anim << "    y, 0" << endl;
   anim << "    texture { T_Simple_Green }" << endl;
   anim << "  }" << endl;
   anim << "  object { Ground_Cutout translate -y*0.45 }" << endl;
   anim << "}" << endl;
   anim << endl;
   // provisional version of makemm: constant speed of camera ride, to 
be replaced later on by a speed script
   anim << "#declare speed = " << sp << "; // metres/second" << endl;
   anim << "#declare fps = " << fps << "; // animation frames per 
second" << endl;
   anim << endl;
   anim << "#if (ani)" << endl;
   anim << "  camera" << endl;
   anim << "  {" << endl;
   anim << "    #switch (clock)" << endl;

   unsigned short i = 0; // counter for track segments in animation 
sequences loop
   unsigned long j = 0; // counter for vector elements in "buffer"
   unsigned long start_s = 0; // frame number at beginning of each 
animation sequence
   unsigned long end_s = 100; // frame number at end of each animation 
sequence, provisionally initialized with a dummy value


   start_s = 0; //
   end_s = 0;
   i = 0; // track segment counter

   double length; // segment's length in metres
   double total_length = 0; // cumulated length of track segments
   bool t; // segment type: false = straight, true = curved
   double arc;    // curved segment's arc size in degrees
   double radius; // curved segment's radius width in metres
   double compart; // either length or arc size
   string comment; // adds information about each track segment
   string type;   // segment's type (to be printed into comment for each 
#range section)
   string direction; // curved segment's direction (left or right)
   string line(""); // stores current track script line
   vector<string> numbers; // stores numerals extracted from line as string
   double step = sp/fps; // movement per frame in metres
   double remain; // remaining track length of each segment after at 
last frame
   double offset; // track length allready travelled at fist frame of 
segment (for all i>1)
   double offset_x; // x component of offset vector
   double offset_z; // z component of offset vector
   const double pi = 3.141592265359;
   double loc_x; // x coordinate of camera position
   double loc_z; // z coordinate of camera position
   double ldir_x = 0; // x component of look_at vector
   const double ldir_y = 0; // y component of look_at vector (fixed)
   double ldir_z = 1; // z component of look_at vector (default pointing 
at N = 0 degrees azimuth)
   string lookat; // vrotate transformation for look_at vector
   double start_x; // x coordinate of each segment's starting point
   const double start_y = 0; // y coordinate of each segment's starting 
point (fixed)
   double start_z;
   double end_x; // x coordinate of each segment's end point
   const double end_y = y + loc_y; // y coordinate of each segment's end 
point (fixed)
   double end_z; // z coordinate of each segment's end point
   double center_x; // x coordinate of center point (curved segments only)
   double center_z; // z coordinate of center point (curved segments only)
   double arcstep;  // distance on curved segment travelled per frame
   string arcsign;  // clockwise vs. anti-clockwise curving
   string arcsign_lookat; // clockwise vs. anti-clockwise curving
   double arcoffset; // length offset converted to arc offset
   double d_old; // orientation of last segment
   double d_end; // orientation at end of current segment;


   while (j < buffer.size())
   {
     line.append(1, buffer.at(j));
     if (buffer.at(j)=='\n')
     {
       i++;
       // begin code by 0xdeadbeef
       numbers = explode(line, ',');
       try
       {
         t = convert<bool>(numbers.at(0));
       }
       catch(exception &e)
       {
         cerr << "Error while processing \"" << numbers.at(0) << "\": "
              << e.what() << endl;
       }
       try
       {
         if (!t)
           length = convert<double>(numbers.at(1));
         else
           arc = convert<double>(numbers.at(1));
       }
       catch(exception &e)
       {
         cerr << "Error while processing \"" << numbers.at(1) << "\": "
              << e.what() << endl;
       }
       try
       {
         if (t)
           radius = convert<double>(numbers.at(2));
       }
       catch(exception &e)
       {
         cerr << "Error while processing \"" << numbers.at(1) << "\": "
              << e.what() << endl;
       }
       // end code by 0xdeadbeef
       line = "";
       if (!t)
       {
         compart = length;
         total_length += length;
         comment = " metres straight; total length = ";
         if (i==1)
         {
           d_old = atof(argv[4]);
           start_s = 0;
           loc_x = sin(d_old*(pi/180))*step;
           loc_z = cos(d_old*(pi/180))*step;
           start_x = x;
           start_z = z;
         }
         else
         {
           start_s = end_s + 1;
           loc_x = sin(d_end*(pi/180))*step;
           loc_z = cos(d_end*(pi/180))*step;
           start_x = end_x;
           start_z = end_z;
           d_old = d_end;
         }
         d_end = d_old;
         end_x = start_x + length*sin(d_end*(pi/180));
         end_z = start_z + length*cos(d_end*(pi/180));
         end_s = start_s + length/step;
         anim << "      #range(" << start_s << ", " << end_s << ") // 
track segment #" << i << ": " << compart << comment << total_length 
    << endl;
         remain = length - (end_s - start_s)*step;
         if (remain > 0)
           offset = step - remain;
         else
           offset = 0;
         offset_x = offset*sin(d_end*(pi/180));
         offset_z = offset*cos(d_end*(pi/180));
         d_old = d;
         anim << "        #declare loc = < " << start_x << ", " << loc_y 
<< ", " << start_z << " > + < " << offset_x << ", " << 0 << ", " << 
offset_z << "> + < " << loc_x << "* (clock-" << start_s << "), " << 0 << 
", " << loc_z << " * (clock-" << start_s << ")>;" << endl;
         anim << "        #declare ldir = vrotate(<" << ldir_x << ", " 
<< ldir_y << ", " << ldir_z << ">, y*" << d_end << ");" << endl;

       }
       else
       {
         compart = abs(arc);
         length = compart * (pi/180) * radius;
         total_length += length;
         arcstep = step / (pi * radius) * 180;
         if (i==1)
         {
           start_s = 0;
           start_x = x;
           start_z = z;
           d_old = atof(argv[4]);
         }
         else
         {
           start_s = end_s + 1;
           start_x = end_x;
           start_z = end_z;
           d_old = d_end;
         }
         d_end = d_old+arc;
         if (arc > 0)
         {
           direction = "right ";
           center_x = radius * sin((d_old+90)*(pi/180));
           center_z = radius * cos((d_old+90)*(pi/180));
           arcsign = "-";
           arcsign_lookat = "+";
           //arcterm = "-90+arcstep*clock)";
           end_x = start_x + center_x + radius * 
sin((d_old-90+arc)*(pi/180));
           end_z = start_z + center_z + radius * 
cos((d_old-90+arc)*(pi/180));
           // loc_x = radius * sin((d-90
         }
         else
         {
           direction = "left ";
           center_x = radius * sin((d_old-90)*(pi/180));
           center_z = radius * cos((d_old-90)*(pi/180));
           arcsign = "+";
           arcsign_lookat = "-";
           // arcterm = "+90-arcstep*clock)";
           end_x = start_x + center_x + radius * 
sin((d_old+90+arc)*(pi/180));
           end_z = start_z + center_z + radius * 
cos((d_old+90+arc)*(pi/180));
         }


         end_s = start_s + length/step;
         remain = length - (end_s - start_s)*step;
         if (remain > 0)
           offset = step - remain;
         else
           offset = 0;
         arcoffset = offset / (radius * pi) * 180;

         comment = " degrees " + direction;
         comment += "turn; total length = ";
         anim << "      #range(" << start_s << ", " << end_s << ") // 
track segment #" << i << ": " << compart << comment << total_length 
    << endl;
         anim << "        #declare loc = < " << start_x << ", " << loc_y 
<< ", " << start_z << " > + < " << center_x << ", " << 0 << ", " << 
center_z << " > + " << radius << " * <sin(radians("<< d_old << arcsign 
<< "90" << arcsign_lookat << arcoffset << arcsign_lookat << "( " << 
arcstep << " * ( clock-" << start_s << ")))), " << 0 << ", 
cos(radians("<< d_old << arcsign << "90" << arcsign_lookat << arcoffset 
<< arcsign_lookat << "( " << arcstep << " * ( clock-" << start_s << 
"))))>;" << endl;
         anim << "        #declare ldir = vrotate(<" << ldir_x << ", " 
<< ldir_y << ", " << ldir_z << ">, y*(" << d_old << arcsign_lookat << 
arcoffset << arcsign_lookat << "(" << arcstep << "*(clock - " << start_s 
<< "))));" << endl;
       }


       anim << "        location loc" << endl;
       anim << "        look_at loc+ldir" << endl;
       anim << "      #break" << endl;
     }
     j++;

   }
    anim << "    #end" << endl;
    anim << "    angle 40" << endl;
    anim << "  }" << endl;
    anim << "#end" << endl;



   return 0;
}

// end of code

Have fun!

See you in Khyberspace!

Yadgar


Post a reply to this message

From: Warp
Subject: Re: MyMaglev animation sequence generator
Date: 3 Jul 2009 05:14:19
Message: <4a4dcbeb$1@news.povray.org>
Want some commentary on your C++ program?


Post a reply to this message

From: Jörg 'Yadgar' Bleimann
Subject: Re: MyMaglev animation sequence generator
Date: 3 Jul 2009 06:17:51
Message: <4a4ddacf@news.povray.org>
High!

Warp wrote:
>   Want some commentary on your C++ program?

Yes, I thought so...

See you in Khyberspace!

Yadgar


Post a reply to this message

From: Warp
Subject: Re: MyMaglev animation sequence generator
Date: 3 Jul 2009 06:31:29
Message: <4a4dde01@news.povray.org>

> High!
> 
> Warp wrote:
>>   Want some commentary on your C++ program?
> 
> Yes, I thought so...

  I apologize, I don't understand your answer...


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.