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.      * Build a transform by combining two existing ones.
  121.      * <p>
  122.      * Note that the dates of the two existing transformed are <em>ignored</em>,
  123.      * and the combined transform date is set to the date supplied in this
  124.      * constructor without any attempt to shift the raw transforms. This is a
  125.      * design choice allowing user full control of the combination.
  126.      * </p>
  127.      *
  128.      * @param date   date of the transform
  129.      * @param first  first transform applied
  130.      * @param second second transform applied
  131.      * @return the newly created static transform that has the same effect as
  132.      * applying {@code first}, then {@code second}.
  133.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  134.      */
  135.     static StaticTransform compose(final AbsoluteDate date,
  136.                                    final StaticTransform first,
  137.                                    final StaticTransform second) {
  138.         return of(date,
  139.                 compositeTranslation(first, second),
  140.                 compositeRotation(first, second));
  141.     }

  142.     /**
  143.      * Compute a composite translation.
  144.      *
  145.      * @param first  first applied transform
  146.      * @param second second applied transform
  147.      * @return translation part of the composite transform
  148.      */
  149.     static Vector3D compositeTranslation(
  150.             final StaticTransform first,
  151.             final StaticTransform second) {
  152.         final Vector3D p1 = first.getTranslation();
  153.         final Rotation r1 = first.getRotation();
  154.         final Vector3D p2 = second.getTranslation();

  155.         return p1.add(r1.applyInverseTo(p2));
  156.     }

  157.     /**
  158.      * Compute a composite rotation.
  159.      *
  160.      * @param first  first applied transform
  161.      * @param second second applied transform
  162.      * @return rotation part of the composite transform
  163.      */
  164.     static Rotation compositeRotation(final StaticTransform first,
  165.                                       final StaticTransform second) {
  166.         final Rotation r1 = first.getRotation();
  167.         final Rotation r2 = second.getRotation();
  168.         return r1.compose(r2, RotationConvention.FRAME_TRANSFORM);

  169.     }

  170.     /**
  171.      * Create a new static transform from a rotation and zero translation.
  172.      *
  173.      * @param date     of translation.
  174.      * @param rotation to apply after the translation. That is after translating
  175.      *                 applying this rotation produces positions expressed in
  176.      *                 the new frame.
  177.      * @return the newly created static transform.
  178.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  179.      */
  180.     static StaticTransform of(final AbsoluteDate date,
  181.                               final Rotation rotation) {
  182.         return of(date, Vector3D.ZERO, rotation);
  183.     }

  184.     /**
  185.      * Create a new static transform from a translation and rotation.
  186.      *
  187.      * @param date        of translation.
  188.      * @param translation to apply, expressed in the old frame. That is, the
  189.      *                    opposite of the coordinates of the new origin in the
  190.      *                    old frame.
  191.      * @return the newly created static transform.
  192.      * @see #of(AbsoluteDate, Vector3D, Rotation)
  193.      */
  194.     static StaticTransform of(final AbsoluteDate date,
  195.                               final Vector3D translation) {
  196.         return of(date, translation, Rotation.IDENTITY);
  197.     }

  198.     /**
  199.      * Create a new static transform from a translation and rotation.
  200.      *
  201.      * @param date        of translation.
  202.      * @param translation to apply, expressed in the old frame. That is, the
  203.      *                    opposite of the coordinates of the new origin in the
  204.      *                    old frame.
  205.      * @param rotation    to apply after the translation. That is after
  206.      *                    translating applying this rotation produces positions
  207.      *                    expressed in the new frame.
  208.      * @return the newly created static transform.
  209.      * @see #compose(AbsoluteDate, StaticTransform, StaticTransform)
  210.      * @see #of(AbsoluteDate, Rotation)
  211.      * @see #of(AbsoluteDate, Vector3D)
  212.      */
  213.     static StaticTransform of(final AbsoluteDate date,
  214.                               final Vector3D translation,
  215.                               final Rotation rotation) {
  216.         return new StaticTransform() {

  217.             @Override
  218.             public StaticTransform getInverse() {
  219.                 final Rotation r = getRotation();
  220.                 final Vector3D rp = r.applyTo(getTranslation());
  221.                 final Vector3D pInv = rp.negate();
  222.                 return StaticTransform.of(date, pInv, rotation.revert());
  223.             }

  224.             @Override
  225.             public AbsoluteDate getDate() {
  226.                 return date;
  227.             }

  228.             @Override
  229.             public Vector3D getTranslation() {
  230.                 return translation;
  231.             }

  232.             @Override
  233.             public Rotation getRotation() {
  234.                 return rotation;
  235.             }

  236.         };
  237.     }

  238. }