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.FieldVector3D;
23  import org.hipparchus.geometry.euclidean.threed.Rotation;
24  import org.hipparchus.geometry.euclidean.threed.Vector3D;
25  import org.orekit.utils.FieldPVCoordinates;
26  import org.orekit.utils.PVCoordinates;
27  
28  /**
29   * Valsecchi encounter local orbital frame based on Valsecchi formulation from : "Valsecchi, G. B., Milani, A., Gronchi, G.
30   * F. & Ches- ley, S. R. Resonant returns to close approaches: Analytical theory. Astronomy & Astrophysics 408,
31   * 1179–1196 (2003).".
32   * <p>
33   * Note that <b>it is up to the user</b> to choose which object should be at the origin.
34   *
35   * @author Vincent Cucchietti
36   * @author Quentin Parpaite
37   * @since 12.0
38   */
39  public class ValsecchiEncounterFrame extends AbstractEncounterLOF {
40  
41      /**
42       * Constructor.
43       *
44       * @param other other object to create the encounter frame with (not the origin of the frame !)
45       */
46      public ValsecchiEncounterFrame(final PVCoordinates other) {
47          super(other);
48      }
49  
50      /**
51       * Constructor.
52       *
53       * @param other other object to create the encounter frame with (not the origin of the frame !)
54       * @param <T> type of the field elements
55       */
56      public <T extends CalculusFieldElement<T>> ValsecchiEncounterFrame(final FieldPVCoordinates<T> other) {
57          super(other);
58      }
59  
60      /** {@inheritDoc} */
61      @Override
62      public <T extends CalculusFieldElement<T>> FieldRotation<T> rotationFromInertial(final Field<T> field,
63                                                                                       final FieldPVCoordinates<T> origin,
64                                                                                       final FieldPVCoordinates<T> other) {
65          final FieldVector3D<T> otherVelocity = other.getVelocity();
66  
67          final FieldVector3D<T> xAxis = origin.getVelocity().crossProduct(otherVelocity).normalize();
68          final FieldVector3D<T> yAxis = otherVelocity.subtract(origin.getVelocity()).normalize();
69  
70          return new FieldRotation<>(xAxis, yAxis, FieldVector3D.getPlusI(field), FieldVector3D.getPlusJ(field));
71      }
72  
73      /** {@inheritDoc} */
74      @Override
75      public Rotation rotationFromInertial(final PVCoordinates origin, final PVCoordinates other) {
76          final Vector3D xAxis = origin.getVelocity().crossProduct(other.getVelocity()).normalize();
77          final Vector3D yAxis = other.getVelocity().subtract(origin.getVelocity()).normalize();
78  
79          return new Rotation(xAxis, yAxis, Vector3D.PLUS_I, Vector3D.PLUS_J);
80      }
81  
82      /**
83       * {@inheritDoc}
84       * <p>
85       * In this case, return (0,1,0);
86       */
87      @Override
88      public <T extends CalculusFieldElement<T>> FieldVector3D<T> getAxisNormalToCollisionPlane(final Field<T> field) {
89          return FieldVector3D.getPlusJ(field);
90      }
91  
92      /**
93       * {@inheritDoc}
94       * <p>
95       * In this case, return (0,1,0);
96       */
97      @Override
98      public Vector3D getAxisNormalToCollisionPlane() {
99          return Vector3D.PLUS_J;
100     }
101 
102     /** {@inheritDoc} */
103     @Override
104     public String getName() {
105         return "VALSECCHI_ENCOUNTER_LOF";
106     }
107 }