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.      * It overrides most methods for speed.
  39.      *
  40.      * @return identity transform.
  41.      */
  42.     static StaticTransform getIdentity() {
  43.         return new StaticTransform() {
  44.             @Override
  45.             public Vector3D getTranslation() {
  46.                 return Vector3D.ZERO;
  47.             }

  48.             @Override
  49.             public Rotation getRotation() {
  50.                 return Rotation.IDENTITY;
  51.             }

  52.             @Override
  53.             public StaticTransform getStaticInverse() {
  54.                 return getInverse();
  55.             }

  56.             @Override
  57.             public StaticTransform getInverse() {
  58.                 return this;
  59.             }

  60.             @Override
  61.             public AbsoluteDate getDate() {
  62.                 return AbsoluteDate.ARBITRARY_EPOCH;
  63.             }

  64.             @Override
  65.             public Vector3D transformPosition(final Vector3D position) {
  66.                 return transformVector(position);
  67.             }

  68.             @Override
  69.             public Vector3D transformVector(final Vector3D vector) {
  70.                 return new Vector3D(vector.getX(), vector.getY(), vector.getZ());
  71.             }

  72.             @Override
  73.             public <T extends CalculusFieldElement<T>> FieldVector3D<T> transformVector(final FieldVector3D<T> vector) {
  74.                 return new FieldVector3D<>(vector.getX(), vector.getY(), vector.getZ());
  75.             }

  76.             @Override
  77.             public <T extends CalculusFieldElement<T>> FieldVector3D<T> transformPosition(final FieldVector3D<T> position) {
  78.                 return transformVector(position);
  79.             }
  80.         };
  81.     }

  82.     /**
  83.      * Transform a position vector (including translation effects).
  84.      *
  85.      * @param position vector to transform
  86.      * @return transformed position
  87.      */
  88.     default Vector3D transformPosition(final Vector3D position) {
  89.         return getRotation().applyTo(getTranslation().add(position));
  90.     }

  91.     /**
  92.      * Transform a position vector (including translation effects).
  93.      *
  94.      * @param position vector to transform
  95.      * @param <T>      the type of the field elements
  96.      * @return transformed position
  97.      */
  98.     default  <T extends CalculusFieldElement<T>> FieldVector3D<T> transformPosition(
  99.             final FieldVector3D<T> position) {
  100.         return FieldRotation.applyTo(getRotation(), position.add(getTranslation()));
  101.     }

  102.     /**
  103.      * Transform a vector (ignoring translation effects).
  104.      *
  105.      * @param vector vector to transform
  106.      * @return transformed vector
  107.      */
  108.     default  Vector3D transformVector(final Vector3D vector) {
  109.         return getRotation().applyTo(vector);
  110.     }

  111.     /**
  112.      * Transform a vector (ignoring translation effects).
  113.      *
  114.      * @param vector vector to transform
  115.      * @param <T>    the type of the field elements
  116.      * @return transformed vector
  117.      */
  118.     default <T extends CalculusFieldElement<T>> FieldVector3D<T> transformVector(
  119.             final FieldVector3D<T> vector) {
  120.         return FieldRotation.applyTo(getRotation(), vector);
  121.     }

  122.     /**
  123.      * Transform a line.
  124.      *
  125.      * @param line to transform
  126.      * @return transformed line
  127.      */
  128.     default Line transformLine(final Line line) {
  129.         final Vector3D transformedP0 = transformPosition(line.getOrigin());
  130.         final Vector3D transformedD  = transformVector(line.getDirection());
  131.         return Line.fromDirection(transformedP0, transformedD, line.getTolerance());
  132.     }

  133.     /**
  134.      * Get the underlying elementary translation.
  135.      * <p>A transform can be uniquely represented as an elementary
  136.      * translation followed by an elementary rotation. This method returns this
  137.      * unique elementary translation.</p>
  138.      *
  139.      * @return underlying elementary translation
  140.      */
  141.     Vector3D getTranslation();

  142.     /**
  143.      * Get the underlying elementary rotation.
  144.      * <p>A transform can be uniquely represented as an elementary
  145.      * translation followed by an elementary rotation. This method returns this
  146.      * unique elementary rotation.</p>
  147.      *
  148.      * @return underlying elementary rotation
  149.      */
  150.     Rotation getRotation();

  151.     /**
  152.      * Get the inverse transform of the instance.
  153.      *
  154.      * @return inverse transform of the instance
  155.      */
  156.     StaticTransform getInverse();

  157.     /**
  158.      * Get the inverse transform of the instance in static form (without rates).
  159.      * This enables to create a purely static inverse, as inheritors such as {@link Transform} may
  160.      * have a relatively computationally-heavy #getInverse() method.
  161.      *
  162.      * @return inverse static transform of the instance
  163.      * @since 12.1
  164.      */
  165.     default StaticTransform getStaticInverse() {
  166.         final Rotation rotation = getRotation();
  167.         return StaticTransform.of(getDate(), rotation.applyTo(getTranslation()).negate(), rotation.revert());
  168.     }

  169.     /**
  170.      * Build a transform by combining two existing ones.
  171.      * <p>
  172.      * Note that the dates of the two existing transformed are <em>ignored</em>,
  173.      * and the combined transform date is set to the date supplied in this
  174.      * constructor without any attempt to shift the raw transforms. This is a
  175.      * design choice allowing user full control of the combination.
  176.      * </p>
  177.      *
  178.      * @param date   date of the transform
  179.      * @param first  first transform applied
  180.      * @param second second transform applied
  181.      * @return the newly created static transform that has the same effect as
  182.      * applying {@code first}, then {@code second}.
  183.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  184.      */
  185.     static StaticTransform compose(final AbsoluteDate date,
  186.                                    final StaticTransform first,
  187.                                    final StaticTransform second) {
  188.         return of(date,
  189.                 compositeTranslation(first, second),
  190.                 compositeRotation(first, second));
  191.     }

  192.     /**
  193.      * Compute a composite translation.
  194.      *
  195.      * @param first  first applied transform
  196.      * @param second second applied transform
  197.      * @return translation part of the composite transform
  198.      */
  199.     static Vector3D compositeTranslation(
  200.             final StaticTransform first,
  201.             final StaticTransform second) {
  202.         final Vector3D p1 = first.getTranslation();
  203.         final Rotation r1 = first.getRotation();
  204.         final Vector3D p2 = second.getTranslation();

  205.         return p1.add(r1.applyInverseTo(p2));
  206.     }

  207.     /**
  208.      * Compute a composite rotation.
  209.      *
  210.      * @param first  first applied transform
  211.      * @param second second applied transform
  212.      * @return rotation part of the composite transform
  213.      */
  214.     static Rotation compositeRotation(final StaticTransform first,
  215.                                       final StaticTransform second) {
  216.         final Rotation r1 = first.getRotation();
  217.         final Rotation r2 = second.getRotation();
  218.         return r1.compose(r2, RotationConvention.FRAME_TRANSFORM);

  219.     }

  220.     /**
  221.      * Create a new static transform from a rotation and zero translation.
  222.      *
  223.      * @param date     of translation.
  224.      * @param rotation to apply after the translation. That is after translating
  225.      *                 applying this rotation produces positions expressed in
  226.      *                 the new frame.
  227.      * @return the newly created static transform.
  228.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  229.      */
  230.     static StaticTransform of(final AbsoluteDate date,
  231.                               final Rotation rotation) {
  232.         return of(date, Vector3D.ZERO, rotation);
  233.     }

  234.     /**
  235.      * Create a new static transform from a translation and rotation.
  236.      *
  237.      * @param date        of translation.
  238.      * @param translation to apply, expressed in the old frame. That is, the
  239.      *                    opposite of the coordinates of the new origin in the
  240.      *                    old frame.
  241.      * @return the newly created static transform.
  242.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  243.      */
  244.     static StaticTransform of(final AbsoluteDate date,
  245.                               final Vector3D translation) {
  246.         return of(date, translation, Rotation.IDENTITY);
  247.     }

  248.     /**
  249.      * Create a new static transform from a translation and rotation.
  250.      *
  251.      * @param date        of translation.
  252.      * @param translation to apply, expressed in the old frame. That is, the
  253.      *                    opposite of the coordinates of the new origin in the
  254.      *                    old frame.
  255.      * @param rotation    to apply after the translation. That is after
  256.      *                    translating applying this rotation produces positions
  257.      *                    expressed in the new frame.
  258.      * @return the newly created static transform.
  259.      * @see #compose(AbsoluteDate, StaticTransform, StaticTransform)
  260.      * @see #of(AbsoluteDate, Rotation)
  261.      * @see #of(AbsoluteDate, Vector3D)
  262.      */
  263.     static StaticTransform of(final AbsoluteDate date,
  264.                               final Vector3D translation,
  265.                               final Rotation rotation) {
  266.         return new StaticTransform() {

  267.             @Override
  268.             public StaticTransform getInverse() {
  269.                 final Rotation r = getRotation();
  270.                 final Vector3D rp = r.applyTo(getTranslation());
  271.                 final Vector3D pInv = rp.negate();
  272.                 return StaticTransform.of(date, pInv, rotation.revert());
  273.             }

  274.             @Override
  275.             public AbsoluteDate getDate() {
  276.                 return date;
  277.             }

  278.             @Override
  279.             public Vector3D getTranslation() {
  280.                 return translation;
  281.             }

  282.             @Override
  283.             public Rotation getRotation() {
  284.                 return rotation;
  285.             }

  286.         };
  287.     }

  288. }