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.encounter;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.geometry.euclidean.threed.FieldRotation;
22  import org.hipparchus.geometry.euclidean.threed.Rotation;
23  import org.orekit.utils.FieldPVCoordinates;
24  import org.orekit.utils.PVCoordinates;
25  
26  /**
27   * Abstract class for encounter frame between two objects.
28   *
29   * @author Vincent Cucchietti
30   * @since 12.0
31   */
32  public abstract class AbstractEncounterLOF implements EncounterLOF {
33  
34      /**
35       * Other position and velocity of the encounter frame. Can be null.
36       * <p>
37       * <b>BEWARE: This is not the origin of the encounter local orbital frame !</b>
38       */
39      private PVCoordinates other;
40  
41      /**
42       * Other position and velocity of the encounter frame. Can be null.
43       * <p>
44       * <b>BEWARE: This is not the origin of the encounter local orbital frame !</b>
45       */
46      private FieldPVCoordinates<?> fieldOther;
47  
48      /**
49       * Constructor with {@link PVCoordinates}.
50       *
51       * @param other other object to create the encounter local orbital frame with (<b>not</b> the origin of the frame !)
52       */
53      protected AbstractEncounterLOF(final PVCoordinates other) {
54          this.other = other;
55      }
56  
57      /**
58       * Constructor with {@link FieldPVCoordinates}.
59       *
60       * @param other other object to create the encounter frame with (<b>not</b> the origin of the frame !)
61       * @param <T> type of the field elements
62       */
63      protected <T extends CalculusFieldElement<T>> AbstractEncounterLOF(final FieldPVCoordinates<T> other) {
64          this.fieldOther = other;
65      }
66  
67      /**
68       * Get the rotation from inertial to this encounter local orbital frame.
69       * <p>
70       * <b>BEWARE: The given origin's position and velocity coordinates must be given in the frame in which this instance
71       * has been expressed in.</b>
72       *
73       * @param field field to which the elements belong
74       * @param origin position-velocity of the origin in the same inertial frame as the one this instance has been expressed
75       * in.
76       * @param <T> type of the field elements
77       *
78       * @return rotation from inertial to this encounter local orbital frame
79       */
80      public <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
81                                                                                       final FieldPVCoordinates<T> origin) {
82          return rotationFromInertial(field, origin, getFieldOther(field));
83      }
84  
85      /**
86       * Get the rotation from inertial to this encounter local orbital frame.
87       * <p>
88       * <b>BEWARE: The given origin's position and velocity coordinates must be given in the frame in which this instance
89       * has been expressed in.</b>
90       *
91       * @param origin position-velocity of the origin in some inertial frame
92       *
93       * @return rotation from inertial to this encounter local orbital frame
94       */
95      public Rotation rotationFromInertial(final PVCoordinates origin) {
96          return rotationFromInertial(origin, getOther());
97      }
98  
99      /**
100      * Get the field version of other's position and velocity coordinates. If the instance has been created with normal
101      * {@link PVCoordinates}, then it will build its field equivalent.
102      *
103      * @param field field of the elements
104      * @param <T> type of the field elements
105      *
106      * @return field version of other's position and velocity coordinates
107      */
108     @SuppressWarnings("unchecked")
109     @Override
110     public <T extends CalculusFieldElement<T>> FieldPVCoordinates<T> getFieldOther(final Field<T> field) {
111         return fieldOther == null ? new FieldPVCoordinates<>(field, other) : (FieldPVCoordinates<T>) fieldOther;
112     }
113 
114     /**
115      * Get the normal version of other's position and velocity coordinates. If the instance has been created with field
116      * {@link FieldPVCoordinates}, then it will convert it to its {@link PVCoordinates} equivalent.
117      *
118      * @return normal version of other's position and velocity coordinates
119      */
120     @Override
121     public PVCoordinates getOther() {
122         return other == null ? fieldOther.toPVCoordinates() : other;
123     }
124 }