StaticTransform.java

  1. /* Contributed in the public domain.
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.frames;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  20. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  21. import org.hipparchus.geometry.euclidean.threed.Line;
  22. import org.hipparchus.geometry.euclidean.threed.Rotation;
  23. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  24. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  25. import org.orekit.time.AbsoluteDate;
  26. import org.orekit.time.TimeStamped;

  27. /**
  28.  * A transform that only includes translation and rotation. It is static in the
  29.  * sense that no rates thereof are included.
  30.  *
  31.  * @author Evan Ward
  32.  * @see Transform
  33.  * @since 11.2
  34.  */
  35. public interface StaticTransform extends TimeStamped {

  36.     /**
  37.      * Get the identity static transform.
  38.      *
  39.      * @return identity transform.
  40.      */
  41.     static StaticTransform getIdentity() {
  42.         return Transform.IDENTITY;
  43.     }

  44.     /**
  45.      * Transform a position vector (including translation effects).
  46.      *
  47.      * @param position vector to transform
  48.      * @return transformed position
  49.      */
  50.     default Vector3D transformPosition(final Vector3D position) {
  51.         return getRotation().applyTo(getTranslation().add(position));
  52.     }

  53.     /**
  54.      * Transform a position vector (including translation effects).
  55.      *
  56.      * @param position vector to transform
  57.      * @param <T>      the type of the field elements
  58.      * @return transformed position
  59.      */
  60.     default  <T extends CalculusFieldElement<T>> FieldVector3D<T> transformPosition(
  61.             final FieldVector3D<T> position) {
  62.         return FieldRotation.applyTo(getRotation(), position.add(getTranslation()));
  63.     }

  64.     /**
  65.      * Transform a vector (ignoring translation effects).
  66.      *
  67.      * @param vector vector to transform
  68.      * @return transformed vector
  69.      */
  70.     default  Vector3D transformVector(final Vector3D vector) {
  71.         return getRotation().applyTo(vector);
  72.     }

  73.     /**
  74.      * Transform a vector (ignoring translation effects).
  75.      *
  76.      * @param vector vector to transform
  77.      * @param <T>    the type of the field elements
  78.      * @return transformed vector
  79.      */
  80.     default <T extends CalculusFieldElement<T>> FieldVector3D<T> transformVector(
  81.             final FieldVector3D<T> vector) {
  82.         return FieldRotation.applyTo(getRotation(), vector);
  83.     }

  84.     /**
  85.      * Transform a line.
  86.      *
  87.      * @param line to transform
  88.      * @return transformed line
  89.      */
  90.     default Line transformLine(final Line line) {
  91.         final Vector3D transformedP0 = transformPosition(line.getOrigin());
  92.         final Vector3D transformedD  = transformVector(line.getDirection());
  93.         return Line.fromDirection(transformedP0, transformedD, line.getTolerance());
  94.     }

  95.     /**
  96.      * Get the underlying elementary translation.
  97.      * <p>A transform can be uniquely represented as an elementary
  98.      * translation followed by an elementary rotation. This method returns this
  99.      * unique elementary translation.</p>
  100.      *
  101.      * @return underlying elementary translation
  102.      */
  103.     Vector3D getTranslation();

  104.     /**
  105.      * Get the underlying elementary rotation.
  106.      * <p>A transform can be uniquely represented as an elementary
  107.      * translation followed by an elementary rotation. This method returns this
  108.      * unique elementary rotation.</p>
  109.      *
  110.      * @return underlying elementary rotation
  111.      */
  112.     Rotation getRotation();

  113.     /**
  114.      * Get the inverse transform of the instance.
  115.      *
  116.      * @return inverse transform of the instance
  117.      */
  118.     StaticTransform getInverse();

  119.     /**
  120.      * Get the inverse transform of the instance in static form (without rates).
  121.      * This enables to create a purely static inverse, as inheritors such as {@link Transform} may
  122.      * have a relatively computationally-heavy #getInverse() method.
  123.      *
  124.      * @return inverse static transform of the instance
  125.      * @since 12.1
  126.      */
  127.     default StaticTransform getStaticInverse() {
  128.         final Rotation rotation = getRotation();
  129.         return StaticTransform.of(getDate(), rotation.applyTo(getTranslation()).negate(), rotation.revert());
  130.     }

  131.     /**
  132.      * Build a transform by combining two existing ones.
  133.      * <p>
  134.      * Note that the dates of the two existing transformed are <em>ignored</em>,
  135.      * and the combined transform date is set to the date supplied in this
  136.      * constructor without any attempt to shift the raw transforms. This is a
  137.      * design choice allowing user full control of the combination.
  138.      * </p>
  139.      *
  140.      * @param date   date of the transform
  141.      * @param first  first transform applied
  142.      * @param second second transform applied
  143.      * @return the newly created static transform that has the same effect as
  144.      * applying {@code first}, then {@code second}.
  145.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  146.      */
  147.     static StaticTransform compose(final AbsoluteDate date,
  148.                                    final StaticTransform first,
  149.                                    final StaticTransform second) {
  150.         return of(date,
  151.                 compositeTranslation(first, second),
  152.                 compositeRotation(first, second));
  153.     }

  154.     /**
  155.      * Compute a composite translation.
  156.      *
  157.      * @param first  first applied transform
  158.      * @param second second applied transform
  159.      * @return translation part of the composite transform
  160.      */
  161.     static Vector3D compositeTranslation(
  162.             final StaticTransform first,
  163.             final StaticTransform second) {
  164.         final Vector3D p1 = first.getTranslation();
  165.         final Rotation r1 = first.getRotation();
  166.         final Vector3D p2 = second.getTranslation();

  167.         return p1.add(r1.applyInverseTo(p2));
  168.     }

  169.     /**
  170.      * Compute a composite rotation.
  171.      *
  172.      * @param first  first applied transform
  173.      * @param second second applied transform
  174.      * @return rotation part of the composite transform
  175.      */
  176.     static Rotation compositeRotation(final StaticTransform first,
  177.                                       final StaticTransform second) {
  178.         final Rotation r1 = first.getRotation();
  179.         final Rotation r2 = second.getRotation();
  180.         return r1.compose(r2, RotationConvention.FRAME_TRANSFORM);

  181.     }

  182.     /**
  183.      * Create a new static transform from a rotation and zero translation.
  184.      *
  185.      * @param date     of translation.
  186.      * @param rotation to apply after the translation. That is after translating
  187.      *                 applying this rotation produces positions expressed in
  188.      *                 the new frame.
  189.      * @return the newly created static transform.
  190.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  191.      */
  192.     static StaticTransform of(final AbsoluteDate date,
  193.                               final Rotation rotation) {
  194.         return of(date, Vector3D.ZERO, rotation);
  195.     }

  196.     /**
  197.      * Create a new static transform from a translation and rotation.
  198.      *
  199.      * @param date        of translation.
  200.      * @param translation to apply, expressed in the old frame. That is, the
  201.      *                    opposite of the coordinates of the new origin in the
  202.      *                    old frame.
  203.      * @return the newly created static transform.
  204.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  205.      */
  206.     static StaticTransform of(final AbsoluteDate date,
  207.                               final Vector3D translation) {
  208.         return of(date, translation, Rotation.IDENTITY);
  209.     }

  210.     /**
  211.      * Create a new static transform from a translation and rotation.
  212.      *
  213.      * @param date        of translation.
  214.      * @param translation to apply, expressed in the old frame. That is, the
  215.      *                    opposite of the coordinates of the new origin in the
  216.      *                    old frame.
  217.      * @param rotation    to apply after the translation. That is after
  218.      *                    translating applying this rotation produces positions
  219.      *                    expressed in the new frame.
  220.      * @return the newly created static transform.
  221.      * @see #compose(AbsoluteDate, StaticTransform, StaticTransform)
  222.      * @see #of(AbsoluteDate, Rotation)
  223.      * @see #of(AbsoluteDate, Vector3D)
  224.      */
  225.     static StaticTransform of(final AbsoluteDate date,
  226.                               final Vector3D translation,
  227.                               final Rotation rotation) {
  228.         return new StaticTransform() {

  229.             @Override
  230.             public StaticTransform getInverse() {
  231.                 final Rotation r = getRotation();
  232.                 final Vector3D rp = r.applyTo(getTranslation());
  233.                 final Vector3D pInv = rp.negate();
  234.                 return StaticTransform.of(date, pInv, rotation.revert());
  235.             }

  236.             @Override
  237.             public AbsoluteDate getDate() {
  238.                 return date;
  239.             }

  240.             @Override
  241.             public Vector3D getTranslation() {
  242.                 return translation;
  243.             }

  244.             @Override
  245.             public Rotation getRotation() {
  246.                 return rotation;
  247.             }

  248.         };
  249.     }

  250. }