20 void apply(vtkCamera *camera,
const Eigen::Vector3d ¢er,
const Eigen::Vector3d &
axis,
21 double degreesPerFrame,
size_t frameID,
double advancePerFrame = 0.0)
23 if(!center.allFinite() || !
axis.allFinite() ||
axis.stableNorm() == 0.0 || !std::isfinite(degreesPerFrame) || !std::isfinite(advancePerFrame))
25 throw std::invalid_argument(
"Enter a finite, nonzero rotation axis and finite angle and advance.");
27 if(lastCamera.GetPointer() != camera)
29 applied.setIdentity();
35 const long double degrees = std::fmod(
static_cast<long double>(degreesPerFrame) * frameID, 360.0L);
36 const Eigen::Matrix3d target = Eigen::AngleAxisd(
37 static_cast<double>(degrees) * std::acos(-1.0) / 180.0,
axis.stableNormalized()).toRotationMatrix();
38 if(degreesPerFrame == 0.0 && advancePerFrame == 0.0 && !advanced && target.isApprox(applied, 1.e-14))
45 const Eigen::Matrix3d change = target * applied.transpose();
46 const Eigen::Vector3d focal(camera->GetFocalPoint());
47 const Eigen::Vector3d offset = change * (Eigen::Vector3d(camera->GetPosition()) - focal);
48 const double travel = advancePerFrame *
static_cast<double>(frameID);
49 if(!std::isfinite(travel))
51 throw std::invalid_argument(
"Camera advance times frameID must be finite.");
53 Eigen::Vector3d targetFocal = center;
54 if(offset.stableNorm()>0.0)
56 targetFocal -= travel * offset.stableNormalized();
60 const Eigen::Vector3d position = targetFocal + offset;
61 if(advancePerFrame != 0.0)
63 camera->ParallelProjectionOff();
65 const Eigen::Vector3d up = change * Eigen::Vector3d(camera->GetViewUp());
66 camera->SetFocalPoint(targetFocal.data());
67 camera->SetPosition(position.data());
68 camera->SetViewUp(up.data());
69 camera->OrthogonalizeViewUp();
71 advanced = advancePerFrame != 0.0;