Axes Class |
Namespace: AGI.Foundation.Geometry
The Axes type exposes the following members.
Name | Description | |
---|---|---|
Axes | Initializes a new instance. | |
Axes(Axes, CopyContext) | Initializes a new instance as a copy of an existing instance. |
Name | Description | |
---|---|---|
IsFrozen |
Gets a value indicating whether this object is frozen. A frozen object cannot be modified and an
ObjectFrozenException will be thrown if an attempt is made to do so.
(Inherited from DefinitionalObject.) | |
Root |
Gets the root axes, which is not defined in terms of any other axes.
|
Name | Description | |
---|---|---|
CheckForSameDefinition(Axes) |
Checks to determine if another instance has the same definition as this instance and
returns 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 for all derived-class instances.
Derived classes should check the type of other to preserve the symmetric nature of IsSameDefinition(Object).
| |
CheckForSameDefinition(DefinitionalObject) |
Checks to determine if another instance has the same definition as this instance and
returns 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 for all derived-class instances.
Derived classes should check the type of other to preserve the symmetric nature of IsSameDefinition(Object).
(Overrides DefinitionalObjectCheckForSameDefinition(DefinitionalObject).) | |
Clone |
Clones this object using the specified context.
(Inherited from DefinitionalObject.) | |
ComputeCurrentDefinitionHashCode |
Computes a hash code based on the current properties 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(DefinitionalObject) method.
(Overrides DefinitionalObjectComputeCurrentDefinitionHashCode.) | |
EnumerateDependencies |
Enumerates the dependencies of this object by calling
EnumerateT(T) for each object that this object directly depends upon.
Derived classes which contain additional dependencies MUST override this method, call the base
implementation, and enumerate dependencies introduced by the derived class.
(Inherited from DefinitionalObject.) | |
Equals | Determines whether the specified object is equal to the current object. (Inherited from Object.) | |
Finalize | Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.) | |
Freeze |
Freezes this object. Further attempts to modify it will result
in an ObjectFrozenException.
(Inherited from DefinitionalObject.) | |
FreezeAggregatedObjects |
Called by Freeze to also freeze any objects that are considered to be a part of this object.
Derived classes which contain additional aggregated objects MUST override this method, call the base
implementation, and freeze aggregated objects introduced by the derived class. The objects that need to be
frozen in this method are frequently created in this object's constructor and are not settable via
properties.
(Inherited from DefinitionalObject.) | |
GetDefinitionHashCode |
Gets a hash code representing the definition of this object.
(Inherited from DefinitionalObject.) | |
GetEvaluator |
Gets an evaluator that can be used to find the transformation from this axes' parent axes to
this axes at a given date. Consider using the methods of GeometryTransformer
instead of calling this method directly.
See GetEvaluator(EvaluatorGroup) for details.
| |
GetEvaluator(EvaluatorGroup) |
Gets an evaluator that can be used to find the transformation from this axes' parent axes to
this axes represented by a Motion<UnitQuaternion, Cartesian>
at a given JulianDate.
Consider using the methods of GeometryTransformer
instead of calling this method directly.
| |
GetHashCode | Serves as the default hash function. (Inherited from Object.) | |
GetService |
Gets the service object of the specified type.
| |
GetType | Gets the Type of the current instance. (Inherited from Object.) | |
GetVectorElement(CartesianElement) |
Creates a Vector representing the X, Y or Z of this axes. Note that the vector
returned will return trivial answers unless observed in some other axes. Use the
GeometryTransformer to properly observe the vector instead of getting an evaluator
directly.
| |
GetVectorElement(CartesianElement, Int32) |
Creates a Vector representing the X, Y or Z of this axes. Note that the vector
returned will return trivial answers unless observed in some other axes. Use the
GeometryTransformer to properly observe the vector instead of getting an evaluator
directly.
| |
IsSameDefinition |
Determines if this object has the same definition as another object.
(Inherited from DefinitionalObject.) | |
MemberwiseClone | Creates a shallow copy of the current Object. (Inherited from Object.) | |
ThrowIfFrozen |
Throws ObjectFrozenException if this object IsFrozen.
This method should be called from any method or property that modifies this object.
(Inherited from DefinitionalObject.) | |
ToString | Returns a string that represents the current object. (Inherited from Object.) |
This example shows how to create a new Axes class:
// Create a new type derived from Axes. This Axes represents the axes created by rotating // a reference axes a specified angle about a specified spin vector. The vector and the angle // are specified as a Vector and Scalar, respectively, so both can change with time. public class AngularOffsetAxes : Axes { public AngularOffsetAxes() { } public AngularOffsetAxes(Axes referenceAxes, Vector spinVector, Scalar rotationAngle) { m_referenceAxes = referenceAxes; m_spinVector = spinVector; m_rotationAngle = rotationAngle; } // 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 AngularOffsetAxes(AngularOffsetAxes existingInstance, CopyContext context) : base(existingInstance, context) { m_referenceAxes = context.UpdateReference(existingInstance.m_referenceAxes); m_rotationAngle = context.UpdateReference(existingInstance.m_rotationAngle); m_spinVector = context.UpdateReference(existingInstance.m_spinVector); } // This is called to make a copy of the object, which it does by calling the // copy constructor above. public override object Clone(CopyContext context) { return new AngularOffsetAxes(this, context); } // This method is only called by the IsSameDefinition method in the base class to // determine if two axes 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. protected sealed override bool CheckForSameDefinition(Axes other) { AngularOffsetAxes o = other as AngularOffsetAxes; return o != null && AreSameDefinition(m_referenceAxes, o.m_referenceAxes) && AreSameDefinition(m_spinVector, o.m_spinVector) && AreSameDefinition(m_rotationAngle, o.m_rotationAngle); } // 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. protected override int ComputeCurrentDefinitionHashCode() { return HashCode.Combine(typeof(AngularOffsetAxes).GetHashCode(), base.ComputeCurrentDefinitionHashCode(), GetDefinitionHashCode(m_referenceAxes), GetDefinitionHashCode(m_spinVector), GetDefinitionHashCode(m_rotationAngle)); } // 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. public override void EnumerateDependencies(DependencyEnumerator enumerator) { base.EnumerateDependencies(enumerator); enumerator.Enumerate(m_referenceAxes); enumerator.Enumerate(m_rotationAngle); enumerator.Enumerate(m_spinVector); } // The reference axes that this one is defined relative to. public Axes ReferenceAxes { get { return m_referenceAxes; } set { m_referenceAxes = value; } } // The vector defining the axis about which the ReferenceAxes is rotated to produce these axes. public Vector SpinVector { get { return m_spinVector; } set { m_spinVector = value; } } // The angle to rotate the ReferenceAxes about the SpinVector to produce this axes. public Scalar RotationAngle { get { return m_rotationAngle; } set { m_rotationAngle = 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. public override AxesEvaluator GetEvaluator(EvaluatorGroup group) { if (group == null) throw new ArgumentNullException("group"); // Ensure that the properties are not null. if (ReferenceAxes == null) throw new PropertyInvalidException("ReferenceAxes", PropertyInvalidException.PropertyCannotBeNull); if (SpinVector == null) throw new PropertyInvalidException("SpinVector", PropertyInvalidException.PropertyCannotBeNull); if (RotationAngle == null) throw new PropertyInvalidException("RotationAngle", PropertyInvalidException.PropertyCannotBeNull); return group.CreateEvaluator<AxesEvaluator>(CreateEvaluator); } // This method, which is passed to the evaluator group in the method above as a delegate, // will only be called by the delegate if the evaluator does not yet exist in the group // and needs to be created. private AxesEvaluator CreateEvaluator(EvaluatorGroup group) { // The reference axes is the axes that this axes is defined in. Axes definedIn = ReferenceAxes; // In order to compute the orientation of this axes relative to its parent, we must observe the spin vector // in the reference axes and compute the value of the angle scalar. // Obtain an evaluator for the spin vector in the reference axes. // Notice that we create this evaluator in the same EvaluatorGroup. var spinVectorEvaluator = GeometryTransformer.ObserveVector(SpinVector, ReferenceAxes, group); // Obtain the evaluator for the angle - again in the same EvaluatorGroup. var angleEvaluator = RotationAngle.GetEvaluator(group); return new Evaluator(group, definedIn, spinVectorEvaluator, angleEvaluator); } private Axes m_referenceAxes; private Vector m_spinVector; private Scalar m_rotationAngle; // This is the definition of the Evaluator that is used to actually evaluate this Axes. // Because it is a private, nested class, it is not visible outside of the // AngularOffsetAxes class. This is ok, though, because once it is created users only // interact with it via a reference to its base class: AxesEvaluator. private sealed class Evaluator : AxesEvaluator { // 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, Axes definedIn, VectorEvaluator spinVectorEvaluator, ScalarEvaluator angleEvaluator) : base(group) { m_definedIn = definedIn; m_spinVectorEvaluator = spinVectorEvaluator; m_angleEvaluator = angleEvaluator; } // 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) : base(existingInstance, context) { // Use the UpdateReference method on the CopyContext to perform any updates to the // reference that are required by the context. m_definedIn = context.UpdateReference(existingInstance.m_definedIn); // For evaluators, just assign the reference directly - we'll call UpdateReference later. m_spinVectorEvaluator = existingInstance.m_spinVectorEvaluator; m_angleEvaluator = existingInstance.m_angleEvaluator; // 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. public override void UpdateEvaluatorReferences(CopyContext context) { m_spinVectorEvaluator = context.UpdateReference(m_spinVectorEvaluator); m_angleEvaluator = context.UpdateReference(m_angleEvaluator); } // The Clone method should call the copy constructor. public override object Clone(CopyContext context) { return new Evaluator(this, context); } // This method determines if there is data available from this Evaluator at // the specified date. public override bool IsAvailable(JulianDate date) { // This evaluator is available whenever the two nested evaluators are available. return EvaluatorHelper.AllEvaluatorsAreAvailable(date, m_spinVectorEvaluator, m_angleEvaluator); } // This method returns a collection of time intervals when data is // available from this Evaluator. public override TimeIntervalCollection GetAvailabilityIntervals(TimeIntervalCollection consideredIntervals) { // This evaluator is available whenever the two nested evaluators are available. return EvaluatorHelper.GetAvailabilityIntervals(consideredIntervals, m_spinVectorEvaluator, m_angleEvaluator); } // 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. public override bool IsThreadSafe { get { // This evaluator is thread safe as long as the nested evaluators are thread safe. return EvaluatorHelper.AllEvaluatorsAreThreadSafe(m_spinVectorEvaluator, m_angleEvaluator); } } // This property determines if this Evaluator result changes depending on the time at // which it is evaluated. public override bool IsTimeVarying { get { // This evaluator is time-varying if any of the nested evaluators are time-varying. return EvaluatorHelper.AnyEvaluatorIsTimeVarying(m_spinVectorEvaluator, m_angleEvaluator); } } // This property expresses the Axes that this Axes is defined in for various intervals. public override TimeIntervalCollection<Axes> DefinedInIntervals { get { // This axes is always defined in the reference axes. return CreateConstantDefinedIn(m_definedIn); } } // This is where we do the actual evaluation when only the orientation of the axes (not // its rotational velocity, rotational acceleration, etc.) is required. public override UnitQuaternion Evaluate(JulianDate date) { Cartesian spinVector = m_spinVectorEvaluator.Evaluate(date); UnitCartesian unitSpinVector = new UnitCartesian(spinVector); double angle = m_angleEvaluator.Evaluate(date); AngleAxisRotation rotation = new AngleAxisRotation(angle, unitSpinVector); return new UnitQuaternion(rotation); } // This is where we do the actual evaluation when the rotational velocity and rotational // acceleration of the axes are requested as well. public override Motion<UnitQuaternion, Cartesian> Evaluate(JulianDate date, int order) { // Ideally the implementation should support computing higher derivatives here. However, // sometimes it is not possible or difficult to produce the derivative, in which case just // call the Evaluate overload that computes the value only. Normally, the derivative would // represent the rotational velocity (acceleration, etc) vector of the rotating axes with // respect to the frame in which the axes are defined. In this case, the axes are defined // in the ReferenceAxes set by the user at construction. return new Motion<UnitQuaternion, Cartesian>(Evaluate(date)); } // Override the Dispose method to call the Dispose() method on any nested // evaluators or other disposable nested types. protected override void Dispose(bool disposing) { if (disposing) { m_angleEvaluator.Dispose(); m_spinVectorEvaluator.Dispose(); } } private readonly Axes m_definedIn; private ScalarEvaluator m_angleEvaluator; private VectorEvaluator m_spinVectorEvaluator; } }