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 }