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
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
21 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22 import org.hipparchus.geometry.euclidean.threed.Line;
23 import org.hipparchus.geometry.euclidean.threed.Rotation;
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.TimeStamped;
28
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 * @author Evan Ward
34 * @see Transform
35 * @since 11.2
36 */
37 public interface StaticTransform extends TimeStamped {
38
39 /**
40 * Get the identity static transform.
41 *
42 * @return identity transform.
43 */
44 static StaticTransform getIdentity() {
45 return Transform.IDENTITY;
46 }
47
48 /**
49 * Transform a position vector (including translation effects).
50 *
51 * @param position vector to transform
52 * @return transformed position
53 */
54 default Vector3D transformPosition(final Vector3D position) {
55 return getRotation().applyTo(getTranslation().add(position));
56 }
57
58 /**
59 * Transform a position vector (including translation effects).
60 *
61 * @param position vector to transform
62 * @param <T> the type of the field elements
63 * @return transformed position
64 */
65 default <T extends CalculusFieldElement<T>> FieldVector3D<T> transformPosition(
66 final FieldVector3D<T> position) {
67 return FieldRotation.applyTo(getRotation(), position.add(getTranslation()));
68 }
69
70 /**
71 * Transform a vector (ignoring translation effects).
72 *
73 * @param vector vector to transform
74 * @return transformed vector
75 */
76 default Vector3D transformVector(final Vector3D vector) {
77 return getRotation().applyTo(vector);
78 }
79
80 /**
81 * Transform a vector (ignoring translation effects).
82 *
83 * @param vector vector to transform
84 * @param <T> the type of the field elements
85 * @return transformed vector
86 */
87 default <T extends CalculusFieldElement<T>> FieldVector3D<T> transformVector(
88 final FieldVector3D<T> vector) {
89 return FieldRotation.applyTo(getRotation(), vector);
90 }
91
92 /**
93 * Transform a line.
94 *
95 * @param line to transform
96 * @return transformed line
97 */
98 default Line transformLine(final Line line) {
99 final Vector3D transformedP0 = transformPosition(line.getOrigin());
100 final Vector3D transformedD = transformVector(line.getDirection());
101 return Line.fromDirection(transformedP0, transformedD, line.getTolerance());
102 }
103
104 /**
105 * Get the underlying elementary translation.
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 translation.</p>
109 *
110 * @return underlying elementary translation
111 */
112 Vector3D getTranslation();
113
114 /**
115 * Get the underlying elementary rotation.
116 * <p>A transform can be uniquely represented as an elementary
117 * translation followed by an elementary rotation. This method returns this
118 * unique elementary rotation.</p>
119 *
120 * @return underlying elementary rotation
121 */
122 Rotation getRotation();
123
124 /**
125 * Get the inverse transform of the instance.
126 *
127 * @return inverse transform of the instance
128 */
129 StaticTransform getInverse();
130
131 /**
132 * Build a transform by combining two existing ones.
133 * <p>
134 * Note that the dates of the two existing transformed are <em>ignored</em>,
135 * and the combined transform date is set to the date supplied in this
136 * constructor without any attempt to shift the raw transforms. This is a
137 * design choice allowing user full control of the combination.
138 * </p>
139 *
140 * @param date date of the transform
141 * @param first first transform applied
142 * @param second second transform applied
143 * @return the newly created static transform that has the same effect as
144 * applying {@code first}, then {@code second}.
145 * @see #of(AbsoluteDate, Vector3D, Rotation)
146 */
147 static StaticTransform compose(final AbsoluteDate date,
148 final StaticTransform first,
149 final StaticTransform second) {
150 return of(date,
151 compositeTranslation(first, second),
152 compositeRotation(first, second));
153 }
154
155 /**
156 * Compute a composite translation.
157 *
158 * @param first first applied transform
159 * @param second second applied transform
160 * @return translation part of the composite transform
161 */
162 static Vector3D compositeTranslation(
163 final StaticTransform first,
164 final StaticTransform second) {
165 final Vector3D p1 = first.getTranslation();
166 final Rotation r1 = first.getRotation();
167 final Vector3D p2 = second.getTranslation();
168
169 return p1.add(r1.applyInverseTo(p2));
170 }
171
172 /**
173 * Compute a composite rotation.
174 *
175 * @param first first applied transform
176 * @param second second applied transform
177 * @return rotation part of the composite transform
178 */
179 static Rotation compositeRotation(final StaticTransform first,
180 final StaticTransform second) {
181 final Rotation r1 = first.getRotation();
182 final Rotation r2 = second.getRotation();
183 return r1.compose(r2, RotationConvention.FRAME_TRANSFORM);
184
185 }
186
187 /**
188 * Create a new static transform from a rotation and zero translation.
189 *
190 * @param date of translation.
191 * @param rotation to apply after the translation. That is after translating
192 * applying this rotation produces positions expressed in
193 * the new frame.
194 * @return the newly created static transform.
195 * @see #of(AbsoluteDate, Vector3D, Rotation)
196 */
197 static StaticTransform of(final AbsoluteDate date,
198 final Rotation rotation) {
199 return of(date, Vector3D.ZERO, rotation);
200 }
201
202 /**
203 * Create a new static transform from a translation and rotation.
204 *
205 * @param date of translation.
206 * @param translation to apply, expressed in the old frame. That is, the
207 * opposite of the coordinates of the new origin in the
208 * old frame.
209 * @return the newly created static transform.
210 * @see #of(AbsoluteDate, Vector3D, Rotation)
211 */
212 static StaticTransform of(final AbsoluteDate date,
213 final Vector3D translation) {
214 return of(date, translation, Rotation.IDENTITY);
215 }
216
217 /**
218 * Create a new static transform from a translation and rotation.
219 *
220 * @param date of translation.
221 * @param translation to apply, expressed in the old frame. That is, the
222 * opposite of the coordinates of the new origin in the
223 * old frame.
224 * @param rotation to apply after the translation. That is after
225 * translating applying this rotation produces positions
226 * expressed in the new frame.
227 * @return the newly created static transform.
228 * @see #compose(AbsoluteDate, StaticTransform, StaticTransform)
229 * @see #of(AbsoluteDate, Rotation)
230 * @see #of(AbsoluteDate, Vector3D)
231 */
232 static StaticTransform of(final AbsoluteDate date,
233 final Vector3D translation,
234 final Rotation rotation) {
235 return new StaticTransform() {
236
237 @Override
238 public StaticTransform getInverse() {
239 final Rotation r = getRotation();
240 final Vector3D rp = r.applyTo(getTranslation());
241 final Vector3D pInv = rp.negate();
242 return StaticTransform.of(date, pInv, rotation.revert());
243 }
244
245 @Override
246 public AbsoluteDate getDate() {
247 return date;
248 }
249
250 @Override
251 public Vector3D getTranslation() {
252 return translation;
253 }
254
255 @Override
256 public Rotation getRotation() {
257 return rotation;
258 }
259
260 };
261 }
262
263 }