Reference Frames and Transformations
This topic builds upon the foundation of geometrical and coordinate primitives discussed in the Axes, Points, and Vectors and Coordinates topics. To begin, we define the geometrical concept of a ReferenceFrame as a location point (origin) and a set of axes. A common example of a reference frame is the Earth's fixed frame, EarthCentralBody.FixedFrame (get / set). In this frame, the Point defining the origin is at the center of mass of the Earth and the Axes are aligned such that (in Cartesian coordinates) the Z-axis is pointed North and the X-axis intersects the surface at 0 latitude, 0 longitude. The Y-axis is then defined by the right-hand rule.
GeometryTransformer allows you to easily transform between geometry components by following the chain of relationships between them. One of the primary uses of the transformer is to allow the user to switch between two reference frames. The following example shows how to obtain an evaluator for the transformation between the Earth fixed and Earth inertial reference frames and use it to find an equivalent inertial vector for a given fixed vector:
//Get the Earth central body and assign Earth Orientation Parameters using //the EOP data file located in the directory identified by 'dataPath'. EarthCentralBody earth = CentralBodiesFacet.getFromContext().getEarth(); String eopPath = new File(dataPath, "EOP-v1.1.txt").getPath(); earth.setOrientationParameters(EarthOrientationParametersFile.readData(eopPath)); // Get an evaluator to transform from the fixed to inertial frames, and evaluate it // at 'now' to get the actual transformation. ReferenceFrameEvaluator evaluator = GeometryTransformer.getReferenceFrameTransformation(earth.getFixedFrame(), earth.getInertialFrame()); KinematicTransformation transformation = evaluator.evaluate(JulianDate.getNow(), 0); // Use the transformation to transform a vector in the fixed frame to the inertial frame. Cartesian fixedVectorToTransform = new Cartesian(1.0, 2.0, 3.0); Cartesian equivalentInertialVector = transformation.transform(fixedVectorToTransform);
Each geometry component is defined relative to another geometry component. A Point is defined in a ReferenceFrame. A Vector is defined in a set of Axes. A set of Axes or a ReferenceFrame is defined in terms of another set of Axes or a ReferenceFrame, respectively. However, each Point is not necessarily defined in terms of the same ReferenceFrame all the time. For example, the Point representing a spacecraft traveling toward the Moon may initially be defined in an Earth-centered ReferenceFrame. As it gets closer to the Moon, it may switch to a Moon-centered ReferenceFrame. To handle this, the geometry components' evaluators have a property called DefinedInIntervals (get) which identifies the ReferenceFrame or Axes in which the component is defined over that interval. In the case of the interplanetary trajectory, the DefinedInIntervals (get) collection contains two TimeInterval<ReferenceFrame> objects. The first holds the Earth-centered ReferenceFrame in its Data (get) property, and the second holds the Moon-centered ReferenceFrame as its Data (get). The first interval stops at the same time the second interval starts, with the IsStartIncluded (get) and IsStopIncluded (get) properties of the TimeInterval<ReferenceFrame> indicating which system is used at that time. This allows a single geometry component to be defined in different systems at different times.
In general, it is best to use the GeometryTransformer to observe the geometry in the desired system. However, to find the Axes or ReferenceFrame in which a component is defined at a given time, call the findIntervalContainingDate method with the JulianDate used to evaluate the component. Then, get the Data (get) property of the TimeInterval<T>.
Each geometry component knows how to evaluate itself with respect to the components held in DefinedInIntervals (get). For example, if a PointEvaluator is defined in the Earth fixed frame, then calling evaluate will return the position and its derivatives with respect to the Earth fixed frame. To obtain the position, velocity, acceleration, etc. with respect to the Earth inertial frame instead, use the GeometryTransformer.observePoint method, as shown in the next example.
//Get the Earth central body and assign Earth Orientation Parameters using //the EOP data file located in the same directory as this example code. EarthCentralBody earth = CentralBodiesFacet.getFromContext().getEarth(); String eopPath = new File(dataPath, "EOP-v1.1.txt").getPath(); earth.setOrientationParameters(EarthOrientationParametersFile.readData(eopPath)); // Create a point at a fixed location with respect to the Earth fixed reference frame. PointFixedOffset point = new PointFixedOffset(earth.getFixedFrame(), new Cartesian(8000000.0, 0.0, 0.0)); // Get an evaluator which can transform the point into the Earth inertial // reference frame at a given time. PointEvaluator evaluator = GeometryTransformer.observePoint(point, earth.getInertialFrame()); // Evaluate the evaluator 'now'. The point is stationary with respect to the fixed frame, but // it is moving with respect to the inertial frame. Motion1<Cartesian> positionAndVelocity = evaluator.evaluate(JulianDate.getNow(), 1);
For a Point, the GeometryTransformer follows the chains created by the ReferenceFrame in the DefinedInIntervals (get) to determine the shortest sequence of transformations between any two geometry components. In general, whenever creating an evaluator to evaluate vector geometry, it is best to get the evaluator through the GeometryTransformer rather than calling getEvaluator on a particular geometry component itself. This ensures that the evaluator computes the geometry in the expected reference system.
Lastly, new geometry components can be easily added by deriving from Axes, Point, or Vector and creating the corresponding AxesEvaluator, PointEvaluator, or VectorEvaluator respectively. These user-defined components can then participate in GeometryTransformer transformations and other geometry types just like the existing components included with STK Components.
The geometry components can be found in the agi.foundation.geometry package.