[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