189 lines
6.5 KiB
C++
189 lines
6.5 KiB
C++
// rotation.h
|
|
//
|
|
// Copyright (C) 2004-2009, the Celestia Development Team
|
|
// Original version by Chris Laurel <claurel@gmail.com>
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
|
|
#ifndef _CELENGINE_ROTATION_H_
|
|
#define _CELENGINE_ROTATION_H_
|
|
|
|
#include <Eigen/Geometry>
|
|
|
|
|
|
/*! A RotationModel object describes the orientation of an object
|
|
* over some time range.
|
|
*/
|
|
class RotationModel
|
|
{
|
|
public:
|
|
virtual ~RotationModel() = default;
|
|
|
|
/*! Return the orientation of an object in its reference frame at the
|
|
* specified time (TDB). Some rotations can be decomposed into two parts:
|
|
* a fixed or slowly varying part, and a much more rapidly varying part.
|
|
* The rotation of a planet is such an example. The rapidly varying part
|
|
* is referred to as spin; the slowly varying part determines the
|
|
* equatorial plane. When the rotation of an object can be decomposed
|
|
* in this way, the overall orientation = spin * equator. Otherwise,
|
|
* orientation = spin.
|
|
*/
|
|
Eigen::Quaterniond orientationAtTime(double tjd) const
|
|
{
|
|
return spin(tjd) * equatorOrientationAtTime(tjd);
|
|
}
|
|
|
|
virtual Eigen::Vector3d angularVelocityAtTime(double tjd) const;
|
|
|
|
/*! Return the orientation of the equatorial plane (normal to the primary
|
|
* axis of rotation.) The overall orientation of the object is
|
|
* spin * equator. If there is no primary axis of rotation, equator = 1
|
|
* and orientation = spin.
|
|
*/
|
|
virtual Eigen::Quaterniond equatorOrientationAtTime(double /*tjd*/) const
|
|
{
|
|
return Eigen::Quaterniond::Identity();
|
|
}
|
|
|
|
/*! Return the rotation about primary axis of rotation (if there is one.)
|
|
* The overall orientation is spin * equator. For objects without a
|
|
* primary axis of rotation, spin *is* the orientation.
|
|
*/
|
|
virtual Eigen::Quaterniond spin(double tjd) const = 0;
|
|
|
|
virtual double getPeriod() const
|
|
{
|
|
return 0.0;
|
|
};
|
|
|
|
virtual bool isPeriodic() const
|
|
{
|
|
return false;
|
|
};
|
|
|
|
// Return the time range over which the orientation model is valid;
|
|
// if the model is always valid, begin and end should be equal.
|
|
virtual void getValidRange(double& begin, double& end) const
|
|
{
|
|
begin = 0.0;
|
|
end = 0.0;
|
|
};
|
|
};
|
|
|
|
|
|
/*! CachingRotationModel is an abstract base class for complicated rotation
|
|
* models that are computationally expensive. The last calculated spin,
|
|
* equator orientation, and angular velocity are all cached and reused in
|
|
* order to avoid redundant calculation. Subclasses must override computeSpin(),
|
|
* computeEquatorOrientation(), and getPeriod(). The default implementation
|
|
* of computeAngularVelocity uses differentiation to approximate the
|
|
* the instantaneous angular velocity. It may be overridden if there is some
|
|
* better means to calculate the angular velocity for a specific rotation
|
|
* model.
|
|
*/
|
|
class CachingRotationModel : public RotationModel
|
|
{
|
|
public:
|
|
CachingRotationModel();
|
|
virtual ~CachingRotationModel() = default;
|
|
|
|
Eigen::Quaterniond spin(double tjd) const;
|
|
Eigen::Quaterniond equatorOrientationAtTime(double tjd) const;
|
|
Eigen::Vector3d angularVelocityAtTime(double tjd) const;
|
|
|
|
virtual Eigen::Quaterniond computeEquatorOrientation(double tjd) const = 0;
|
|
virtual Eigen::Quaterniond computeSpin(double tjd) const = 0;
|
|
virtual Eigen::Vector3d computeAngularVelocity(double tjd) const;
|
|
virtual double getPeriod() const = 0;
|
|
virtual bool isPeriodic() const = 0;
|
|
|
|
private:
|
|
mutable Eigen::Quaterniond lastSpin;
|
|
mutable Eigen::Quaterniond lastEquator;
|
|
mutable Eigen::Vector3d lastAngularVelocity;
|
|
mutable double lastTime;
|
|
mutable bool spinCacheValid;
|
|
mutable bool equatorCacheValid;
|
|
mutable bool angularVelocityCacheValid;
|
|
};
|
|
|
|
|
|
/*! The simplest rotation model is ConstantOrientation, which describes
|
|
* an orientation that is fixed within a reference frame.
|
|
*/
|
|
class ConstantOrientation : public RotationModel
|
|
{
|
|
public:
|
|
ConstantOrientation(const Eigen::Quaterniond& q);
|
|
virtual ~ConstantOrientation() = default;
|
|
|
|
virtual Eigen::Quaterniond spin(double tjd) const;
|
|
virtual Eigen::Vector3d angularVelocityAtTime(double tjd) const;
|
|
|
|
private:
|
|
Eigen::Quaterniond orientation;
|
|
};
|
|
|
|
|
|
/*! UniformRotationModel describes an object that rotates with a constant
|
|
* angular velocity.
|
|
*/
|
|
class UniformRotationModel : public RotationModel
|
|
{
|
|
public:
|
|
UniformRotationModel(double _period,
|
|
float _offset,
|
|
double _epoch,
|
|
float _inclination,
|
|
float _ascendingNode);
|
|
virtual ~UniformRotationModel() = default;
|
|
|
|
virtual bool isPeriodic() const;
|
|
virtual double getPeriod() const;
|
|
virtual Eigen::Quaterniond equatorOrientationAtTime(double tjd) const;
|
|
virtual Eigen::Quaterniond spin(double tjd) const;
|
|
virtual Eigen::Vector3d angularVelocityAtTime(double tjd) const;
|
|
|
|
private:
|
|
double period; // sidereal rotation period
|
|
float offset; // rotation at epoch
|
|
double epoch;
|
|
float inclination; // tilt of rotation axis w.r.t. reference plane
|
|
float ascendingNode; // longitude of ascending node of equator on the refernce plane
|
|
};
|
|
|
|
|
|
/*! PrecessingRotationModel describes an object with a spin axis that
|
|
* precesses at a constant rate about some axis.
|
|
*/
|
|
class PrecessingRotationModel : public RotationModel
|
|
{
|
|
public:
|
|
PrecessingRotationModel(double _period,
|
|
float _offset,
|
|
double _epoch,
|
|
float _inclination,
|
|
float _ascendingNode,
|
|
double _precPeriod);
|
|
virtual ~PrecessingRotationModel() = default;
|
|
|
|
virtual bool isPeriodic() const;
|
|
virtual double getPeriod() const;
|
|
virtual Eigen::Quaterniond equatorOrientationAtTime(double tjd) const;
|
|
virtual Eigen::Quaterniond spin(double tjd) const;
|
|
|
|
private:
|
|
double period; // sidereal rotation period (in Julian days)
|
|
float offset; // rotation at epoch
|
|
double epoch;
|
|
float inclination; // tilt of rotation axis w.r.t. reference plane
|
|
float ascendingNode; // longitude of ascending node of equator on the refernce plane
|
|
|
|
double precessionPeriod; // period of precession (in Julian days)
|
|
};
|
|
|
|
#endif // _CELENGINE_ROTATION_H_
|