public abstract class Point extends DefinitionalObject implements IServiceProvider
This example shows how to create a new Point class:
// Create a new type derived from Point. This type will represent a point on the surface
// of a CentralBody formed by projecting another point onto the central body's ellipsoidal
// surface.
public static class SurfacePoint extends Point {
public SurfacePoint() {}
public SurfacePoint(CentralBody centralBody, Point referencePoint) {
m_centralBody = centralBody;
m_referencePoint = referencePoint;
}
// The copy constructor, used to make a copy of the object. Copy all of the
// fields of the 'existingInstance' to the new object. Reference types should
// be passed through a call to updateReference so that the depth of the copy
// can be controlled by the user. See the documentation of the ICloneWithContext
// interface for more information.
protected SurfacePoint(SurfacePoint existingInstance, CopyContext context) {
super(existingInstance, context);
m_centralBody = context.updateReference(existingInstance.m_centralBody);
m_referencePoint = context.updateReference(existingInstance.m_referencePoint);
}
// This is called to make a copy of the object, which it does by calling the
// copy constructor above.
@Override
public Object clone(CopyContext context) {
return new SurfacePoint(this, context);
}
// This method is only called by the isSameDefinition method in the base class to
// determine if two points are equivalent. Derived classes MUST override this method and
// check all new fields introduced by the derived class for definitional equivalence. It
// is NOT necessary to check base class fields because the base class will already have
// done that.
@Override
protected final boolean checkForSameDefinition(Point other) {
SurfacePoint o = (other instanceof SurfacePoint) ? (SurfacePoint) other : null;
return o != null &&
areSameDefinition(m_centralBody, o.m_centralBody) &&
areSameDefinition(m_referencePoint, o.m_referencePoint);
}
// Called to determine a hash code for the current configuration of this object.
// Derived classes MUST override this method and compute a hash code that combines:
// a unique hash code seed, the base implementation result, and the
// hash codes of all new fields introduced by the derived class which are used
// in the checkForSameDefinition method.
@Override
protected int computeCurrentDefinitionHashCode() {
return HashCode.combine(SurfacePoint.class.hashCode(),
super.computeCurrentDefinitionHashCode(),
getDefinitionHashCode(m_centralBody),
getDefinitionHashCode(m_referencePoint));
}
// Called to enumerate all of the other objects on which this object depends. This
// allows clients to navigate the graph of objects related to a computation.
@Override
public void enumerateDependencies(DependencyEnumerator enumerator) {
super.enumerateDependencies(enumerator);
enumerator.enumerate(m_centralBody);
enumerator.enumerate(m_referencePoint);
}
// The central body on which to project the given ReferencePoint.
public final CentralBody getCentralBody() {
return m_centralBody;
}
// The central body on which to project the given ReferencePoint.
public final void setCentralBody(CentralBody value) {
m_centralBody = value;
}
// The reference point to be projected onto the surface of the central body.
public final Point getReferencePoint() {
return m_referencePoint;
}
// The reference point to be projected onto the surface of the central body.
public final void setReferencePoint(Point value) {
m_referencePoint = value;
}
// This method is responsible for returning an instance of the private
// Evaluator class. It should ensure that the properties are not null or
// in an invalid state and then use the evaluator group when it constructs
// and returns an instance of the Evaluator.
@Override
public PointEvaluator getEvaluator(EvaluatorGroup group) {
if (group == null) {
throw new ArgumentNullException("group");
}
// Ensure that the properties are not null.
if (getCentralBody() == null) {
throw new PropertyInvalidException("CentralBody", PropertyInvalidException.PropertyCannotBeNull);
}
if (getReferencePoint() == null) {
throw new PropertyInvalidException("ReferencePoint", PropertyInvalidException.PropertyCannotBeNull);
}
return group.createEvaluator(getEvaluatorCallback);
}
// This method will only be called if the evaluator does not
// yet exist in the group and needs to be created.
private PointEvaluator createEvaluator(EvaluatorGroup group) {
// In order to find the surface point, we're going to observe the reference point in the
// central body's fixed frame and use methods on Ellipsoid to find the surface point.
// Obtain an evaluator for the reference point observed in the central body's fixed frame.
// Notice that we create this evaluator in the same EvaluatorGroup.
PointEvaluator pointEvaluator = GeometryTransformer.observePoint(getReferencePoint(), getCentralBody().getFixedFrame(), group);
return new Evaluator(group, pointEvaluator, getCentralBody().getShape());
}
private final EvaluatorGroup.Callback0<PointEvaluator> getEvaluatorCallback = EvaluatorGroup.Callback0.of(this::createEvaluator);
private CentralBody m_centralBody;
private Point m_referencePoint;
// This is the definition of the Evaluator that is used to actually evaluate this Point.
// Because it is a private, nested class, it is not visible outside of the SurfacePosition
// class. This is ok, though, because once it is created users only interact with it via a
// reference to its base class: PointEvaluator.
private static final class Evaluator extends PointEvaluator {
// An evaluator should not store any data that the user will be able to change
// after creating the evaluator. This sometimes requires that data required by the
// evaluator be copied or frozen using the IFreezable interface.
public Evaluator(EvaluatorGroup group, PointEvaluator pointEvaluator, Ellipsoid shape) {
super(group);
m_pointEvaluator = pointEvaluator;
m_shape = shape;
}
// The Evaluator's copy constructor will be called from the clone method.
// Don't forget to call the base class implementation!
private Evaluator(Evaluator existingInstance, CopyContext context) {
super(existingInstance, context);
// Use the updateReference method on the CopyContext to perform any updates to the
// reference that are required by the context.
m_shape = context.updateReference(existingInstance.m_shape);
// For evaluators, just assign the reference directly - we'll call updateReference later.
m_pointEvaluator = existingInstance.m_pointEvaluator;
// Always call updateEvaluatorReferences at the end of the copy constructor.
// This is where references to evaluators will be updated.
updateEvaluatorReferences(context);
}
// This method is used by the EvaluatorGroup system to avoid redundant evaluations. The
// EvaluatorGroup may call it on your evaluator in order to replace your evaluator's
// reference to another evaluator with a reference to a version that caches its last
// result.
@Override
public void updateEvaluatorReferences(CopyContext context) {
m_pointEvaluator = context.updateReference(m_pointEvaluator);
}
// The clone method should call the copy constructor.
@Override
public Object clone(CopyContext context) {
return new Evaluator(this, context);
}
// This method determines if there is data available from this Evaluator at
// the specified date.
@Override
public boolean isAvailable(JulianDate date) {
// This evaluator is available whenever the nested evaluator is available.
return m_pointEvaluator.isAvailable(date);
}
// This method returns a collection of time intervals when data is
// available from this Evaluator.
@Override
public TimeIntervalCollection getAvailabilityIntervals(TimeIntervalCollection consideredIntervals) {
// This evaluator is available whenever the nested evaluator is available.
return m_pointEvaluator.getAvailabilityIntervals(consideredIntervals);
}
// This property determines if this Evaluator can safely be used from multiple threads
// simultaneously. If the evaluator stores data during the evaluate call, it is not thread
// safe. Otherwise, it generally is thread safe as long as any nested evaluators it uses
// are thread safe.
@Override
public boolean getIsThreadSafe() {
// This evaluator is thread safe as long as the nested evaluator is thread safe.
return m_pointEvaluator.getIsThreadSafe();
}
// This property determines if this Evaluator result changes depending on the time at which it is evaluated.
@Override
public boolean getIsTimeVarying() {
return m_pointEvaluator.getIsTimeVarying();
}
// This property expresses the ReferenceFrame(s) that this Point is defined in
// for various intervals.
@Override
public TimeIntervalCollection1<ReferenceFrame> getDefinedInIntervals() {
// This point is defined in the same reference frame(s) that the nested evaluator is defined in.
return m_pointEvaluator.getDefinedInIntervals();
}
// This is where we do the actual evaluation when only the position of the point (not its velocity,
// acceleration, etc.) is required.
@Override
public Cartesian evaluate(JulianDate date) {
Cartesian position = m_pointEvaluator.evaluate(date);
Cartesian surfacePosition = m_shape.surfaceProjection(position);
return surfacePosition;
}
// This is where we do the actual evaluation when the velocity and acceleration of the point
// are requested as well.
@Override
public Motion1<Cartesian> evaluate(JulianDate date, int order) {
Motion1<Cartesian> motion = m_pointEvaluator.evaluate(date, order);
Motion1<Cartesian> surfaceMotion = m_shape.surfaceProjection(motion, order);
return surfaceMotion;
}
// Override the dispose method to call the dispose() method on any nested
// evaluators or other disposable nested types.
@Override
protected void dispose(boolean disposing) {
if (disposing) {
m_pointEvaluator.dispose();
}
}
private final Ellipsoid m_shape;
private PointEvaluator m_pointEvaluator;
}
}
Modifier | Constructor and Description |
---|---|
protected |
Point()
Initializes a new instance.
|
protected |
Point(Point existingInstance,
CopyContext context)
Initializes a new instance as a copy of an existing instance.
|
Modifier and Type | Method and Description |
---|---|
protected boolean |
checkForSameDefinition(DefinitionalObject other)
Checks to determine if another instance has the same definition as this instance and
returns
true if it does. |
protected abstract boolean |
checkForSameDefinition(Point other)
Checks to determine if another instance has the same definition as this instance and
returns
true if it does. |
protected int |
computeCurrentDefinitionHashCode()
Computes a hash code based on the current properties of this object.
|
Vector |
createVectorAcceleration(ReferenceFrame frame)
Constructs a vector which represents the second derivative of this point's position.
|
Vector |
createVectorDerivative(ReferenceFrame frame,
int order)
Constructs a vector which represents the requested order of the derivative of this point's position.
|
Vector |
createVectorVelocity(ReferenceFrame frame)
Constructs a vector which represents the derivative of this point's position.
|
PointEvaluator |
getEvaluator()
Gets an evaluator that can be used to find the motion of this point in its parent reference frame
at a given date.
|
abstract PointEvaluator |
getEvaluator(EvaluatorGroup group)
Gets an evaluator that can be used to find the
Motion <Cartesian >
of this point at a given JulianDate . |
static Point |
getRoot()
Gets the root point, which is not defined in terms of any reference frame.
|
Scalar |
getScalarElement(CartesianElement element,
ReferenceFrame referenceFrame)
Returns a
Scalar representing the X, Y, Z, or Magnitude
of this point. |
Scalar |
getScalarElement(CartesianElement element,
ReferenceFrame referenceFrame,
int order)
Returns a
Scalar representing the X, Y, Z, or Magnitude, or any derivative of
those elements of this point. |
Object |
getService(Class<?> serviceType)
Gets the service object of the specified type.
|
areSameDefinition, areSameDefinition, areSameDefinition, areSameDefinition, areSameDefinition, clone, collectionItemsAreSameDefinition, collectionItemsAreSameDefinition, collectionItemsAreSameDefinition, dictionaryItemsAreSameDefinition, enumerateDependencies, freeze, freezeAggregatedObjects, getCollectionHashCode, getCollectionHashCode, getCollectionHashCode, getDefinitionHashCode, getDefinitionHashCode, getDefinitionHashCode, getDefinitionHashCode, getDefinitionHashCode, getDefinitionHashCode, getDictionaryHashCode, getIsFrozen, isSameDefinition, throwIfFrozen
protected Point()
protected Point(@Nonnull Point existingInstance, @Nonnull CopyContext context)
See ICloneWithContext.clone(CopyContext)
for more information about how to implement this constructor
in a derived class.
existingInstance
- The existing instance to copy.context
- A CopyContext
that controls the depth of the copy.ArgumentNullException
- Thrown when existingInstance
or context
is null
.protected final boolean checkForSameDefinition(DefinitionalObject other)
true
if it does. Derived classes MUST override this method and check
all new fields introduced by the derived class for definitional equivalence. It is NOT necessary
to check base class fields because the base class will already have done that. When overriding this method,
you should NOT call the base implementation because it will return false
for all derived-class instances.
Derived classes should check the type of other
to preserve the symmetric nature of IEquatableDefinition.isSameDefinition(java.lang.Object)
.checkForSameDefinition
in class DefinitionalObject
other
- The other instance to compare to this one.true
if the two objects are defined equivalently; otherwise false
.protected abstract boolean checkForSameDefinition(Point other)
true
if it does. Derived classes MUST override this method and check
all new fields introduced by the derived class for definitional equivalence. It is NOT necessary
to check base class fields because the base class will already have done that. When overriding this method,
you should NOT call the base implementation because it will return false
for all derived-class instances.
Derived classes should check the type of other
to preserve the symmetric nature of IEquatableDefinition.isSameDefinition(java.lang.Object)
.other
- The other instance to compare to this one.true
if the two objects are defined equivalently; otherwise false
.protected int computeCurrentDefinitionHashCode()
Point.checkForSameDefinition(agi.foundation.infrastructure.DefinitionalObject)
method.computeCurrentDefinitionHashCode
in class DefinitionalObject
@Nonnull public static Point getRoot()
@Nullable public Object getService(@Nonnull Class<?> serviceType)
getService
in interface IServiceProvider
serviceType
- An object that specifies the type of service object to get.null
if the service does not exist.ArgumentNullException
- Thrown when serviceType
is null
.@Nonnull public Vector createVectorVelocity(ReferenceFrame frame)
frame
- The ReferenceFrame
that the resultant Vector's
results will be in.@Nonnull public Vector createVectorAcceleration(ReferenceFrame frame)
frame
- The ReferenceFrame
that the resultant Vector's
results will be in.@Nonnull public Vector createVectorDerivative(@Nonnull ReferenceFrame frame, int order)
frame
- The ReferenceFrame
that the resultant Vector's
results will be in.order
- The order of derivative the constructed vector will represent.@Nonnull public final Scalar getScalarElement(@Nonnull CartesianElement element, ReferenceFrame referenceFrame, int order)
Scalar
representing the X, Y, Z, or Magnitude, or any derivative of
those elements of this point.element
- Specifies that the returned scalar represents the X, Y, Z or magnitude.referenceFrame
- The axes to view this point in.order
- The order of derivative of the point to represent with this objectScalar
representing the X, Y, Z, or Magnitude
of this point.@Nonnull public final Scalar getScalarElement(@Nonnull CartesianElement element, ReferenceFrame referenceFrame)
Scalar
representing the X, Y, Z, or Magnitude
of this point.element
- Specifies that the returned scalar represents the X, Y, Z or magnitude.referenceFrame
- The ReferenceFrame
to view this point in.Scalar
representing the X, Y, Z, or Magnitude
of this point.@Nonnull public final PointEvaluator getEvaluator()
GeometryTransformer
instead of calling this method directly.
See Point.getEvaluator(EvaluatorGroup)
for more details.@Nonnull public abstract PointEvaluator getEvaluator(@Nonnull EvaluatorGroup group)
Motion
<Cartesian
>
of this point at a given JulianDate
.
Adds the evaluator to the EvaluatorGroup
.group
- The group with which to associate the new evaluator. By grouping evaluators
that are often evaluated at the same Julian dates, common computations can be performed only once
for the entire group instead of multiple times for each evaluator.