|
4 | 4 | import static us.ihmc.euclid.geometry.tools.EuclidGeometryTools.ONE_TRILLIONTH; |
5 | 5 | import static us.ihmc.euclid.tools.EuclidCoreTools.normSquared; |
6 | 6 |
|
| 7 | +import org.ejml.data.DMatrixRMaj; |
| 8 | + |
7 | 9 | import us.ihmc.commons.MathTools; |
8 | 10 | import us.ihmc.euclid.Axis3D; |
9 | 11 | import us.ihmc.euclid.geometry.tools.EuclidGeometryTools; |
|
21 | 23 | import us.ihmc.euclid.tuple2D.Point2D; |
22 | 24 | import us.ihmc.euclid.tuple2D.interfaces.Point2DBasics; |
23 | 25 | import us.ihmc.euclid.tuple2D.interfaces.Point2DReadOnly; |
24 | | -import us.ihmc.euclid.tuple2D.interfaces.Tuple2DReadOnly; |
25 | 26 | import us.ihmc.euclid.tuple2D.interfaces.Vector2DReadOnly; |
26 | | -import us.ihmc.euclid.tuple3D.interfaces.*; |
| 27 | +import us.ihmc.euclid.tuple3D.interfaces.Point3DBasics; |
| 28 | +import us.ihmc.euclid.tuple3D.interfaces.Tuple3DBasics; |
| 29 | +import us.ihmc.euclid.tuple3D.interfaces.Tuple3DReadOnly; |
| 30 | +import us.ihmc.euclid.tuple3D.interfaces.UnitVector3DReadOnly; |
| 31 | +import us.ihmc.euclid.tuple3D.interfaces.Vector3DBasics; |
| 32 | +import us.ihmc.euclid.tuple3D.interfaces.Vector3DReadOnly; |
27 | 33 | import us.ihmc.euclid.tuple4D.interfaces.QuaternionBasics; |
28 | 34 | import us.ihmc.euclid.tuple4D.interfaces.QuaternionReadOnly; |
29 | 35 |
|
@@ -93,7 +99,7 @@ public static void projectRotationOnAxis(QuaternionReadOnly rotation, Vector3DRe |
93 | 99 | { |
94 | 100 | double dotProduct = rotation.getX() * axis.getX() + rotation.getY() * axis.getY() + rotation.getZ() * axis.getZ(); |
95 | 101 |
|
96 | | - double scale = dotProduct / axis.lengthSquared(); |
| 102 | + double scale = dotProduct / axis.normSquared(); |
97 | 103 | double projectedX = scale * axis.getX(); |
98 | 104 | double projectedY = scale * axis.getY(); |
99 | 105 | double projectedZ = scale * axis.getZ(); |
@@ -1088,14 +1094,14 @@ public static boolean intersectionBetweenRay2DAndLine2D(Point2DReadOnly rayOrigi |
1088 | 1094 | * Just a more thorough version |
1089 | 1095 | */ |
1090 | 1096 | public static boolean intersectionBetweenRay2DAndLine2D(double rayOriginX, |
1091 | | - double rayOriginY, |
1092 | | - double rayDirectionX, |
1093 | | - double rayDirectionY, |
1094 | | - double lineOriginX, |
1095 | | - double lineOriginY, |
1096 | | - double lineDirectionX, |
1097 | | - double lineDirectionY, |
1098 | | - Point2DBasics intersectionToPack) |
| 1097 | + double rayOriginY, |
| 1098 | + double rayDirectionX, |
| 1099 | + double rayDirectionY, |
| 1100 | + double lineOriginX, |
| 1101 | + double lineOriginY, |
| 1102 | + double lineDirectionX, |
| 1103 | + double lineDirectionY, |
| 1104 | + Point2DBasics intersectionToPack) |
1099 | 1105 | { |
1100 | 1106 | double start1x = rayOriginX; |
1101 | 1107 | double start1y = rayOriginY; |
@@ -1138,7 +1144,7 @@ private static boolean intersectionBetweenTwoLine2DsImpl(double start1x, |
1138 | 1144 |
|
1139 | 1145 | if (Math.abs(determinant) < epsilon) |
1140 | 1146 | { // The lines are parallel |
1141 | | - // Check if they are collinear |
| 1147 | + // Check if they are collinear |
1142 | 1148 | double dx = start2x - start1x; |
1143 | 1149 | double dy = start2y - start1y; |
1144 | 1150 | double cross = dx * direction1y - dy * direction1x; |
@@ -1266,4 +1272,70 @@ private static boolean intersectionBetweenTwoLine2DsImpl(double start1x, |
1266 | 1272 |
|
1267 | 1273 | return areIntersecting; |
1268 | 1274 | } |
| 1275 | + |
| 1276 | + /** |
| 1277 | + * Calculate the angular velocity by differentiating orientation. |
| 1278 | + * |
| 1279 | + * @param qStart the initial orientation at time t. |
| 1280 | + * @param qEnd the final orientation at time t + duration. |
| 1281 | + * @param duration the time interval between the 2 orientations. |
| 1282 | + * @param angularVelocityToPack the angular velocity. |
| 1283 | + */ |
| 1284 | + public static void differentiateOrientation(QuaternionReadOnly qStart, QuaternionReadOnly qEnd, double duration, Vector3DBasics angularVelocityToPack) |
| 1285 | + { |
| 1286 | + double q1x = qStart.getX(); |
| 1287 | + double q1y = qStart.getY(); |
| 1288 | + double q1z = qStart.getZ(); |
| 1289 | + double q1s = qStart.getS(); |
| 1290 | + |
| 1291 | + double q2x = qEnd.getX(); |
| 1292 | + double q2y = qEnd.getY(); |
| 1293 | + double q2z = qEnd.getZ(); |
| 1294 | + double q2s = qEnd.getS(); |
| 1295 | + |
| 1296 | + double diffx = q1s * q2x - q1x * q2s - q1y * q2z + q1z * q2y; |
| 1297 | + double diffy = q1s * q2y + q1x * q2z - q1y * q2s - q1z * q2x; |
| 1298 | + double diffz = q1s * q2z - q1x * q2y + q1y * q2x - q1z * q2s; |
| 1299 | + double diffs = q1s * q2s + q1x * q2x + q1y * q2y + q1z * q2z; |
| 1300 | + |
| 1301 | + if (diffs < 0.0) |
| 1302 | + { |
| 1303 | + diffx = -diffx; |
| 1304 | + diffy = -diffy; |
| 1305 | + diffz = -diffz; |
| 1306 | + diffs = -diffs; |
| 1307 | + } |
| 1308 | + |
| 1309 | + double sinHalfTheta = EuclidCoreTools.norm(diffx, diffy, diffz); |
| 1310 | + |
| 1311 | + double angle; |
| 1312 | + if (EuclidCoreTools.epsilonEquals(1.0, diffs, 1.0e-12)) |
| 1313 | + angle = 2.0 * sinHalfTheta / diffs; |
| 1314 | + else |
| 1315 | + angle = 2.0 * EuclidCoreTools.atan2(sinHalfTheta, diffs); |
| 1316 | + angularVelocityToPack.set(diffx, diffy, diffz); |
| 1317 | + angularVelocityToPack.scale(angle / (sinHalfTheta * duration)); |
| 1318 | + } |
| 1319 | + |
| 1320 | + // *** NOTE ***: The 4x4 output matrix produced by this method assumes a Quaternion component ordering of: |
| 1321 | + // Quat = [ Qs |
| 1322 | + // Qx |
| 1323 | + // Qy |
| 1324 | + // Qz ] |
| 1325 | + public static DMatrixRMaj quaternionDotToOmegaTransform(QuaternionReadOnly rotatingFrameQuaternion) |
| 1326 | + { |
| 1327 | + double qs = rotatingFrameQuaternion.getS(); |
| 1328 | + double qx = rotatingFrameQuaternion.getX(); |
| 1329 | + double qy = rotatingFrameQuaternion.getY(); |
| 1330 | + double qz = rotatingFrameQuaternion.getZ(); |
| 1331 | + |
| 1332 | + DMatrixRMaj E = new DMatrixRMaj(4,4); |
| 1333 | + |
| 1334 | + E.set(0,0, qs); E.set(0,1, qx); E.set(0,2, qy); E.set(0,3, qz); |
| 1335 | + E.set(1,0,-qx); E.set(1,1, qs); E.set(1,2, qz); E.set(1,3,-qy); |
| 1336 | + E.set(2,0,-qy); E.set(2,1,-qz); E.set(2,2, qs); E.set(2,3, qx); |
| 1337 | + E.set(3,0,-qz); E.set(3,1, qy); E.set(3,2,-qx); E.set(3,3, qs); |
| 1338 | + |
| 1339 | + return E; |
| 1340 | + } |
1269 | 1341 | } |
0 commit comments