261 lines
8.3 KiB
C++
261 lines
8.3 KiB
C++
// frame.h
|
|
//
|
|
// Copyright (C) 2003-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_FRAME_H_
|
|
#define _CELENGINE_FRAME_H_
|
|
|
|
#include <celengine/astro.h>
|
|
#include <celengine/selection.h>
|
|
#include <Eigen/Core>
|
|
#include <Eigen/Geometry>
|
|
#include "shared.h"
|
|
|
|
/*! A ReferenceFrame object has a center and set of orthogonal axes.
|
|
*
|
|
* Subclasses of ReferenceFrame must override the getOrientation method
|
|
* (which specifies the coordinate axes at a given time) and the
|
|
* nestingDepth() method (which is used to check for recursive frames.)
|
|
*/
|
|
class ReferenceFrame
|
|
{
|
|
public:
|
|
SHARED_TYPES(ReferenceFrame)
|
|
|
|
ReferenceFrame(Selection center);
|
|
virtual ~ReferenceFrame() {};
|
|
|
|
UniversalCoord convertFromUniversal(const UniversalCoord& uc, double tjd) const;
|
|
UniversalCoord convertToUniversal(const UniversalCoord& uc, double tjd) const;
|
|
Eigen::Quaterniond convertFromUniversal(const Eigen::Quaterniond& q, double tjd) const;
|
|
Eigen::Quaterniond convertToUniversal(const Eigen::Quaterniond& q, double tjd) const;
|
|
|
|
Eigen::Vector3d convertFromAstrocentric(const Eigen::Vector3d& p, double tjd) const;
|
|
Eigen::Vector3d convertToAstrocentric(const Eigen::Vector3d& p, double tjd) const;
|
|
|
|
Selection getCenter() const;
|
|
|
|
virtual Eigen::Quaterniond getOrientation(double tjd) const = 0;
|
|
virtual Eigen::Vector3d getAngularVelocity(double tdb) const;
|
|
|
|
virtual bool isInertial() const = 0;
|
|
|
|
enum FrameType
|
|
{
|
|
PositionFrame = 1,
|
|
OrientationFrame = 2,
|
|
};
|
|
|
|
unsigned int nestingDepth(unsigned int maxDepth, FrameType) const;
|
|
|
|
virtual unsigned int nestingDepth(unsigned int depth,
|
|
unsigned int maxDepth,
|
|
FrameType frameType) const = 0;
|
|
|
|
private:
|
|
Selection centerObject;
|
|
};
|
|
|
|
|
|
/*! Base class for complex frames where there may be some benefit
|
|
* to caching the last calculated orientation.
|
|
*/
|
|
class CachingFrame : public ReferenceFrame
|
|
{
|
|
public:
|
|
SHARED_TYPES(CachingFrame)
|
|
|
|
CachingFrame(Selection _center);
|
|
virtual ~CachingFrame() {};
|
|
|
|
Eigen::Quaterniond getOrientation(double tjd) const;
|
|
Eigen::Vector3d getAngularVelocity(double tjd) const;
|
|
virtual Eigen::Quaterniond computeOrientation(double tjd) const = 0;
|
|
virtual Eigen::Vector3d computeAngularVelocity(double tjd) const;
|
|
|
|
private:
|
|
mutable double lastTime;
|
|
mutable Eigen::Quaterniond lastOrientation;
|
|
mutable Eigen::Vector3d lastAngularVelocity;
|
|
mutable bool orientationCacheValid;
|
|
mutable bool angularVelocityCacheValid;
|
|
};
|
|
|
|
|
|
//! J2000.0 Earth ecliptic frame
|
|
class J2000EclipticFrame : public ReferenceFrame
|
|
{
|
|
public:
|
|
SHARED_TYPES(J2000EclipticFrame)
|
|
|
|
J2000EclipticFrame(Selection center);
|
|
virtual ~J2000EclipticFrame() {};
|
|
|
|
Eigen::Quaterniond getOrientation(double /* tjd */) const
|
|
{
|
|
return Eigen::Quaterniond::Identity();
|
|
}
|
|
|
|
virtual bool isInertial() const;
|
|
|
|
virtual unsigned int nestingDepth(unsigned int depth,
|
|
unsigned int maxDepth,
|
|
FrameType frameType) const;
|
|
};
|
|
|
|
|
|
//! J2000.0 Earth Mean Equator
|
|
class J2000EquatorFrame : public ReferenceFrame
|
|
{
|
|
public:
|
|
SHARED_TYPES(J2000EquatorFrame)
|
|
|
|
J2000EquatorFrame(Selection center);
|
|
virtual ~J2000EquatorFrame() {};
|
|
Eigen::Quaterniond getOrientation(double tjd) const;
|
|
virtual bool isInertial() const;
|
|
virtual unsigned int nestingDepth(unsigned int depth,
|
|
unsigned int maxDepth,
|
|
FrameType frameType) const;
|
|
};
|
|
|
|
|
|
/*! A BodyFixed frame is a coordinate system with the x-axis pointing
|
|
* from the body center through the intersection of the prime meridian
|
|
* and the equator, and the z-axis aligned with the north pole. The
|
|
* y-axis is the cross product of x and z, and points toward the 90
|
|
* meridian.
|
|
*/
|
|
class BodyFixedFrame : public ReferenceFrame
|
|
{
|
|
public:
|
|
SHARED_TYPES(BodyFixedFrame)
|
|
|
|
BodyFixedFrame(Selection center, Selection obj);
|
|
virtual ~BodyFixedFrame() {};
|
|
Eigen::Quaterniond getOrientation(double tjd) const;
|
|
virtual Eigen::Vector3d getAngularVelocity(double tjd) const;
|
|
virtual bool isInertial() const;
|
|
virtual unsigned int nestingDepth(unsigned int depth,
|
|
unsigned int maxDepth,
|
|
FrameType frameType) const;
|
|
|
|
private:
|
|
Selection fixObject;
|
|
};
|
|
|
|
|
|
class BodyMeanEquatorFrame : public ReferenceFrame
|
|
{
|
|
public:
|
|
SHARED_TYPES(BodyMeanEquatorFrame)
|
|
|
|
BodyMeanEquatorFrame(Selection center, Selection obj, double freeze);
|
|
BodyMeanEquatorFrame(Selection center, Selection obj);
|
|
virtual ~BodyMeanEquatorFrame() {};
|
|
Eigen::Quaterniond getOrientation(double tjd) const;
|
|
virtual Eigen::Vector3d getAngularVelocity(double tjd) const;
|
|
virtual bool isInertial() const;
|
|
virtual unsigned int nestingDepth(unsigned int depth,
|
|
unsigned int maxDepth,
|
|
FrameType frameType) const;
|
|
|
|
private:
|
|
Selection equatorObject;
|
|
double freezeEpoch;
|
|
bool isFrozen;
|
|
};
|
|
|
|
|
|
/*! FrameVectors are used to define the axes for TwoVector frames
|
|
*/
|
|
class FrameVector
|
|
{
|
|
public:
|
|
FrameVector(const FrameVector& fv);
|
|
~FrameVector() = default;
|
|
FrameVector& operator=(const FrameVector&);
|
|
|
|
Eigen::Vector3d direction(double tjd) const;
|
|
|
|
/*! Frames can be defined in reference to other frames; this method
|
|
* counts the depth of such nesting, up to some specified maximum
|
|
* level. This method is used to test for circular references in
|
|
* frames.
|
|
*/
|
|
unsigned int nestingDepth(unsigned int depth, unsigned int maxDepth) const;
|
|
|
|
enum FrameVectorType
|
|
{
|
|
RelativePosition,
|
|
RelativeVelocity,
|
|
ConstantVector,
|
|
};
|
|
|
|
static FrameVector createRelativePositionVector(const Selection& _observer,
|
|
const Selection& _target);
|
|
static FrameVector createRelativeVelocityVector(const Selection& _observer,
|
|
const Selection& _target);
|
|
static FrameVector createConstantVector(const Eigen::Vector3d& _vec,
|
|
const ReferenceFrame::SharedConstPtr& _frame);
|
|
|
|
private:
|
|
/*! Type-only constructor is private. Code outside the class should
|
|
* use create*Vector methods to create new FrameVectors.
|
|
*/
|
|
FrameVector(FrameVectorType t);
|
|
|
|
FrameVectorType vecType;
|
|
Selection observer;
|
|
Selection target;
|
|
Eigen::Vector3d vec; // constant vector
|
|
ReferenceFrame::SharedConstPtr frame; // frame for constant vector
|
|
};
|
|
|
|
|
|
/*! A two vector frame is a coordinate system defined by a primary and
|
|
* secondary vector. The primary axis points in the direction of the
|
|
* primary vector. The secondary axis points in the direction of the
|
|
* component of the secondary vector that is orthogonal to the primary
|
|
* vector. The third axis is the cross product of the primary and
|
|
* secondary axis.
|
|
*/
|
|
class TwoVectorFrame : public CachingFrame
|
|
{
|
|
public:
|
|
/*! primAxis and secAxis are the labels of the axes defined by
|
|
* the primary and secondary vectors:
|
|
* 1 = x, 2 = y, 3 = z, -1 = -x, -2 = -y, -3 = -z
|
|
*/
|
|
TwoVectorFrame(Selection center,
|
|
const FrameVector& prim,
|
|
int primAxis,
|
|
const FrameVector& sec,
|
|
int secAxis);
|
|
virtual ~TwoVectorFrame() {};
|
|
|
|
Eigen::Quaterniond computeOrientation(double tjd) const;
|
|
virtual bool isInertial() const;
|
|
virtual unsigned int nestingDepth(unsigned int depth,
|
|
unsigned int maxDepth,
|
|
FrameType frameType) const;
|
|
|
|
//! The sine of minimum angle between the primary and secondary vectors
|
|
static const double Tolerance;
|
|
|
|
private:
|
|
FrameVector primaryVector;
|
|
int primaryAxis;
|
|
FrameVector secondaryVector;
|
|
int secondaryAxis;
|
|
int tertiaryAxis;
|
|
};
|
|
|
|
#endif // _CELENGINE_FRAME_H_
|