[vtkusers] Making camera follow a path defined by a set of points

tom fogal tfogal at apollo.sr.unh.edu
Tue Nov 9 10:14:55 EST 2004


 <20041109081056.99346.qmail at web61109.mail.yahoo.com>s comp writes:
>How could I make the camera follow a path defined by a set of points? Also I would like to define the camera direction by this set of point
>s.
> 
>Specifically I am thinking of making the camera follow a streamline of  a vector field.

Sonam,

I have done something similar to this before. You want to manually
interpolate a point through a vector field. I did this using
vtkRungeKutta4, but I think any vtkInitialProblemSolver will work.

Basically the code is:

void GGCMAnimator::InterpolatePoint(const double* seed, double *end,
const double time, vtkDataSet *Interpolated)
{
   double unused; //RK4 ignores these parameters
   double mod_time = time;
   double range[2];
   int rk4_error;
   /* here we have a problem. we declared 'seed' to be const, but
    * RungeKutta4 isn't const correct. I'm almost positive the first
    * argument to ComputeNextStep isn't changed, but we're not
	 * guaranteed that by the prototype.
    * So we copy 'seed's value, const_cast it to a mutable value, pass
    * the mutable into ComputeNextStep, and then restore the value. */
   double *seed2 = const_cast<double*>(seed);
   double seed_orig[3] = {seed[0], seed[1], seed[2]};

   vtkRungeKutta4               *RK4 = vtkRungeKutta4::New();
   vtkInterpolatedVelocityField *IntVField =
                                vtkInterpolatedVelocityField::New();

   Interpolated->GetPointData()->GetVectors()->GetRange(range);
#ifdef DEBUG
   std::cerr << "range: " << range[0] << ',' << range[1] << "\n";
#endif //DEBUG
   IntVField->AddDataSet(Interpolated);
   IntVField->SelectVectors("V");
   IntVField->CachingOff(); /* hopefully will save some memory ? */
   RK4->SetFunctionSet(IntVField);

   /* pass in mutable 'seed2'... */
   rk4_error = RK4->ComputeNextStep(seed2, end, 0.0, mod_time, unused,
unused);
   /* restore seed value (probably the same anyway...) */
   seed2[0] = seed_orig[0];
   seed2[1] = seed_orig[1];
   seed2[2] = seed_orig[2];
   if(rk4_error) {
      std::cerr << "Error interpolating seed through velocity field!:
";
      switch(rk4_error) {
         case 1: std::cerr  << "Out of domain\n";    break;
         case 2: std::cerr  << "Not initialized\n";  break;
         case 3: std::cerr  << "Unexpected value\n"; break;
         default: std::cerr << "should never get here...\n"; break;
      }
   }

   IntVField->Delete();
   RK4->Delete();
}

( sorry -- things are a little overcomplicated because my application is
const-correct but VTK is not :\ )

You basically give it a an XYZ double start point, space for an
endpoint, the "time" you want to interpolate, which should be a
percentage between 0 and 1, and then finally the dataset that has the
vector field. The vectors it uses for the vector field come from the
dataset -> PointData -> GetVectors(), or the active vectors for the
dataset.
You must copy the data set to a 'vtkInterpolatedVelocityField',
because thats what vtkInitialProblemSolver's accept. This seems to
require a great deal of overhead (at least memory-wise), unfortunately.
Perhaps you are lucky enough to be working with smaller datasets (mine
are typically 30-70meg on disk, and much larger when loaded into
memory).

>I guess this a matter of just "doing the work", but I suppose someone might have done something like this before, and could offer some sugg
>estions or advice.

My application generates time-evolved animations of streamlines plotted
through a magnetic field, where the seeds move according to a different
vector field. I had never thought of moving the camera according to a
field -- that could have a nice effect.
Anyway if you can be more specific about your application maybe I've
also done some other parts of your work and could share some more code.

HTH,

-tom



More information about the vtkusers mailing list