FieldStaticTransform.java

  1. /* Copyright 2002-2024 CS GROUP
  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.Field;
  20. import org.hipparchus.geometry.euclidean.threed.FieldLine;
  21. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.hipparchus.geometry.euclidean.threed.Line;
  24. import org.hipparchus.geometry.euclidean.threed.RotationConvention;
  25. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  26. import org.orekit.time.AbsoluteDate;
  27. import org.orekit.time.FieldAbsoluteDate;
  28. import org.orekit.time.TimeStamped;

  29. /**
  30.  * A transform that only includes translation and rotation. It is static in the
  31.  * sense that no rates thereof are included.
  32.  *
  33.  * @param <T> the type of the field elements
  34.  * @author Bryan Cazabonne
  35.  * @see FieldTransform
  36.  * @since 12.0
  37.  */
  38. public interface FieldStaticTransform<T extends CalculusFieldElement<T>> extends TimeStamped {

  39.     /**
  40.      * Get the identity static transform.
  41.      *
  42.      * @param <T> type of the elements
  43.      * @param field field used by default
  44.      * @return identity transform.
  45.      */
  46.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getIdentity(final Field<T> field) {
  47.         return FieldTransform.getIdentity(field);
  48.     }

  49.     /**
  50.      * Transform a position vector (including translation effects).
  51.      *
  52.      * @param position vector to transform
  53.      * @return transformed position
  54.      */
  55.     default FieldVector3D<T> transformPosition(final Vector3D position) {
  56.         return getRotation().applyTo(getTranslation().add(position));
  57.     }

  58.     /**
  59.      * Transform a position vector (including translation effects).
  60.      *
  61.      * @param position vector to transform
  62.      * @return transformed position
  63.      */
  64.     default FieldVector3D<T> transformPosition(final FieldVector3D<T> position) {
  65.         return getRotation().applyTo(position.add(getTranslation()));
  66.     }

  67.     /**
  68.      * Transform a vector (ignoring translation effects).
  69.      *
  70.      * @param vector vector to transform
  71.      * @return transformed vector
  72.      */
  73.     default FieldVector3D<T> transformVector(final Vector3D vector) {
  74.         return getRotation().applyTo(vector);
  75.     }

  76.     /**
  77.      * Transform a vector (ignoring translation effects).
  78.      *
  79.      * @param vector vector to transform
  80.      * @return transformed vector
  81.      */
  82.     default FieldVector3D<T> transformVector(final FieldVector3D<T> vector) {
  83.         return getRotation().applyTo(vector);
  84.     }

  85.     /**
  86.      * Transform a line.
  87.      *
  88.      * @param line to transform
  89.      * @return transformed line
  90.      */
  91.     default FieldLine<T> transformLine(final Line line) {
  92.         final FieldVector3D<T> transformedP0 = transformPosition(line.getOrigin());
  93.         final FieldVector3D<T> transformedP1 = transformPosition(line.pointAt(1.0e6));
  94.         return new FieldLine<>(transformedP0, transformedP1, line.getTolerance());
  95.     }

  96.     /**
  97.      * Transform a line.
  98.      *
  99.      * @param line to transform
  100.      * @return transformed line
  101.      */
  102.     default FieldLine<T> transformLine(final FieldLine<T> line) {
  103.         final FieldVector3D<T> transformedP0 = transformPosition(line.getOrigin());
  104.         final FieldVector3D<T> transformedP1 = transformPosition(line.pointAt(1.0e6));
  105.         return new FieldLine<>(transformedP0, transformedP1, line.getTolerance());
  106.     }

  107.     /** Get the Field date.
  108.      * This default implementation is there so that no API is broken by a minor release.
  109.      * It is overloaded by native inheritors and shall be removed in the next major release.
  110.      * @return Field date attached to the object
  111.      * @since 12.1
  112.      */
  113.     default FieldAbsoluteDate<T> getFieldDate() {
  114.         return new FieldAbsoluteDate<>(getTranslation().getX().getField(), getDate());
  115.     }

  116.     /**
  117.      * Get the underlying elementary translation.
  118.      * <p>A transform can be uniquely represented as an elementary
  119.      * translation followed by an elementary rotation. This method returns this
  120.      * unique elementary translation.</p>
  121.      *
  122.      * @return underlying elementary translation
  123.      */
  124.     FieldVector3D<T> getTranslation();

  125.     /**
  126.      * Get the underlying elementary rotation.
  127.      * <p>A transform can be uniquely represented as an elementary
  128.      * translation followed by an elementary rotation. This method returns this
  129.      * unique elementary rotation.</p>
  130.      *
  131.      * @return underlying elementary rotation
  132.      */
  133.     FieldRotation<T> getRotation();

  134.     /**
  135.      * Get the inverse transform of the instance.
  136.      *
  137.      * @return inverse transform of the instance
  138.      */
  139.     FieldStaticTransform<T> getInverse();

  140.     /**
  141.      * Get the inverse transform of the instance in static form (without rates).
  142.      * This enables to create a purely static inverse, as inheritors such as {@link FieldTransform} may
  143.      * have a relatively computationally-heavy #getInverse() method.
  144.      *
  145.      * @return inverse static transform of the instance
  146.      * @since 12.1
  147.      */
  148.     default FieldStaticTransform<T> getStaticInverse() {
  149.         final FieldVector3D<T> negatedTranslation = getTranslation().negate();
  150.         final FieldRotation<T> rotation = getRotation();
  151.         return FieldStaticTransform.of(getFieldDate(), rotation.applyTo(negatedTranslation), rotation.revert());
  152.     }

  153.     /**
  154.      * Build a transform by combining two existing ones.
  155.      * <p>
  156.      * Note that the dates of the two existing transformed are <em>ignored</em>,
  157.      * and the combined transform date is set to the date supplied in this
  158.      * constructor without any attempt to shift the raw transforms. This is a
  159.      * design choice allowing user full control of the combination.
  160.      * </p>
  161.      *
  162.      * @param <T>    type of the elements
  163.      * @param date   date of the transform
  164.      * @param first  first transform applied
  165.      * @param second second transform applied
  166.      * @return the newly created static transform that has the same effect as
  167.      * applying {@code first}, then {@code second}.
  168.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  169.      */
  170.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> compose(final FieldAbsoluteDate<T> date,
  171.                                                                                final FieldStaticTransform<T> first,
  172.                                                                                final FieldStaticTransform<T> second) {
  173.         return of(date,
  174.                   compositeTranslation(first, second),
  175.                   compositeRotation(first, second));
  176.     }

  177.     /**
  178.      * Compute a composite translation.
  179.      *
  180.      * @param first first applied transform
  181.      * @param second second applied transform
  182.      * @param <T> the type of the field elements
  183.      * @return translation part of the composite transform
  184.      */
  185.     static <T extends CalculusFieldElement<T>> FieldVector3D<T> compositeTranslation(final FieldStaticTransform<T> first,
  186.                                                                                      final FieldStaticTransform<T> second) {

  187.         final FieldVector3D<T> p1 = first.getTranslation();
  188.         final FieldRotation<T> r1 = first.getRotation();
  189.         final FieldVector3D<T> p2 = second.getTranslation();

  190.         return p1.add(r1.applyInverseTo(p2));

  191.     }

  192.     /**
  193.      * Compute a composite rotation.
  194.      *
  195.      * @param first first applied transform
  196.      * @param second second applied transform
  197.      * @param <T> the type of the field elements
  198.      * @return rotation part of the composite transform
  199.      */
  200.     static <T extends CalculusFieldElement<T>> FieldRotation<T> compositeRotation(final FieldStaticTransform<T> first,
  201.                                                                                   final FieldStaticTransform<T> second) {
  202.         final FieldRotation<T> r1 = first.getRotation();
  203.         final FieldRotation<T> r2 = second.getRotation();
  204.         return r1.compose(r2, RotationConvention.FRAME_TRANSFORM);
  205.     }

  206.     /**
  207.      * Create a new static transform from a rotation and zero translation.
  208.      *
  209.      * @param <T>         type of the elements
  210.      * @param date     of translation.
  211.      * @param rotation to apply after the translation. That is after translating
  212.      *                 applying this rotation produces positions expressed in
  213.      *                 the new frame.
  214.      * @return the newly created static transform.
  215.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  216.      */
  217.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  218.                                                                           final FieldRotation<T> rotation) {
  219.         return of(date, FieldVector3D.getZero(date.getField()), rotation);
  220.     }

  221.     /**
  222.      * Create a new static transform from a translation and rotation.
  223.      *
  224.      * @param <T>         type of the elements
  225.      * @param date        of translation.
  226.      * @param translation to apply, expressed in the old frame. That is, the
  227.      *                    opposite of the coordinates of the new origin in the
  228.      *                    old frame.
  229.      * @return the newly created static transform.
  230.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  231.      */
  232.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  233.                                                                           final FieldVector3D<T> translation) {
  234.         return of(date, translation, FieldRotation.getIdentity(date.getField()));
  235.     }

  236.     /**
  237.      * Create a new static transform from an {@link FieldAbsoluteDate} and a {@link StaticTransform}.
  238.      *
  239.      * @param <T>         type of the elements
  240.      * @param date        of translation.
  241.      * @param staticTransform to apply
  242.      * @return the newly created static transform.
  243.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  244.      */
  245.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  246.                                                                           final StaticTransform staticTransform) {
  247.         return of(date,
  248.                   new FieldVector3D<>(date.getField(), staticTransform.getTranslation()),
  249.                   new FieldRotation<>(date.getField(), staticTransform.getRotation()));
  250.     }

  251.     /**
  252.      * Create a new static transform from a translation and rotation.
  253.      *
  254.      * @param <T>         type of the elements
  255.      * @param date        of translation.
  256.      * @param translation to apply, expressed in the old frame. That is, the
  257.      *                    opposite of the coordinates of the new origin in the
  258.      *                    old frame.
  259.      * @param rotation    to apply after the translation. That is after
  260.      *                    translating applying this rotation produces positions
  261.      *                    expressed in the new frame.
  262.      * @return the newly created static transform.
  263.      * @see #compose(FieldAbsoluteDate, FieldStaticTransform, FieldStaticTransform)
  264.      * @see #of(FieldAbsoluteDate, FieldRotation)
  265.      * @see #of(FieldAbsoluteDate, FieldVector3D)
  266.      */
  267.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  268.                                                                           final FieldVector3D<T> translation,
  269.                                                                           final FieldRotation<T> rotation) {
  270.         return new FieldStaticTransform<T>() {

  271.             @Override
  272.             public FieldStaticTransform<T> getInverse() {
  273.                 final FieldRotation<T> r = getRotation();
  274.                 final FieldVector3D<T> rp = r.applyTo(getTranslation());
  275.                 final FieldVector3D<T> pInv = rp.negate();
  276.                 return FieldStaticTransform.of(date, pInv, rotation.revert());
  277.             }

  278.             @Override
  279.             public AbsoluteDate getDate() {
  280.                 return date.toAbsoluteDate();
  281.             }

  282.             @Override
  283.             public FieldAbsoluteDate<T> getFieldDate() {
  284.                 return date;
  285.             }

  286.             @Override
  287.             public FieldVector3D<T> getTranslation() {
  288.                 return translation;
  289.             }

  290.             @Override
  291.             public FieldRotation<T> getRotation() {
  292.                 return rotation;
  293.             }

  294.         };
  295.     }

  296. }