FieldStaticTransform.java

  1. /* Copyright 2002-2025 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.      * Override methods for speed.
  42.      *
  43.      * @param <T> type of the elements
  44.      * @param field field used by default
  45.      * @return identity transform.
  46.      */
  47.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> getIdentity(final Field<T> field) {
  48.         return new FieldStaticTransform<T>() {
  49.             @Override
  50.             public FieldVector3D<T> getTranslation() {
  51.                 return  FieldVector3D.getZero(field);
  52.             }

  53.             @Override
  54.             public FieldRotation<T> getRotation() {
  55.                 return FieldRotation.getIdentity(field);
  56.             }

  57.             @Override
  58.             public FieldStaticTransform<T> getStaticInverse() {
  59.                 return getInverse();
  60.             }

  61.             @Override
  62.             public FieldStaticTransform<T> getInverse() {
  63.                 return this;
  64.             }

  65.             @Override
  66.             public AbsoluteDate getDate() {
  67.                 return AbsoluteDate.ARBITRARY_EPOCH;
  68.             }

  69.             @Override
  70.             public FieldVector3D<T> transformVector(final FieldVector3D<T> vector) {
  71.                 return new FieldVector3D<>(vector.getX(), vector.getY(), vector.getZ());
  72.             }

  73.             @Override
  74.             public FieldVector3D<T> transformVector(final Vector3D vector) {
  75.                 return new FieldVector3D<>(field, vector);
  76.             }

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

  81.             @Override
  82.             public FieldVector3D<T> transformPosition(final Vector3D position) {
  83.                 return transformVector(position);
  84.             }
  85.         };
  86.     }

  87.     /**
  88.      * Transform a position vector (including translation effects).
  89.      *
  90.      * @param position vector to transform
  91.      * @return transformed position
  92.      */
  93.     default FieldVector3D<T> transformPosition(final Vector3D position) {
  94.         return getRotation().applyTo(getTranslation().add(position));
  95.     }

  96.     /**
  97.      * Transform a position vector (including translation effects).
  98.      *
  99.      * @param position vector to transform
  100.      * @return transformed position
  101.      */
  102.     default FieldVector3D<T> transformPosition(final FieldVector3D<T> position) {
  103.         return getRotation().applyTo(getTranslation().add(position));
  104.     }

  105.     /**
  106.      * Transform a vector (ignoring translation effects).
  107.      *
  108.      * @param vector vector to transform
  109.      * @return transformed vector
  110.      */
  111.     default FieldVector3D<T> transformVector(final Vector3D vector) {
  112.         return getRotation().applyTo(vector);
  113.     }

  114.     /**
  115.      * Transform a vector (ignoring translation effects).
  116.      *
  117.      * @param vector vector to transform
  118.      * @return transformed vector
  119.      */
  120.     default FieldVector3D<T> transformVector(final FieldVector3D<T> vector) {
  121.         return getRotation().applyTo(vector);
  122.     }

  123.     /**
  124.      * Transform a line.
  125.      *
  126.      * @param line to transform
  127.      * @return transformed line
  128.      */
  129.     default FieldLine<T> transformLine(final Line line) {
  130.         final FieldVector3D<T> transformedP0 = transformPosition(line.getOrigin());
  131.         final FieldVector3D<T> transformedP1 = transformPosition(line.pointAt(1.0e6));
  132.         return new FieldLine<>(transformedP0, transformedP1, line.getTolerance());
  133.     }

  134.     /**
  135.      * Transform a line.
  136.      *
  137.      * @param line to transform
  138.      * @return transformed line
  139.      */
  140.     default FieldLine<T> transformLine(final FieldLine<T> line) {
  141.         final FieldVector3D<T> transformedP0 = transformPosition(line.getOrigin());
  142.         final FieldVector3D<T> transformedP1 = transformPosition(line.pointAt(1.0e6));
  143.         return new FieldLine<>(transformedP0, transformedP1, line.getTolerance());
  144.     }

  145.     /** Get the Field date.
  146.      * This default implementation is there so that no API is broken by a minor release.
  147.      * It is overloaded by native inheritors and shall be removed in the next major release.
  148.      * @return Field date attached to the object
  149.      * @since 12.1
  150.      */
  151.     default FieldAbsoluteDate<T> getFieldDate() {
  152.         return new FieldAbsoluteDate<>(getTranslation().getX().getField(), getDate());
  153.     }

  154.     /**
  155.      * Get the underlying elementary translation.
  156.      * <p>A transform can be uniquely represented as an elementary
  157.      * translation followed by an elementary rotation. This method returns this
  158.      * unique elementary translation.</p>
  159.      *
  160.      * @return underlying elementary translation
  161.      */
  162.     FieldVector3D<T> getTranslation();

  163.     /**
  164.      * Get the underlying elementary rotation.
  165.      * <p>A transform can be uniquely represented as an elementary
  166.      * translation followed by an elementary rotation. This method returns this
  167.      * unique elementary rotation.</p>
  168.      *
  169.      * @return underlying elementary rotation
  170.      */
  171.     FieldRotation<T> getRotation();

  172.     /**
  173.      * Get the inverse transform of the instance.
  174.      *
  175.      * @return inverse transform of the instance
  176.      */
  177.     FieldStaticTransform<T> getInverse();

  178.     /**
  179.      * Get the inverse transform of the instance in static form (without rates).
  180.      * This enables to create a purely static inverse, as inheritors such as {@link FieldTransform} may
  181.      * have a relatively computationally-heavy #getInverse() method.
  182.      *
  183.      * @return inverse static transform of the instance
  184.      * @since 12.1
  185.      */
  186.     default FieldStaticTransform<T> getStaticInverse() {
  187.         final FieldVector3D<T> negatedTranslation = getTranslation().negate();
  188.         final FieldRotation<T> rotation = getRotation();
  189.         return FieldStaticTransform.of(getFieldDate(), rotation.applyTo(negatedTranslation), rotation.revert());
  190.     }

  191.     /**
  192.      * Build a transform by combining two existing ones.
  193.      * <p>
  194.      * Note that the dates of the two existing transformed are <em>ignored</em>,
  195.      * and the combined transform date is set to the date supplied in this
  196.      * constructor without any attempt to shift the raw transforms. This is a
  197.      * design choice allowing user full control of the combination.
  198.      * </p>
  199.      *
  200.      * @param <T>    type of the elements
  201.      * @param date   date of the transform
  202.      * @param first  first transform applied
  203.      * @param second second transform applied
  204.      * @return the newly created static transform that has the same effect as
  205.      * applying {@code first}, then {@code second}.
  206.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  207.      */
  208.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> compose(final FieldAbsoluteDate<T> date,
  209.                                                                                final FieldStaticTransform<T> first,
  210.                                                                                final FieldStaticTransform<T> second) {
  211.         return of(date,
  212.                   compositeTranslation(first, second),
  213.                   compositeRotation(first, second));
  214.     }

  215.     /**
  216.      * Compute a composite translation.
  217.      *
  218.      * @param first first applied transform
  219.      * @param second second applied transform
  220.      * @param <T> the type of the field elements
  221.      * @return translation part of the composite transform
  222.      */
  223.     static <T extends CalculusFieldElement<T>> FieldVector3D<T> compositeTranslation(final FieldStaticTransform<T> first,
  224.                                                                                      final FieldStaticTransform<T> second) {

  225.         final FieldVector3D<T> p1 = first.getTranslation();
  226.         final FieldRotation<T> r1 = first.getRotation();
  227.         final FieldVector3D<T> p2 = second.getTranslation();

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

  229.     }

  230.     /**
  231.      * Compute a composite rotation.
  232.      *
  233.      * @param first first applied transform
  234.      * @param second second applied transform
  235.      * @param <T> the type of the field elements
  236.      * @return rotation part of the composite transform
  237.      */
  238.     static <T extends CalculusFieldElement<T>> FieldRotation<T> compositeRotation(final FieldStaticTransform<T> first,
  239.                                                                                   final FieldStaticTransform<T> second) {
  240.         final FieldRotation<T> r1 = first.getRotation();
  241.         final FieldRotation<T> r2 = second.getRotation();
  242.         return r1.compose(r2, RotationConvention.FRAME_TRANSFORM);
  243.     }

  244.     /**
  245.      * Create a new static transform from a rotation and zero translation.
  246.      *
  247.      * @param <T>         type of the elements
  248.      * @param date     of translation.
  249.      * @param rotation to apply after the translation. That is after translating
  250.      *                 applying this rotation produces positions expressed in
  251.      *                 the new frame.
  252.      * @return the newly created static transform.
  253.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  254.      */
  255.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  256.                                                                           final FieldRotation<T> rotation) {
  257.         return of(date, FieldVector3D.getZero(date.getField()), rotation);
  258.     }

  259.     /**
  260.      * Create a new static transform from a translation and rotation.
  261.      *
  262.      * @param <T>         type of the elements
  263.      * @param date        of translation.
  264.      * @param translation to apply, expressed in the old frame. That is, the
  265.      *                    opposite of the coordinates of the new origin in the
  266.      *                    old frame.
  267.      * @return the newly created static transform.
  268.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  269.      */
  270.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  271.                                                                           final FieldVector3D<T> translation) {
  272.         return of(date, translation, FieldRotation.getIdentity(date.getField()));
  273.     }

  274.     /**
  275.      * Create a new static transform from an {@link FieldAbsoluteDate} and a {@link StaticTransform}.
  276.      *
  277.      * @param <T>         type of the elements
  278.      * @param date        of translation.
  279.      * @param staticTransform to apply
  280.      * @return the newly created static transform.
  281.      * @see #of(FieldAbsoluteDate, FieldVector3D, FieldRotation)
  282.      */
  283.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  284.                                                                           final StaticTransform staticTransform) {
  285.         return of(date,
  286.                   new FieldVector3D<>(date.getField(), staticTransform.getTranslation()),
  287.                   new FieldRotation<>(date.getField(), staticTransform.getRotation()));
  288.     }

  289.     /**
  290.      * Create a new static transform from a translation and rotation.
  291.      *
  292.      * @param <T>         type of the elements
  293.      * @param date        of translation.
  294.      * @param translation to apply, expressed in the old frame. That is, the
  295.      *                    opposite of the coordinates of the new origin in the
  296.      *                    old frame.
  297.      * @param rotation    to apply after the translation. That is after
  298.      *                    translating applying this rotation produces positions
  299.      *                    expressed in the new frame.
  300.      * @return the newly created static transform.
  301.      * @see #compose(FieldAbsoluteDate, FieldStaticTransform, FieldStaticTransform)
  302.      * @see #of(FieldAbsoluteDate, FieldRotation)
  303.      * @see #of(FieldAbsoluteDate, FieldVector3D)
  304.      */
  305.     static <T extends CalculusFieldElement<T>> FieldStaticTransform<T> of(final FieldAbsoluteDate<T> date,
  306.                                                                           final FieldVector3D<T> translation,
  307.                                                                           final FieldRotation<T> rotation) {
  308.         return new FieldStaticTransform<T>() {

  309.             @Override
  310.             public FieldStaticTransform<T> getInverse() {
  311.                 final FieldRotation<T> r = getRotation();
  312.                 final FieldVector3D<T> rp = r.applyTo(getTranslation());
  313.                 final FieldVector3D<T> pInv = rp.negate();
  314.                 return FieldStaticTransform.of(date, pInv, rotation.revert());
  315.             }

  316.             @Override
  317.             public AbsoluteDate getDate() {
  318.                 return date.toAbsoluteDate();
  319.             }

  320.             @Override
  321.             public FieldAbsoluteDate<T> getFieldDate() {
  322.                 return date;
  323.             }

  324.             @Override
  325.             public FieldVector3D<T> getTranslation() {
  326.                 return translation;
  327.             }

  328.             @Override
  329.             public FieldRotation<T> getRotation() {
  330.                 return rotation;
  331.             }

  332.         };
  333.     }

  334. }