| | | 1 | | //======================================================================= |
| | | 2 | | // WideTriangleRelations.ClosestPoint.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2024–present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | namespace FixedMathSharp.Geometry; |
| | | 9 | | |
| | | 10 | | /// <content> |
| | | 11 | | /// Provides the exact closest-point reducer for rigid triangle frames. |
| | | 12 | | /// </content> |
| | | 13 | | internal static partial class WideTriangleRelations |
| | | 14 | | { |
| | | 15 | | internal static FixedPointAnchor GetClosestPointAnchor( |
| | | 16 | | FixedTriangle triangle, |
| | | 17 | | Vector3d triangleOrigin, |
| | | 18 | | FixedQuaternion triangleRotation, |
| | | 19 | | in FixedPointAnchor point) |
| | | 20 | | { |
| | 450 | 21 | | GetPointLocalNumerators( |
| | 450 | 22 | | point, |
| | 450 | 23 | | triangleOrigin, |
| | 450 | 24 | | triangleRotation, |
| | 450 | 25 | | out Signed576 pointX, |
| | 450 | 26 | | out Signed576 pointY, |
| | 450 | 27 | | out Signed576 pointZ, |
| | 450 | 28 | | out Signed320 pointDenominator); |
| | 450 | 29 | | Vector3d closest = GetClosestTriangleLocalPoint( |
| | 450 | 30 | | triangle, |
| | 450 | 31 | | pointX, |
| | 450 | 32 | | pointY, |
| | 450 | 33 | | pointZ, |
| | 450 | 34 | | pointDenominator); |
| | 450 | 35 | | return FixedPointAnchor.FromValidatedFrame( |
| | 450 | 36 | | triangleOrigin, |
| | 450 | 37 | | triangleRotation, |
| | 450 | 38 | | closest); |
| | | 39 | | } |
| | | 40 | | |
| | | 41 | | private static Vector3d GetClosestTriangleLocalPoint( |
| | | 42 | | FixedTriangle triangle, |
| | | 43 | | Signed576 pointX, |
| | | 44 | | Signed576 pointY, |
| | | 45 | | Signed576 pointZ, |
| | | 46 | | Signed320 pointDenominator) |
| | | 47 | | { |
| | 450 | 48 | | Signed192 abAb = GetTriangleDifferenceDot( |
| | 450 | 49 | | triangle.B, |
| | 450 | 50 | | triangle.A, |
| | 450 | 51 | | triangle.B, |
| | 450 | 52 | | triangle.A); |
| | 450 | 53 | | Signed192 abAc = GetTriangleDifferenceDot( |
| | 450 | 54 | | triangle.B, |
| | 450 | 55 | | triangle.A, |
| | 450 | 56 | | triangle.C, |
| | 450 | 57 | | triangle.A); |
| | 450 | 58 | | Signed192 acAc = GetTriangleDifferenceDot( |
| | 450 | 59 | | triangle.C, |
| | 450 | 60 | | triangle.A, |
| | 450 | 61 | | triangle.C, |
| | 450 | 62 | | triangle.A); |
| | 450 | 63 | | Signed320 gram = WideArithmetic.MultiplySubtract( |
| | 450 | 64 | | abAb, |
| | 450 | 65 | | acAc, |
| | 450 | 66 | | abAc, |
| | 450 | 67 | | abAc); |
| | 450 | 68 | | if (WideGeometry.IsQ128MagnitudeAtMostEpsilon(gram)) |
| | | 69 | | { |
| | 102 | 70 | | return GetClosestTriangleEdgePoint( |
| | 102 | 71 | | triangle, |
| | 102 | 72 | | pointX, |
| | 102 | 73 | | pointY, |
| | 102 | 74 | | pointZ, |
| | 102 | 75 | | pointDenominator); |
| | | 76 | | } |
| | | 77 | | |
| | 348 | 78 | | Signed576 d1 = GetPointEdgeDotNumerator( |
| | 348 | 79 | | pointX, |
| | 348 | 80 | | pointY, |
| | 348 | 81 | | pointZ, |
| | 348 | 82 | | pointDenominator, |
| | 348 | 83 | | triangle.A, |
| | 348 | 84 | | triangle.B); |
| | 348 | 85 | | Signed576 d2 = GetPointEdgeDotNumerator( |
| | 348 | 86 | | pointX, |
| | 348 | 87 | | pointY, |
| | 348 | 88 | | pointZ, |
| | 348 | 89 | | pointDenominator, |
| | 348 | 90 | | triangle.A, |
| | 348 | 91 | | triangle.C); |
| | 348 | 92 | | if (d1.Sign <= 0 && d2.Sign <= 0) |
| | 2 | 93 | | return triangle.A; |
| | | 94 | | |
| | 346 | 95 | | Signed576 abAbScaled = ScaleTriangleDot(abAb, pointDenominator); |
| | 346 | 96 | | Signed576 abAcScaled = ScaleTriangleDot(abAc, pointDenominator); |
| | 346 | 97 | | Signed576 acAcScaled = ScaleTriangleDot(acAc, pointDenominator); |
| | 346 | 98 | | Signed576 d3 = WideArithmetic.SubtractSigned576(d1, abAbScaled); |
| | 346 | 99 | | Signed576 d4 = WideArithmetic.SubtractSigned576(d2, abAcScaled); |
| | 346 | 100 | | if (d3.Sign >= 0 |
| | 346 | 101 | | && WideArithmetic.SubtractSigned576(d4, d3).Sign <= 0) |
| | | 102 | | { |
| | 2 | 103 | | return triangle.B; |
| | | 104 | | } |
| | | 105 | | |
| | 344 | 106 | | Signed576 vc = WideArithmetic.SubtractSigned576( |
| | 344 | 107 | | WideArithmetic.MultiplySigned576(d2, abAb), |
| | 344 | 108 | | WideArithmetic.MultiplySigned576(d1, abAc)); |
| | 344 | 109 | | if (vc.Sign <= 0 && d1.Sign >= 0 && d3.Sign <= 0) |
| | | 110 | | { |
| | 28 | 111 | | Fixed64 parameter = GetTriangleUnitRatio(d1, abAbScaled); |
| | 28 | 112 | | return Vector3d.Lerp(triangle.A, triangle.B, parameter); |
| | | 113 | | } |
| | | 114 | | |
| | 316 | 115 | | Signed576 d5 = WideArithmetic.SubtractSigned576(d1, abAcScaled); |
| | 316 | 116 | | Signed576 d6 = WideArithmetic.SubtractSigned576(d2, acAcScaled); |
| | 316 | 117 | | if (d6.Sign >= 0 |
| | 316 | 118 | | && WideArithmetic.SubtractSigned576(d5, d6).Sign <= 0) |
| | | 119 | | { |
| | 1 | 120 | | return triangle.C; |
| | | 121 | | } |
| | | 122 | | |
| | 315 | 123 | | Signed576 vb = WideArithmetic.SubtractSigned576( |
| | 315 | 124 | | WideArithmetic.MultiplySigned576(d1, acAc), |
| | 315 | 125 | | WideArithmetic.MultiplySigned576(d2, abAc)); |
| | 315 | 126 | | if (vb.Sign <= 0 && d2.Sign >= 0 && d6.Sign <= 0) |
| | | 127 | | { |
| | 163 | 128 | | Fixed64 parameter = GetTriangleUnitRatio(d2, acAcScaled); |
| | 163 | 129 | | return Vector3d.Lerp(triangle.A, triangle.C, parameter); |
| | | 130 | | } |
| | | 131 | | |
| | 152 | 132 | | Signed576 d4MinusD3 = WideArithmetic.SubtractSigned576(d4, d3); |
| | 152 | 133 | | Signed576 d5MinusD6 = WideArithmetic.SubtractSigned576(d5, d6); |
| | 152 | 134 | | Signed576 gramScaled = WideArithmetic.MultiplySigned320( |
| | 152 | 135 | | gram, |
| | 152 | 136 | | pointDenominator); |
| | 152 | 137 | | Signed576 va = WideArithmetic.SubtractSigned576( |
| | 152 | 138 | | WideArithmetic.SubtractSigned576(gramScaled, vb), |
| | 152 | 139 | | vc); |
| | 152 | 140 | | if (va.Sign <= 0 |
| | 152 | 141 | | && d4MinusD3.Sign >= 0 |
| | 152 | 142 | | && d5MinusD6.Sign >= 0) |
| | | 143 | | { |
| | 66 | 144 | | Fixed64 parameter = GetTriangleUnitRatio( |
| | 66 | 145 | | d4MinusD3, |
| | 66 | 146 | | WideArithmetic.AddSigned576(d4MinusD3, d5MinusD6)); |
| | 66 | 147 | | return Vector3d.Lerp(triangle.B, triangle.C, parameter); |
| | | 148 | | } |
| | | 149 | | |
| | 86 | 150 | | Fixed64 weightB = GetTriangleUnitRatio(vb, gramScaled); |
| | 86 | 151 | | Fixed64 weightC = GetTriangleUnitRatio(vc, gramScaled); |
| | 86 | 152 | | return triangle.GetPoint(weightB, weightC); |
| | | 153 | | } |
| | | 154 | | |
| | | 155 | | private static Vector3d GetClosestTriangleEdgePoint( |
| | | 156 | | FixedTriangle triangle, |
| | | 157 | | Signed576 pointX, |
| | | 158 | | Signed576 pointY, |
| | | 159 | | Signed576 pointZ, |
| | | 160 | | Signed320 pointDenominator) |
| | | 161 | | { |
| | 102 | 162 | | Vector3d best = GetClosestTriangleSegmentPoint( |
| | 102 | 163 | | triangle.A, |
| | 102 | 164 | | triangle.B, |
| | 102 | 165 | | pointX, |
| | 102 | 166 | | pointY, |
| | 102 | 167 | | pointZ, |
| | 102 | 168 | | pointDenominator); |
| | 102 | 169 | | KeepCloserTriangleSegmentPoint( |
| | 102 | 170 | | triangle.B, |
| | 102 | 171 | | triangle.C, |
| | 102 | 172 | | pointX, |
| | 102 | 173 | | pointY, |
| | 102 | 174 | | pointZ, |
| | 102 | 175 | | pointDenominator, |
| | 102 | 176 | | ref best); |
| | 102 | 177 | | KeepCloserTriangleSegmentPoint( |
| | 102 | 178 | | triangle.C, |
| | 102 | 179 | | triangle.A, |
| | 102 | 180 | | pointX, |
| | 102 | 181 | | pointY, |
| | 102 | 182 | | pointZ, |
| | 102 | 183 | | pointDenominator, |
| | 102 | 184 | | ref best); |
| | 102 | 185 | | return best; |
| | | 186 | | } |
| | | 187 | | |
| | | 188 | | private static void KeepCloserTriangleSegmentPoint( |
| | | 189 | | Vector3d start, |
| | | 190 | | Vector3d end, |
| | | 191 | | Signed576 pointX, |
| | | 192 | | Signed576 pointY, |
| | | 193 | | Signed576 pointZ, |
| | | 194 | | Signed320 pointDenominator, |
| | | 195 | | ref Vector3d best) |
| | | 196 | | { |
| | 204 | 197 | | Vector3d candidate = GetClosestTriangleSegmentPoint( |
| | 204 | 198 | | start, |
| | 204 | 199 | | end, |
| | 204 | 200 | | pointX, |
| | 204 | 201 | | pointY, |
| | 204 | 202 | | pointZ, |
| | 204 | 203 | | pointDenominator); |
| | 204 | 204 | | Signed832 candidateDistance = GetTriangleSquaredDistanceNumerator( |
| | 204 | 205 | | pointX, |
| | 204 | 206 | | pointY, |
| | 204 | 207 | | pointZ, |
| | 204 | 208 | | pointDenominator, |
| | 204 | 209 | | candidate); |
| | 204 | 210 | | Signed832 bestDistance = GetTriangleSquaredDistanceNumerator( |
| | 204 | 211 | | pointX, |
| | 204 | 212 | | pointY, |
| | 204 | 213 | | pointZ, |
| | 204 | 214 | | pointDenominator, |
| | 204 | 215 | | best); |
| | 204 | 216 | | if (WideArithmetic.SubtractSigned832( |
| | 204 | 217 | | candidateDistance, |
| | 204 | 218 | | bestDistance).Sign < 0) |
| | | 219 | | { |
| | 1 | 220 | | best = candidate; |
| | | 221 | | } |
| | 204 | 222 | | } |
| | | 223 | | |
| | | 224 | | private static Vector3d GetClosestTriangleSegmentPoint( |
| | | 225 | | Vector3d start, |
| | | 226 | | Vector3d end, |
| | | 227 | | Signed576 pointX, |
| | | 228 | | Signed576 pointY, |
| | | 229 | | Signed576 pointZ, |
| | | 230 | | Signed320 pointDenominator) |
| | | 231 | | { |
| | 306 | 232 | | Signed192 lengthSquared = GetTriangleDifferenceDot( |
| | 306 | 233 | | end, |
| | 306 | 234 | | start, |
| | 306 | 235 | | end, |
| | 306 | 236 | | start); |
| | 306 | 237 | | if (lengthSquared.Sign <= 0) |
| | 102 | 238 | | return start; |
| | | 239 | | |
| | 204 | 240 | | Signed576 projection = GetPointEdgeDotNumerator( |
| | 204 | 241 | | pointX, |
| | 204 | 242 | | pointY, |
| | 204 | 243 | | pointZ, |
| | 204 | 244 | | pointDenominator, |
| | 204 | 245 | | start, |
| | 204 | 246 | | end); |
| | 204 | 247 | | if (projection.Sign <= 0) |
| | 2 | 248 | | return start; |
| | | 249 | | |
| | 202 | 250 | | Signed576 scaledLength = |
| | 202 | 251 | | ScaleTriangleDot(lengthSquared, pointDenominator); |
| | 202 | 252 | | if (WideArithmetic.SubtractSigned576( |
| | 202 | 253 | | projection, |
| | 202 | 254 | | scaledLength).Sign >= 0) |
| | | 255 | | { |
| | 2 | 256 | | return end; |
| | | 257 | | } |
| | | 258 | | |
| | 200 | 259 | | return Vector3d.Lerp( |
| | 200 | 260 | | start, |
| | 200 | 261 | | end, |
| | 200 | 262 | | GetTriangleUnitRatio(projection, scaledLength)); |
| | | 263 | | } |
| | | 264 | | |
| | | 265 | | private static Signed832 GetTriangleSquaredDistanceNumerator( |
| | | 266 | | Signed576 pointX, |
| | | 267 | | Signed576 pointY, |
| | | 268 | | Signed576 pointZ, |
| | | 269 | | Signed320 pointDenominator, |
| | | 270 | | Vector3d candidate) |
| | | 271 | | { |
| | 408 | 272 | | Signed576 x = GetTrianglePointDeltaNumerator( |
| | 408 | 273 | | pointX, |
| | 408 | 274 | | candidate.X, |
| | 408 | 275 | | pointDenominator); |
| | 408 | 276 | | Signed576 y = GetTrianglePointDeltaNumerator( |
| | 408 | 277 | | pointY, |
| | 408 | 278 | | candidate.Y, |
| | 408 | 279 | | pointDenominator); |
| | 408 | 280 | | Signed576 z = GetTrianglePointDeltaNumerator( |
| | 408 | 281 | | pointZ, |
| | 408 | 282 | | candidate.Z, |
| | 408 | 283 | | pointDenominator); |
| | 408 | 284 | | return WideArithmetic.AddSigned832( |
| | 408 | 285 | | WideArithmetic.AddSigned832( |
| | 408 | 286 | | WideArithmetic.MultiplySigned576ToSigned832(x, x), |
| | 408 | 287 | | WideArithmetic.MultiplySigned576ToSigned832(y, y)), |
| | 408 | 288 | | WideArithmetic.MultiplySigned576ToSigned832(z, z)); |
| | | 289 | | } |
| | | 290 | | |
| | | 291 | | private static Signed576 GetPointEdgeDotNumerator( |
| | | 292 | | Signed576 pointX, |
| | | 293 | | Signed576 pointY, |
| | | 294 | | Signed576 pointZ, |
| | | 295 | | Signed320 pointDenominator, |
| | | 296 | | Vector3d edgeStart, |
| | | 297 | | Vector3d edgeEnd) |
| | | 298 | | { |
| | 900 | 299 | | Signed576 deltaX = GetTrianglePointDeltaNumerator( |
| | 900 | 300 | | pointX, |
| | 900 | 301 | | edgeStart.X, |
| | 900 | 302 | | pointDenominator); |
| | 900 | 303 | | Signed576 deltaY = GetTrianglePointDeltaNumerator( |
| | 900 | 304 | | pointY, |
| | 900 | 305 | | edgeStart.Y, |
| | 900 | 306 | | pointDenominator); |
| | 900 | 307 | | Signed576 deltaZ = GetTrianglePointDeltaNumerator( |
| | 900 | 308 | | pointZ, |
| | 900 | 309 | | edgeStart.Z, |
| | 900 | 310 | | pointDenominator); |
| | 900 | 311 | | Signed192 edgeX = WideArithmetic.SubtractSigned192( |
| | 900 | 312 | | Signed192.Raw(edgeEnd.X), |
| | 900 | 313 | | Signed192.Raw(edgeStart.X)); |
| | 900 | 314 | | Signed192 edgeY = WideArithmetic.SubtractSigned192( |
| | 900 | 315 | | Signed192.Raw(edgeEnd.Y), |
| | 900 | 316 | | Signed192.Raw(edgeStart.Y)); |
| | 900 | 317 | | Signed192 edgeZ = WideArithmetic.SubtractSigned192( |
| | 900 | 318 | | Signed192.Raw(edgeEnd.Z), |
| | 900 | 319 | | Signed192.Raw(edgeStart.Z)); |
| | 900 | 320 | | return WideArithmetic.AddSigned576( |
| | 900 | 321 | | WideArithmetic.AddSigned576( |
| | 900 | 322 | | WideArithmetic.MultiplySigned576(deltaX, edgeX), |
| | 900 | 323 | | WideArithmetic.MultiplySigned576(deltaY, edgeY)), |
| | 900 | 324 | | WideArithmetic.MultiplySigned576(deltaZ, edgeZ)); |
| | | 325 | | } |
| | | 326 | | |
| | | 327 | | private static Signed576 GetTrianglePointDeltaNumerator( |
| | | 328 | | Signed576 pointCoordinate, |
| | | 329 | | Fixed64 triangleCoordinate, |
| | | 330 | | Signed320 pointDenominator) => |
| | 3924 | 331 | | WideArithmetic.SubtractSigned576( |
| | 3924 | 332 | | pointCoordinate, |
| | 3924 | 333 | | WideArithmetic.MultiplySigned320( |
| | 3924 | 334 | | Signed320.ExtendValue(Signed192.Raw(triangleCoordinate)), |
| | 3924 | 335 | | pointDenominator)); |
| | | 336 | | |
| | | 337 | | private static Signed576 ScaleTriangleDot( |
| | | 338 | | Signed192 value, |
| | | 339 | | Signed320 scale) => |
| | 1240 | 340 | | WideArithmetic.MultiplySigned320( |
| | 1240 | 341 | | Signed320.ExtendValue(value), |
| | 1240 | 342 | | scale); |
| | | 343 | | |
| | | 344 | | private static Fixed64 GetTriangleUnitRatio( |
| | | 345 | | Signed576 numerator, |
| | | 346 | | Signed576 denominator) |
| | | 347 | | { |
| | 629 | 348 | | _ = Fixed64.TryGetSignedRawRatio( |
| | 629 | 349 | | WideArithmetic.MultiplySigned576ToSigned704( |
| | 629 | 350 | | numerator, |
| | 629 | 351 | | Signed320.ExtendValue(Signed192.One)), |
| | 629 | 352 | | Signed704.ExtendValue(denominator), |
| | 629 | 353 | | out Fixed64 ratio); |
| | 629 | 354 | | return ratio; |
| | | 355 | | } |
| | | 356 | | |
| | | 357 | | private static Signed192 GetTriangleDifferenceDot( |
| | | 358 | | Vector3d leftEnd, |
| | | 359 | | Vector3d leftStart, |
| | | 360 | | Vector3d rightEnd, |
| | | 361 | | Vector3d rightStart) => |
| | 1656 | 362 | | WideGeometry.GetDifferenceDotProduct3D( |
| | 1656 | 363 | | leftEnd.X, |
| | 1656 | 364 | | leftStart.X, |
| | 1656 | 365 | | leftEnd.Y, |
| | 1656 | 366 | | leftStart.Y, |
| | 1656 | 367 | | leftEnd.Z, |
| | 1656 | 368 | | leftStart.Z, |
| | 1656 | 369 | | rightEnd.X, |
| | 1656 | 370 | | rightStart.X, |
| | 1656 | 371 | | rightEnd.Y, |
| | 1656 | 372 | | rightStart.Y, |
| | 1656 | 373 | | rightEnd.Z, |
| | 1656 | 374 | | rightStart.Z); |
| | | 375 | | |
| | | 376 | | private static void GetPointLocalNumerators( |
| | | 377 | | in FixedPointAnchor point, |
| | | 378 | | Vector3d frameOrigin, |
| | | 379 | | FixedQuaternion frameRotation, |
| | | 380 | | out Signed576 x, |
| | | 381 | | out Signed576 y, |
| | | 382 | | out Signed576 z, |
| | | 383 | | out Signed320 denominator) |
| | | 384 | | { |
| | 450 | 385 | | WideRationalBasis3d pointBasis = new(point.Rotation); |
| | 450 | 386 | | WideRationalBasis3d frameBasis = new(frameRotation); |
| | 450 | 387 | | denominator = WideArithmetic.MultiplySigned192( |
| | 450 | 388 | | pointBasis.Denominator, |
| | 450 | 389 | | frameBasis.Denominator); |
| | 450 | 390 | | Signed192 originX = WideArithmetic.SubtractSigned192( |
| | 450 | 391 | | Signed192.Raw(point.Origin.X), |
| | 450 | 392 | | Signed192.Raw(frameOrigin.X)); |
| | 450 | 393 | | Signed192 originY = WideArithmetic.SubtractSigned192( |
| | 450 | 394 | | Signed192.Raw(point.Origin.Y), |
| | 450 | 395 | | Signed192.Raw(frameOrigin.Y)); |
| | 450 | 396 | | Signed192 originZ = WideArithmetic.SubtractSigned192( |
| | 450 | 397 | | Signed192.Raw(point.Origin.Z), |
| | 450 | 398 | | Signed192.Raw(frameOrigin.Z)); |
| | 450 | 399 | | Signed320 rotatedX = GetTriangleRotatedPointCoordinate( |
| | 450 | 400 | | point, |
| | 450 | 401 | | pointBasis.Xx, |
| | 450 | 402 | | pointBasis.Yx, |
| | 450 | 403 | | pointBasis.Zx); |
| | 450 | 404 | | Signed320 rotatedY = GetTriangleRotatedPointCoordinate( |
| | 450 | 405 | | point, |
| | 450 | 406 | | pointBasis.Xy, |
| | 450 | 407 | | pointBasis.Yy, |
| | 450 | 408 | | pointBasis.Zy); |
| | 450 | 409 | | Signed320 rotatedZ = GetTriangleRotatedPointCoordinate( |
| | 450 | 410 | | point, |
| | 450 | 411 | | pointBasis.Xz, |
| | 450 | 412 | | pointBasis.Yz, |
| | 450 | 413 | | pointBasis.Zz); |
| | 450 | 414 | | x = GetTriangleFrameCoordinateNumerator( |
| | 450 | 415 | | originX, |
| | 450 | 416 | | originY, |
| | 450 | 417 | | originZ, |
| | 450 | 418 | | rotatedX, |
| | 450 | 419 | | rotatedY, |
| | 450 | 420 | | rotatedZ, |
| | 450 | 421 | | pointBasis.Denominator, |
| | 450 | 422 | | frameBasis.Xx, |
| | 450 | 423 | | frameBasis.Xy, |
| | 450 | 424 | | frameBasis.Xz); |
| | 450 | 425 | | y = GetTriangleFrameCoordinateNumerator( |
| | 450 | 426 | | originX, |
| | 450 | 427 | | originY, |
| | 450 | 428 | | originZ, |
| | 450 | 429 | | rotatedX, |
| | 450 | 430 | | rotatedY, |
| | 450 | 431 | | rotatedZ, |
| | 450 | 432 | | pointBasis.Denominator, |
| | 450 | 433 | | frameBasis.Yx, |
| | 450 | 434 | | frameBasis.Yy, |
| | 450 | 435 | | frameBasis.Yz); |
| | 450 | 436 | | z = GetTriangleFrameCoordinateNumerator( |
| | 450 | 437 | | originX, |
| | 450 | 438 | | originY, |
| | 450 | 439 | | originZ, |
| | 450 | 440 | | rotatedX, |
| | 450 | 441 | | rotatedY, |
| | 450 | 442 | | rotatedZ, |
| | 450 | 443 | | pointBasis.Denominator, |
| | 450 | 444 | | frameBasis.Zx, |
| | 450 | 445 | | frameBasis.Zy, |
| | 450 | 446 | | frameBasis.Zz); |
| | 450 | 447 | | } |
| | | 448 | | |
| | | 449 | | private static Signed320 GetTriangleRotatedPointCoordinate( |
| | | 450 | | in FixedPointAnchor point, |
| | | 451 | | Signed192 axisX, |
| | | 452 | | Signed192 axisY, |
| | | 453 | | Signed192 axisZ) => |
| | 1350 | 454 | | WideArithmetic.AddSigned320( |
| | 1350 | 455 | | WideArithmetic.GetDotProduct3D( |
| | 1350 | 456 | | Signed192.Raw(point.LocalPoint.X), |
| | 1350 | 457 | | Signed192.Raw(point.LocalPoint.Y), |
| | 1350 | 458 | | Signed192.Raw(point.LocalPoint.Z), |
| | 1350 | 459 | | axisX, |
| | 1350 | 460 | | axisY, |
| | 1350 | 461 | | axisZ), |
| | 1350 | 462 | | WideArithmetic.GetDotProduct3D( |
| | 1350 | 463 | | Signed192.Raw(point.LocalDisplacement.X), |
| | 1350 | 464 | | Signed192.Raw(point.LocalDisplacement.Y), |
| | 1350 | 465 | | Signed192.Raw(point.LocalDisplacement.Z), |
| | 1350 | 466 | | axisX, |
| | 1350 | 467 | | axisY, |
| | 1350 | 468 | | axisZ)); |
| | | 469 | | |
| | | 470 | | private static Signed576 GetTriangleFrameCoordinateNumerator( |
| | | 471 | | Signed192 originX, |
| | | 472 | | Signed192 originY, |
| | | 473 | | Signed192 originZ, |
| | | 474 | | Signed320 rotatedX, |
| | | 475 | | Signed320 rotatedY, |
| | | 476 | | Signed320 rotatedZ, |
| | | 477 | | Signed192 pointDenominator, |
| | | 478 | | Signed192 frameAxisX, |
| | | 479 | | Signed192 frameAxisY, |
| | | 480 | | Signed192 frameAxisZ) |
| | | 481 | | { |
| | 1350 | 482 | | Signed320 originProjection = WideArithmetic.GetDotProduct3D( |
| | 1350 | 483 | | originX, |
| | 1350 | 484 | | originY, |
| | 1350 | 485 | | originZ, |
| | 1350 | 486 | | frameAxisX, |
| | 1350 | 487 | | frameAxisY, |
| | 1350 | 488 | | frameAxisZ); |
| | 1350 | 489 | | Signed576 rotatedProjection = WideArithmetic.AddSigned576( |
| | 1350 | 490 | | WideArithmetic.AddSigned576( |
| | 1350 | 491 | | WideArithmetic.MultiplySigned320( |
| | 1350 | 492 | | rotatedX, |
| | 1350 | 493 | | Signed320.ExtendValue(frameAxisX)), |
| | 1350 | 494 | | WideArithmetic.MultiplySigned320( |
| | 1350 | 495 | | rotatedY, |
| | 1350 | 496 | | Signed320.ExtendValue(frameAxisY))), |
| | 1350 | 497 | | WideArithmetic.MultiplySigned320( |
| | 1350 | 498 | | rotatedZ, |
| | 1350 | 499 | | Signed320.ExtendValue(frameAxisZ))); |
| | 1350 | 500 | | return WideArithmetic.AddSigned576( |
| | 1350 | 501 | | WideArithmetic.MultiplySigned320( |
| | 1350 | 502 | | originProjection, |
| | 1350 | 503 | | Signed320.ExtendValue(pointDenominator)), |
| | 1350 | 504 | | rotatedProjection); |
| | | 505 | | } |
| | | 506 | | } |