@itwin/core-geometry 3.6.0-dev.8 → 4.0.0-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -1
- package/LICENSE.md +1 -1
- package/lib/cjs/Geometry.d.ts +28 -17
- package/lib/cjs/Geometry.d.ts.map +1 -1
- package/lib/cjs/Geometry.js +52 -25
- package/lib/cjs/Geometry.js.map +1 -1
- package/lib/cjs/curve/CurveChainWithDistanceIndex.d.ts +10 -6
- package/lib/cjs/curve/CurveChainWithDistanceIndex.d.ts.map +1 -1
- package/lib/cjs/curve/CurveChainWithDistanceIndex.js +29 -31
- package/lib/cjs/curve/CurveChainWithDistanceIndex.js.map +1 -1
- package/lib/cjs/curve/CurveCurve.d.ts +11 -8
- package/lib/cjs/curve/CurveCurve.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCurve.js +16 -12
- package/lib/cjs/curve/CurveCurve.js.map +1 -1
- package/lib/cjs/curve/CurveCurveIntersectXY.d.ts +5 -1
- package/lib/cjs/curve/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCurveIntersectXY.js +11 -10
- package/lib/cjs/curve/CurveCurveIntersectXY.js.map +1 -1
- package/lib/cjs/geometry3d/Angle.d.ts +19 -0
- package/lib/cjs/geometry3d/Angle.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Angle.js +39 -0
- package/lib/cjs/geometry3d/Angle.js.map +1 -1
- package/lib/cjs/geometry3d/AngleSweep.d.ts +1 -0
- package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
- package/lib/cjs/geometry3d/AngleSweep.js +1 -0
- package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
- package/lib/cjs/geometry3d/CoincidentGeometryOps.d.ts +1 -0
- package/lib/cjs/geometry3d/CoincidentGeometryOps.d.ts.map +1 -1
- package/lib/cjs/geometry3d/CoincidentGeometryOps.js +3 -0
- package/lib/cjs/geometry3d/CoincidentGeometryOps.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYArray.d.ts +1 -1
- package/lib/cjs/geometry3d/GrowableXYArray.js +1 -1
- package/lib/cjs/geometry3d/GrowableXYArray.js.map +1 -1
- package/lib/cjs/geometry3d/Matrix3d.d.ts +369 -254
- package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Matrix3d.js +807 -660
- package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
- package/lib/cjs/geometry3d/OrderedRotationAngles.d.ts +71 -14
- package/lib/cjs/geometry3d/OrderedRotationAngles.d.ts.map +1 -1
- package/lib/cjs/geometry3d/OrderedRotationAngles.js +204 -114
- package/lib/cjs/geometry3d/OrderedRotationAngles.js.map +1 -1
- package/lib/cjs/geometry3d/Point2dVector2d.d.ts +1 -0
- package/lib/cjs/geometry3d/Point2dVector2d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Point2dVector2d.js +1 -0
- package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
- package/lib/cjs/geometry3d/Point3dVector3d.d.ts +16 -16
- package/lib/cjs/geometry3d/Point3dVector3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Point3dVector3d.js +21 -18
- package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/cjs/geometry3d/Segment1d.d.ts +1 -1
- package/lib/cjs/geometry3d/Segment1d.js +1 -1
- package/lib/cjs/geometry3d/Segment1d.js.map +1 -1
- package/lib/cjs/geometry3d/YawPitchRollAngles.d.ts +49 -25
- package/lib/cjs/geometry3d/YawPitchRollAngles.d.ts.map +1 -1
- package/lib/cjs/geometry3d/YawPitchRollAngles.js +146 -50
- package/lib/cjs/geometry3d/YawPitchRollAngles.js.map +1 -1
- package/lib/cjs/numerics/Polynomials.d.ts +12 -0
- package/lib/cjs/numerics/Polynomials.d.ts.map +1 -1
- package/lib/cjs/numerics/Polynomials.js +14 -0
- package/lib/cjs/numerics/Polynomials.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.d.ts +5 -4
- package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.js +50 -10
- package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceQuery.d.ts +82 -0
- package/lib/cjs/polyface/PolyfaceQuery.d.ts.map +1 -1
- package/lib/cjs/polyface/PolyfaceQuery.js +150 -1
- package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
- package/lib/cjs/polyface/multiclip/OffsetMeshContext.d.ts +202 -0
- package/lib/cjs/polyface/multiclip/OffsetMeshContext.d.ts.map +1 -0
- package/lib/cjs/polyface/multiclip/OffsetMeshContext.js +1038 -0
- package/lib/cjs/polyface/multiclip/OffsetMeshContext.js.map +1 -0
- package/lib/cjs/serialization/GeometrySamples.d.ts +4 -1
- package/lib/cjs/serialization/GeometrySamples.d.ts.map +1 -1
- package/lib/cjs/serialization/GeometrySamples.js +14 -6
- package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
- package/lib/cjs/serialization/IModelJsonSchema.d.ts +1 -1
- package/lib/cjs/serialization/IModelJsonSchema.js.map +1 -1
- package/lib/cjs/topology/Graph.d.ts +113 -7
- package/lib/cjs/topology/Graph.d.ts.map +1 -1
- package/lib/cjs/topology/Graph.js +185 -7
- package/lib/cjs/topology/Graph.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts +38 -0
- package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts.map +1 -0
- package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js +82 -0
- package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -0
- package/lib/esm/Geometry.d.ts +28 -17
- package/lib/esm/Geometry.d.ts.map +1 -1
- package/lib/esm/Geometry.js +52 -25
- package/lib/esm/Geometry.js.map +1 -1
- package/lib/esm/curve/CurveChainWithDistanceIndex.d.ts +10 -6
- package/lib/esm/curve/CurveChainWithDistanceIndex.d.ts.map +1 -1
- package/lib/esm/curve/CurveChainWithDistanceIndex.js +30 -32
- package/lib/esm/curve/CurveChainWithDistanceIndex.js.map +1 -1
- package/lib/esm/curve/CurveCurve.d.ts +11 -8
- package/lib/esm/curve/CurveCurve.d.ts.map +1 -1
- package/lib/esm/curve/CurveCurve.js +16 -12
- package/lib/esm/curve/CurveCurve.js.map +1 -1
- package/lib/esm/curve/CurveCurveIntersectXY.d.ts +5 -1
- package/lib/esm/curve/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/esm/curve/CurveCurveIntersectXY.js +11 -10
- package/lib/esm/curve/CurveCurveIntersectXY.js.map +1 -1
- package/lib/esm/geometry3d/Angle.d.ts +19 -0
- package/lib/esm/geometry3d/Angle.d.ts.map +1 -1
- package/lib/esm/geometry3d/Angle.js +39 -0
- package/lib/esm/geometry3d/Angle.js.map +1 -1
- package/lib/esm/geometry3d/AngleSweep.d.ts +1 -0
- package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
- package/lib/esm/geometry3d/AngleSweep.js +1 -0
- package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
- package/lib/esm/geometry3d/CoincidentGeometryOps.d.ts +1 -0
- package/lib/esm/geometry3d/CoincidentGeometryOps.d.ts.map +1 -1
- package/lib/esm/geometry3d/CoincidentGeometryOps.js +3 -0
- package/lib/esm/geometry3d/CoincidentGeometryOps.js.map +1 -1
- package/lib/esm/geometry3d/GrowableXYArray.d.ts +1 -1
- package/lib/esm/geometry3d/GrowableXYArray.js +1 -1
- package/lib/esm/geometry3d/GrowableXYArray.js.map +1 -1
- package/lib/esm/geometry3d/Matrix3d.d.ts +369 -254
- package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Matrix3d.js +807 -660
- package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
- package/lib/esm/geometry3d/OrderedRotationAngles.d.ts +71 -14
- package/lib/esm/geometry3d/OrderedRotationAngles.d.ts.map +1 -1
- package/lib/esm/geometry3d/OrderedRotationAngles.js +205 -115
- package/lib/esm/geometry3d/OrderedRotationAngles.js.map +1 -1
- package/lib/esm/geometry3d/Point2dVector2d.d.ts +1 -0
- package/lib/esm/geometry3d/Point2dVector2d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Point2dVector2d.js +1 -0
- package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
- package/lib/esm/geometry3d/Point3dVector3d.d.ts +16 -16
- package/lib/esm/geometry3d/Point3dVector3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Point3dVector3d.js +21 -18
- package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/esm/geometry3d/Segment1d.d.ts +1 -1
- package/lib/esm/geometry3d/Segment1d.js +1 -1
- package/lib/esm/geometry3d/Segment1d.js.map +1 -1
- package/lib/esm/geometry3d/YawPitchRollAngles.d.ts +49 -25
- package/lib/esm/geometry3d/YawPitchRollAngles.d.ts.map +1 -1
- package/lib/esm/geometry3d/YawPitchRollAngles.js +146 -50
- package/lib/esm/geometry3d/YawPitchRollAngles.js.map +1 -1
- package/lib/esm/numerics/Polynomials.d.ts +12 -0
- package/lib/esm/numerics/Polynomials.d.ts.map +1 -1
- package/lib/esm/numerics/Polynomials.js +14 -0
- package/lib/esm/numerics/Polynomials.js.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.d.ts +5 -4
- package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.js +50 -10
- package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/esm/polyface/PolyfaceQuery.d.ts +82 -0
- package/lib/esm/polyface/PolyfaceQuery.d.ts.map +1 -1
- package/lib/esm/polyface/PolyfaceQuery.js +148 -0
- package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
- package/lib/esm/polyface/multiclip/OffsetMeshContext.d.ts +202 -0
- package/lib/esm/polyface/multiclip/OffsetMeshContext.d.ts.map +1 -0
- package/lib/esm/polyface/multiclip/OffsetMeshContext.js +1032 -0
- package/lib/esm/polyface/multiclip/OffsetMeshContext.js.map +1 -0
- package/lib/esm/serialization/GeometrySamples.d.ts +4 -1
- package/lib/esm/serialization/GeometrySamples.d.ts.map +1 -1
- package/lib/esm/serialization/GeometrySamples.js +14 -6
- package/lib/esm/serialization/GeometrySamples.js.map +1 -1
- package/lib/esm/serialization/IModelJsonSchema.d.ts +1 -1
- package/lib/esm/serialization/IModelJsonSchema.js.map +1 -1
- package/lib/esm/topology/Graph.d.ts +113 -7
- package/lib/esm/topology/Graph.d.ts.map +1 -1
- package/lib/esm/topology/Graph.js +185 -7
- package/lib/esm/topology/Graph.js.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts +38 -0
- package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts.map +1 -0
- package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js +78 -0
- package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Segment1d.js","sourceRoot":"","sources":["../../../src/geometry3d/Segment1d.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module CartesianGeometry\r\n */\r\n\r\nimport { Geometry } from \"../Geometry\";\r\n\r\n/**\r\n * * A Segment1d is an interval of an axis named x.\r\n * * The interval is defined by two values x0 and x1.\r\n * * The x0 and x1 values can be in either order.\r\n * * if `x0 < x1` fractional coordinates within the segment move from left to right.\r\n * * if `x0 > x1` fractional coordinates within the segment move from right to left.\r\n * * This differs from a Range1d in that:\r\n * * For a Range1d the reversed ordering of its limit values means \"empty interval\".\r\n * * For a Segment1d the reversed ordering is a real interval but fractional positions move backwards.\r\n * * The segment is parameterized with a fraction\r\n * * * Fraction 0 is the start (`x0`)\r\n * * * Fraction 1 is the end (`x1`)\r\n * * * The fraction equation is `x = x0 + fraction * (x1-x0)` or (equivalently) `x = (1-fraction) * x0 + fraction * x1`\r\n * @public\r\n */\r\nexport class Segment1d {\r\n /** start coordinate */\r\n public x0: number;\r\n /** end coordinate */\r\n public x1: number;\r\n private constructor(x0: number, x1: number) {\r\n this.x0 = x0;\r\n this.x1 = x1;\r\n }\r\n /**\r\n * replace both end values.\r\n * @param x0 new x0 value\r\n * @param x1 new y0 value\r\n */\r\n public set(x0: number, x1: number) { this.x0 = x0, this.x1 = x1; }\r\n /**\r\n * shift (translate) the segment along its axis by adding `dx` to both `x0` and `x1`.\r\n * @param dx value to add to both x0 and x1\r\n */\r\n public shift(dx: number) { this.x0 += dx, this.x1 += dx; }\r\n /**\r\n * create segment1d with given end values\r\n * @param x0 start value\r\n * @param x1 end value\r\n * @param result optional pre-existing result to be reinitialized.\r\n */\r\n public static create(x0: number = 0, x1: number = 1, result?: Segment1d): Segment1d {\r\n if (!result)\r\n return new Segment1d(x0, x1);\r\n result.set(x0, x1);\r\n return result;\r\n }\r\n /**\r\n * Copy both end values from other Segment1d\r\n * @param other source Segment1d\r\n */\r\n public setFrom(other: Segment1d) { this.x0 = other.x0; this.x1 = other.x1; }\r\n /**\r\n * clone this Segment1d, return as a separate object.\r\n */\r\n public clone(): Segment1d { return new Segment1d(this.x0, this.x1); }\r\n /**\r\n * Returns true if both coordinates (`x0` and `x1`) are in the 0..1 range.\r\n */\r\n public get isIn01() {\r\n return Geometry.isIn01(this.x0) && Geometry.isIn01(this.x1);\r\n\r\n }\r\n /**\r\n * Evaluate the segment at fractional position\r\n * @returns position within the segment\r\n * @param fraction fractional position within this segment\r\n */\r\n public fractionToPoint(fraction: number): number { return Geometry.interpolate(this.x0, fraction, this.x1); }\r\n /**\r\n * Return the signed start-to-end shift (aka signed distance)\r\n */\r\n public signedDelta(): number { return this.x1 - this.x0; }\r\n /**\r\n * Return the absolute start-to-end shift (aka distance)\r\n */\r\n public absoluteDelta(): number { return Math.abs(this.x1 - this.x0); }\r\n /**\r\n * * swap the x0 and x1 member values.\r\n * * This makes the fractionToPoint evaluates reverse direction.\r\n */\r\n public reverseInPlace(): void { const x = this.x0; this.x0 = this.x1; this.x1 = x; }\r\n /**\r\n * * if `x1<x0` multiplied by the scale factor is (strictly) negative, swap the x0 and x1 member values.\r\n * * This makes the fractionToPoint evaluates reverse direction.\r\n */\r\n public reverseIfNeededForDeltaSign(sign: number = 1): void {\r\n if (sign * (this.x1 - this.x0) < 0)\r\n this.reverseInPlace();\r\n }\r\n /**\r\n * Near equality test, using Geometry.isSameCoordinate for tolerances.\r\n */\r\n public isAlmostEqual(other: Segment1d): boolean {\r\n return Geometry.isSameCoordinate(this.x0, other.x0) && Geometry.isSameCoordinate(this.x1, other.x1);\r\n }\r\n /**\r\n * Return true if the segment limits are (exactly) 0 and 1\r\n */\r\n public get isExact01(): boolean { return this.x0 === 0.0 && this.x1 === 1.0; }\r\n /**\r\n * Return true if the segment limits are (exactly) 1 and 0\r\n */\r\n public get isExact01Reversed(): boolean { return this.x0 === 1.0 && this.x1 === 0.0; }\r\n\r\n /** On input, `this` is an interval of a line. On output, the interval has been clipped to positive parts of a linear function\r\n * * f0 and f1 are values at parameter values 0 and 1 (which are in general NOT x0 and x1)\r\n * * From that determine where the segment crosses function value 0.\r\n * * The segment contains some interval in the same parameter space.\r\n * * Clip the segment to the positive part of the space.\r\n * * Return true (and modify the segment) if any of the segment remains.\r\n * * Return false (but without modifying the segment) if the active part is entirely out.\r\n */\r\n public clipBy01FunctionValuesPositive(f0: number, f1: number): boolean {\r\n const df01 = f1 - f0;\r\n const fA = f0 + this.x0 * df01;\r\n const fB = f0 + this.x1 * df01;\r\n const dfAB = fB - fA;\r\n if (fA > 0) {\r\n if (fB >= 0) return true; // inside at both ends\r\n /** There is an inside to outside crossing. The division is safe ... (and value between 0 and 1) */\r\n const u = -fA / dfAB;\r\n this.x1 = this.x0 + u * (this.x1 - this.x0);\r\n return true;\r\n } else if (fA < 0) {\r\n if (fB < 0) return false; // outside at both ends.\r\n /** There is an outside to inside crossing crossing. The division is safe ... (and value between 0 and 1) */\r\n const u = -fA / dfAB;\r\n this.x0 = this.x0 + u * (this.x1 - this.x0);\r\n return true;\r\n }\r\n /** fA is on the cut. fB determines the entire segment. */\r\n return fB > 0;\r\n }\r\n /**\r\n * * On input, (f0,f1) is a (directed) segment.\r\n * * On output, it is restricted to (0,1) while maintaining direction\r\n * * If the clip leaves nothing, leave this segment alone and return false.\r\n * * If the clip leaves something, update this segment and return true.\r\n */\r\n public clampDirectedTo01(): boolean {\r\n let x0 = this.x0;\r\n let x1 = this.x1;\r\n if (x1 > x0) {\r\n if (x0 < 0) x0 = 0;\r\n if (x1 > 1) x1 = 1;\r\n if (x0 >= x1)\r\n return false;\r\n } else {\r\n if (x0 > 1) x0 = 1;\r\n if (x1 < 0) x1 = 0;\r\n if (x0 <= x1)\r\n return false;\r\n }\r\n this.set(x0, x1);\r\n return true;\r\n }\r\n\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"Segment1d.js","sourceRoot":"","sources":["../../../src/geometry3d/Segment1d.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,SAAS;IAKpB,YAAoB,EAAU,EAAE,EAAU;QACxC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IACD;;;;OAIG;IACI,GAAG,CAAC,EAAU,EAAE,EAAU,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAClE;;;OAGG;IACI,KAAK,CAAC,EAAU,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1D;;;;;OAKG;IACI,MAAM,CAAC,MAAM,CAAC,KAAa,CAAC,EAAE,KAAa,CAAC,EAAE,MAAkB;QACrE,IAAI,CAAC,MAAM;YACT,OAAO,IAAI,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD;;;OAGG;IACI,OAAO,CAAC,KAAgB,IAAI,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5E;;OAEG;IACI,KAAK,KAAgB,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE;;OAEG;IACH,IAAW,MAAM;QACf,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE9D,CAAC;IACD;;;;OAIG;IACI,eAAe,CAAC,QAAgB,IAAY,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7G;;OAEG;IACI,WAAW,KAAa,OAAO,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D;;OAEG;IACI,aAAa,KAAa,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACtE;;;OAGG;IACI,cAAc,KAAW,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACpF;;;OAGG;IACI,2BAA2B,CAAC,OAAe,CAAC;QACjD,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;YAChC,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IACD;;OAEG;IACI,aAAa,CAAC,KAAgB;QACnC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACtG,CAAC;IACD;;OAEG;IACH,IAAW,SAAS,KAAc,OAAO,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9E;;OAEG;IACH,IAAW,iBAAiB,KAAc,OAAO,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAEtF;;;;;;;OAOG;IACI,8BAA8B,CAAC,EAAU,EAAE,EAAU;QAC1D,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;QACrB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QAC/B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QAC/B,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;QACrB,IAAI,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,sBAAsB;YAChD,mGAAmG;YACnG,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;SACb;aAAM,IAAI,EAAE,GAAG,CAAC,EAAE;YACjB,IAAI,EAAE,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC,CAAG,wBAAwB;YACpD,4GAA4G;YAC5G,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;SACb;QACD,4DAA4D;QAC5D,OAAO,EAAE,GAAG,CAAC,CAAC;IAChB,CAAC;IACD;;;;;OAKG;IACI,iBAAiB;QACtB,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACjB,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACjB,IAAI,EAAE,GAAG,EAAE,EAAE;YACX,IAAI,EAAE,GAAG,CAAC;gBAAE,EAAE,GAAG,CAAC,CAAC;YACnB,IAAI,EAAE,GAAG,CAAC;gBAAE,EAAE,GAAG,CAAC,CAAC;YACnB,IAAI,EAAE,IAAI,EAAE;gBACV,OAAO,KAAK,CAAC;SAChB;aAAM;YACL,IAAI,EAAE,GAAG,CAAC;gBAAE,EAAE,GAAG,CAAC,CAAC;YACnB,IAAI,EAAE,GAAG,CAAC;gBAAE,EAAE,GAAG,CAAC,CAAC;YACnB,IAAI,EAAE,IAAI,EAAE;gBACV,OAAO,KAAK,CAAC;SAChB;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CAEF","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module CartesianGeometry\r\n */\r\n\r\nimport { Geometry } from \"../Geometry\";\r\n\r\n/**\r\n * * A Segment1d is an interval of an axis named x.\r\n * * The interval is defined by two values x0 and x1.\r\n * * The x0 and x1 values can be in either order.\r\n * * if `x0 < x1` fractional coordinates within the segment move from left to right.\r\n * * if `x0 > x1` fractional coordinates within the segment move from right to left.\r\n * * This differs from a Range1d in that:\r\n * * For a Range1d the reversed ordering of its limit values means \"empty interval\".\r\n * * For a Segment1d the reversed ordering is a real interval but fractional positions move backwards.\r\n * * The segment is parameterized with a fraction\r\n * * * Fraction 0 is the start (`x0`)\r\n * * * Fraction 1 is the end (`x1`)\r\n * * * The fraction equation is `x = x0 + fraction * (x1-x0)` or (equivalently) `x = (1-fraction) * x0 + fraction * x1`\r\n * @public\r\n */\r\nexport class Segment1d {\r\n /** start coordinate */\r\n public x0: number;\r\n /** end coordinate */\r\n public x1: number;\r\n private constructor(x0: number, x1: number) {\r\n this.x0 = x0;\r\n this.x1 = x1;\r\n }\r\n /**\r\n * replace both end values.\r\n * @param x0 new x0 value\r\n * @param x1 new y0 value\r\n */\r\n public set(x0: number, x1: number) { this.x0 = x0, this.x1 = x1; }\r\n /**\r\n * shift (translate) the segment along its axis by adding `dx` to both `x0` and `x1`.\r\n * @param dx value to add to both x0 and x1\r\n */\r\n public shift(dx: number) { this.x0 += dx, this.x1 += dx; }\r\n /**\r\n * create segment1d with given end values\r\n * @param x0 start value\r\n * @param x1 end value\r\n * @param result optional pre-existing result to be reinitialized.\r\n */\r\n public static create(x0: number = 0, x1: number = 1, result?: Segment1d): Segment1d {\r\n if (!result)\r\n return new Segment1d(x0, x1);\r\n result.set(x0, x1);\r\n return result;\r\n }\r\n /**\r\n * Copy both end values from other Segment1d\r\n * @param other source Segment1d\r\n */\r\n public setFrom(other: Segment1d) { this.x0 = other.x0; this.x1 = other.x1; }\r\n /**\r\n * clone this Segment1d, return as a separate object.\r\n */\r\n public clone(): Segment1d { return new Segment1d(this.x0, this.x1); }\r\n /**\r\n * Returns true if both coordinates (`x0` and `x1`) are in the 0..1 range.\r\n */\r\n public get isIn01() {\r\n return Geometry.isIn01(this.x0) && Geometry.isIn01(this.x1);\r\n\r\n }\r\n /**\r\n * Evaluate the segment at fractional position\r\n * @returns position within the segment\r\n * @param fraction fractional position within this segment\r\n */\r\n public fractionToPoint(fraction: number): number { return Geometry.interpolate(this.x0, fraction, this.x1); }\r\n /**\r\n * Return the signed start-to-end shift (aka signed distance)\r\n */\r\n public signedDelta(): number { return this.x1 - this.x0; }\r\n /**\r\n * Return the absolute start-to-end shift (aka distance)\r\n */\r\n public absoluteDelta(): number { return Math.abs(this.x1 - this.x0); }\r\n /**\r\n * * swap the x0 and x1 member values.\r\n * * This makes the fractionToPoint evaluates reverse direction.\r\n */\r\n public reverseInPlace(): void { const x = this.x0; this.x0 = this.x1; this.x1 = x; }\r\n /**\r\n * * if `x1-x0` multiplied by the scale factor is (strictly) negative, swap the x0 and x1 member values.\r\n * * This makes the fractionToPoint evaluates reverse direction.\r\n */\r\n public reverseIfNeededForDeltaSign(sign: number = 1): void {\r\n if (sign * (this.x1 - this.x0) < 0)\r\n this.reverseInPlace();\r\n }\r\n /**\r\n * Near equality test, using Geometry.isSameCoordinate for tolerances.\r\n */\r\n public isAlmostEqual(other: Segment1d): boolean {\r\n return Geometry.isSameCoordinate(this.x0, other.x0) && Geometry.isSameCoordinate(this.x1, other.x1);\r\n }\r\n /**\r\n * Return true if the segment limits are (exactly) 0 and 1\r\n */\r\n public get isExact01(): boolean { return this.x0 === 0.0 && this.x1 === 1.0; }\r\n /**\r\n * Return true if the segment limits are (exactly) 1 and 0\r\n */\r\n public get isExact01Reversed(): boolean { return this.x0 === 1.0 && this.x1 === 0.0; }\r\n\r\n /** On input, `this` is an interval of a line. On output, the interval has been clipped to positive parts of a linear function\r\n * * f0 and f1 are values at parameter values 0 and 1 (which are in general NOT x0 and x1)\r\n * * From that determine where the segment crosses function value 0.\r\n * * The segment contains some interval in the same parameter space.\r\n * * Clip the segment to the positive part of the space.\r\n * * Return true (and modify the segment) if any of the segment remains.\r\n * * Return false (but without modifying the segment) if the active part is entirely out.\r\n */\r\n public clipBy01FunctionValuesPositive(f0: number, f1: number): boolean {\r\n const df01 = f1 - f0;\r\n const fA = f0 + this.x0 * df01;\r\n const fB = f0 + this.x1 * df01;\r\n const dfAB = fB - fA;\r\n if (fA > 0) {\r\n if (fB >= 0) return true; // inside at both ends\r\n /** There is an inside to outside crossing. The division is safe ... (and value between 0 and 1) */\r\n const u = -fA / dfAB;\r\n this.x1 = this.x0 + u * (this.x1 - this.x0);\r\n return true;\r\n } else if (fA < 0) {\r\n if (fB < 0) return false; // outside at both ends.\r\n /** There is an outside to inside crossing crossing. The division is safe ... (and value between 0 and 1) */\r\n const u = -fA / dfAB;\r\n this.x0 = this.x0 + u * (this.x1 - this.x0);\r\n return true;\r\n }\r\n /** fA is on the cut. fB determines the entire segment. */\r\n return fB > 0;\r\n }\r\n /**\r\n * * On input, (f0,f1) is a (directed) segment.\r\n * * On output, it is restricted to (0,1) while maintaining direction\r\n * * If the clip leaves nothing, leave this segment alone and return false.\r\n * * If the clip leaves something, update this segment and return true.\r\n */\r\n public clampDirectedTo01(): boolean {\r\n let x0 = this.x0;\r\n let x1 = this.x1;\r\n if (x1 > x0) {\r\n if (x0 < 0) x0 = 0;\r\n if (x1 > 1) x1 = 1;\r\n if (x0 >= x1)\r\n return false;\r\n } else {\r\n if (x0 > 1) x0 = 1;\r\n if (x1 < 0) x1 = 0;\r\n if (x0 <= x1)\r\n return false;\r\n }\r\n this.set(x0, x1);\r\n return true;\r\n }\r\n\r\n}\r\n"]}
|
|
@@ -6,7 +6,6 @@ import { Angle } from "./Angle";
|
|
|
6
6
|
import { Matrix3d } from "./Matrix3d";
|
|
7
7
|
import { Point3d } from "./Point3dVector3d";
|
|
8
8
|
import { Transform } from "./Transform";
|
|
9
|
-
/** The properties that define [[YawPitchRollAngles]]. */
|
|
10
9
|
/**
|
|
11
10
|
* angle properties of a `YawPitchRoll` orientation
|
|
12
11
|
* @public
|
|
@@ -19,44 +18,66 @@ export interface YawPitchRollProps {
|
|
|
19
18
|
/** roll field */
|
|
20
19
|
roll?: AngleProps;
|
|
21
20
|
}
|
|
22
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Three angles that determine the orientation of an object in space, sometimes referred to as [Tait–Bryan angles]
|
|
23
|
+
* (https://en.wikipedia.org/wiki/Euler_angles).
|
|
23
24
|
* * The matrix construction can be replicated by this logic:
|
|
24
25
|
* * xyz coordinates have
|
|
25
26
|
* * x forward
|
|
26
27
|
* * y to left
|
|
27
28
|
* * z up
|
|
28
|
-
*
|
|
29
|
-
*
|
|
29
|
+
* * Note that this is a right handed coordinate system.
|
|
30
|
+
* * yaw is a rotation of x towards y, i.e. around positive z (counterclockwise):
|
|
30
31
|
* * `yawMatrix = Matrix3d.createRotationAroundAxisIndex(2, Angle.createDegrees(yawDegrees));`
|
|
31
|
-
*
|
|
32
|
+
* * pitch is a rotation that raises x towards z, i.e. rotation around **negative y** (**clockwise**):
|
|
32
33
|
* * `pitchMatrix = Matrix3d.createRotationAroundAxisIndex(1, Angle.createDegrees(-pitchDegrees));`
|
|
33
|
-
*
|
|
34
|
+
* * roll is rotation of y towards z, i.e. rotation around positive x (counterclockwise):
|
|
34
35
|
* * `rollMatrix = Matrix3d.createRotationAroundAxisIndex(0, Angle.createDegrees(rollDegrees));`
|
|
35
|
-
*
|
|
36
|
+
* * The YPR matrix is the product
|
|
36
37
|
* * `result = yawMatrix.multiplyMatrixMatrix(pitchMatrix.multiplyMatrixMatrix(rollMatrix));`
|
|
37
|
-
*
|
|
38
|
-
*
|
|
38
|
+
* * Note that this is for "column based" matrix with vectors multiplying on the right of the matrix.
|
|
39
|
+
* Hence a vector is first rotated by roll, then the pitch, finally yaw. So multiplication order in
|
|
40
|
+
* the sense of AxisOrder is `RPY` (i.e., XYZ), in contrast to the familiar name `YPR`.
|
|
39
41
|
* @public
|
|
40
42
|
*/
|
|
41
43
|
export declare class YawPitchRollAngles {
|
|
42
|
-
/** The yaw angle
|
|
44
|
+
/** The yaw angle: counterclockwise rotation angle around z */
|
|
43
45
|
yaw: Angle;
|
|
44
|
-
/** The pitch angle
|
|
46
|
+
/** The pitch angle: **clockwise** rotation angle around y */
|
|
45
47
|
pitch: Angle;
|
|
46
|
-
/** The roll angle
|
|
48
|
+
/** The roll angle: counterclockwise rotation angle around x */
|
|
47
49
|
roll: Angle;
|
|
50
|
+
/**
|
|
51
|
+
* constructor
|
|
52
|
+
* @param yaw counterclockwise rotation angle around z
|
|
53
|
+
* @param pitch **clockwise** rotation angle around y
|
|
54
|
+
* @param roll counterclockwise rotation angle around x
|
|
55
|
+
* */
|
|
48
56
|
constructor(yaw?: Angle, pitch?: Angle, roll?: Angle);
|
|
49
57
|
/** Freeze this YawPitchRollAngles */
|
|
50
58
|
freeze(): Readonly<this>;
|
|
51
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* constructor for YawPitchRollAngles with angles in degrees.
|
|
61
|
+
* @param yawDegrees counterclockwise rotation angle (in degrees) around z
|
|
62
|
+
* @param pitchDegrees **clockwise** rotation angle (in degrees) around y
|
|
63
|
+
* @param rollDegrees counterclockwise rotation angle (in degrees) around x
|
|
64
|
+
* */
|
|
52
65
|
static createDegrees(yawDegrees: number, pitchDegrees: number, rollDegrees: number): YawPitchRollAngles;
|
|
53
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* constructor for YawPitchRollAngles with angles in radians.
|
|
68
|
+
* @param yawRadians counterclockwise rotation angle (in radians) around z
|
|
69
|
+
* @param pitchRadians **clockwise** rotation angle (in radians) around y
|
|
70
|
+
* @param rollRadians counterclockwise rotation angle (in radians) around x
|
|
71
|
+
* */
|
|
54
72
|
static createRadians(yawRadians: number, pitchRadians: number, rollRadians: number): YawPitchRollAngles;
|
|
55
73
|
/** construct a `YawPitchRoll` object from an object with 3 named angles */
|
|
56
74
|
static fromJSON(json?: YawPitchRollProps): YawPitchRollAngles;
|
|
57
75
|
/** populate yaw, pitch and roll fields using `Angle.fromJSON` */
|
|
58
76
|
setFromJSON(json?: YawPitchRollProps): void;
|
|
59
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* Convert to a JSON object of form { pitch: 20 , roll: 30 , yaw: 10 }. Angles are in degrees.
|
|
79
|
+
* Any values that are exactly zero (with tolerance `Geometry.smallAngleRadians`) are omitted.
|
|
80
|
+
**/
|
|
60
81
|
toJSON(): YawPitchRollProps;
|
|
61
82
|
/**
|
|
62
83
|
* Install all rotations from `other` into `this`.
|
|
@@ -64,7 +85,7 @@ export declare class YawPitchRollAngles {
|
|
|
64
85
|
*/
|
|
65
86
|
setFrom(other: YawPitchRollAngles): void;
|
|
66
87
|
/**
|
|
67
|
-
*
|
|
88
|
+
* Compare angles between `this` and `other`.
|
|
68
89
|
* * Comparisons are via `isAlmostEqualAllowPeriodShift`.
|
|
69
90
|
* @param other YawPitchRollAngles source
|
|
70
91
|
*/
|
|
@@ -76,35 +97,38 @@ export declare class YawPitchRollAngles {
|
|
|
76
97
|
/**
|
|
77
98
|
* Expand the angles into a (rigid rotation) matrix.
|
|
78
99
|
*
|
|
79
|
-
* * The returned matrix is "rigid"
|
|
80
|
-
* * The
|
|
100
|
+
* * The returned matrix is "rigid" (i.e., it has unit length rows and columns, and its transpose is its inverse).
|
|
101
|
+
* * The rigid matrix is always a right handed coordinate system.
|
|
81
102
|
* @param result optional pre-allocated `Matrix3d`
|
|
82
103
|
*/
|
|
83
104
|
toMatrix3d(result?: Matrix3d): Matrix3d;
|
|
84
|
-
/** Return the largest angle in radians */
|
|
85
|
-
maxAbsRadians(): number;
|
|
86
|
-
/** Return the sum of the angles in squared radians */
|
|
87
|
-
sumSquaredRadians(): number;
|
|
88
105
|
/** Returns true if this rotation does nothing.
|
|
89
106
|
* * If allowPeriodShift is false, any nonzero angle is considered a non-identity
|
|
90
107
|
* * If allowPeriodShift is true, all angles are individually allowed to be any multiple of 360 degrees.
|
|
91
108
|
*/
|
|
92
109
|
isIdentity(allowPeriodShift?: boolean): boolean;
|
|
110
|
+
/** Return the largest angle in radians */
|
|
111
|
+
maxAbsRadians(): number;
|
|
112
|
+
/** Return the sum of the angles in squared radians */
|
|
113
|
+
sumSquaredRadians(): number;
|
|
93
114
|
/** Return the largest difference of angles (in radians) between this and other */
|
|
94
115
|
maxDiffRadians(other: YawPitchRollAngles): number;
|
|
95
116
|
/** Return the largest angle in degrees. */
|
|
96
117
|
maxAbsDegrees(): number;
|
|
97
118
|
/** Return the sum of squared angles in degrees. */
|
|
98
119
|
sumSquaredDegrees(): number;
|
|
120
|
+
/** Return the largest difference of angles (in degrees) between this and other */
|
|
121
|
+
maxDiffDegrees(other: YawPitchRollAngles): number;
|
|
99
122
|
/** Return an object from a Transform as an origin and YawPitchRollAngles. */
|
|
100
123
|
static tryFromTransform(transform: Transform): {
|
|
101
124
|
origin: Point3d;
|
|
102
125
|
angles: YawPitchRollAngles | undefined;
|
|
103
126
|
};
|
|
104
|
-
/** Attempts to create a YawPitchRollAngles object from
|
|
105
|
-
* * This conversion fails if the matrix is not rigid (unit rows and columns, transpose is inverse)
|
|
127
|
+
/** Attempts to create a YawPitchRollAngles object from a Matrix3d
|
|
128
|
+
* * This conversion fails if the matrix is not rigid (unit rows and columns, and transpose is inverse)
|
|
106
129
|
* * In the failure case the method's return value is `undefined`.
|
|
107
|
-
* * In the failure case, if the optional result was supplied, that result will nonetheless be filled with
|
|
130
|
+
* * In the failure case, if the optional result was supplied, that result will nonetheless be filled with
|
|
131
|
+
* a set of angles.
|
|
108
132
|
*/
|
|
109
133
|
static createFromMatrix3d(matrix: Matrix3d, result?: YawPitchRollAngles): YawPitchRollAngles | undefined;
|
|
110
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YawPitchRollAngles.d.ts","sourceRoot":"","sources":["../../../src/geometry3d/YawPitchRollAngles.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAY,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"YawPitchRollAngles.d.ts","sourceRoot":"","sources":["../../../src/geometry3d/YawPitchRollAngles.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAY,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB;IAChB,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,kBAAkB;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,iBAAiB;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,kBAAkB;IAC7B,+DAA+D;IACxD,GAAG,EAAE,KAAK,CAAC;IAClB,6DAA6D;IACtD,KAAK,EAAE,KAAK,CAAC;IACpB,+DAA+D;IACxD,IAAI,EAAE,KAAK,CAAC;IACnB;;;;;SAKK;gBACO,GAAG,GAAE,KAAoB,EAAE,KAAK,GAAE,KAAoB,EAAE,IAAI,GAAE,KAAoB;IAK9F,qCAAqC;IAC9B,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC;IAM/B;;;;;SAKK;WACS,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB;IAO9G;;;;;SAKK;WACS,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB;IAO9G,2EAA2E;WAC7D,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,kBAAkB;IAQpE,iEAAiE;IAC1D,WAAW,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,IAAI;IAMlD;;;QAGI;IACG,MAAM,IAAI,iBAAiB;IAUlC;;;OAGG;IACI,OAAO,CAAC,KAAK,EAAE,kBAAkB;IAKxC;;;;OAIG;IACI,aAAa,CAAC,KAAK,EAAE,kBAAkB;IAK9C;;OAEG;IACI,KAAK;IAOZ;;;;;;OAMG;IACI,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ;IAqCnC;;;OAGG;IACI,UAAU,CAAC,gBAAgB,GAAE,OAAc,GAAG,OAAO;IAU5D,0CAA0C;IACnC,aAAa,IAAI,MAAM;IAG9B,sDAAsD;IAC/C,iBAAiB,IAAI,MAAM;IAGlC,kFAAkF;IAC3E,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM;IAOxD,2CAA2C;IACpC,aAAa,IAAI,MAAM;IAG9B,mDAAmD;IAC5C,iBAAiB,IAAI,MAAM;IAGlC,kFAAkF;IAC3E,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM;IAOxD,6EAA6E;WAC/D,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG;QACpD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;KACxC;IAMD;;;;;OAKG;WACW,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,SAAS;CA0EhH"}
|
|
@@ -9,39 +9,62 @@ import { Geometry } from "../Geometry";
|
|
|
9
9
|
import { Angle } from "./Angle";
|
|
10
10
|
import { Matrix3d } from "./Matrix3d";
|
|
11
11
|
import { Point3d } from "./Point3dVector3d";
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Three angles that determine the orientation of an object in space, sometimes referred to as [Tait–Bryan angles]
|
|
14
|
+
* (https://en.wikipedia.org/wiki/Euler_angles).
|
|
14
15
|
* * The matrix construction can be replicated by this logic:
|
|
15
16
|
* * xyz coordinates have
|
|
16
17
|
* * x forward
|
|
17
18
|
* * y to left
|
|
18
19
|
* * z up
|
|
19
|
-
*
|
|
20
|
-
*
|
|
20
|
+
* * Note that this is a right handed coordinate system.
|
|
21
|
+
* * yaw is a rotation of x towards y, i.e. around positive z (counterclockwise):
|
|
21
22
|
* * `yawMatrix = Matrix3d.createRotationAroundAxisIndex(2, Angle.createDegrees(yawDegrees));`
|
|
22
|
-
*
|
|
23
|
+
* * pitch is a rotation that raises x towards z, i.e. rotation around **negative y** (**clockwise**):
|
|
23
24
|
* * `pitchMatrix = Matrix3d.createRotationAroundAxisIndex(1, Angle.createDegrees(-pitchDegrees));`
|
|
24
|
-
*
|
|
25
|
+
* * roll is rotation of y towards z, i.e. rotation around positive x (counterclockwise):
|
|
25
26
|
* * `rollMatrix = Matrix3d.createRotationAroundAxisIndex(0, Angle.createDegrees(rollDegrees));`
|
|
26
|
-
*
|
|
27
|
+
* * The YPR matrix is the product
|
|
27
28
|
* * `result = yawMatrix.multiplyMatrixMatrix(pitchMatrix.multiplyMatrixMatrix(rollMatrix));`
|
|
28
|
-
*
|
|
29
|
-
*
|
|
29
|
+
* * Note that this is for "column based" matrix with vectors multiplying on the right of the matrix.
|
|
30
|
+
* Hence a vector is first rotated by roll, then the pitch, finally yaw. So multiplication order in
|
|
31
|
+
* the sense of AxisOrder is `RPY` (i.e., XYZ), in contrast to the familiar name `YPR`.
|
|
30
32
|
* @public
|
|
31
33
|
*/
|
|
32
34
|
export class YawPitchRollAngles {
|
|
35
|
+
/**
|
|
36
|
+
* constructor
|
|
37
|
+
* @param yaw counterclockwise rotation angle around z
|
|
38
|
+
* @param pitch **clockwise** rotation angle around y
|
|
39
|
+
* @param roll counterclockwise rotation angle around x
|
|
40
|
+
* */
|
|
33
41
|
constructor(yaw = Angle.zero(), pitch = Angle.zero(), roll = Angle.zero()) {
|
|
34
42
|
this.yaw = yaw;
|
|
35
43
|
this.pitch = pitch;
|
|
36
44
|
this.roll = roll;
|
|
37
45
|
}
|
|
38
46
|
/** Freeze this YawPitchRollAngles */
|
|
39
|
-
freeze() {
|
|
40
|
-
|
|
47
|
+
freeze() {
|
|
48
|
+
this.yaw.freeze();
|
|
49
|
+
this.pitch.freeze();
|
|
50
|
+
this.roll.freeze();
|
|
51
|
+
return Object.freeze(this);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* constructor for YawPitchRollAngles with angles in degrees.
|
|
55
|
+
* @param yawDegrees counterclockwise rotation angle (in degrees) around z
|
|
56
|
+
* @param pitchDegrees **clockwise** rotation angle (in degrees) around y
|
|
57
|
+
* @param rollDegrees counterclockwise rotation angle (in degrees) around x
|
|
58
|
+
* */
|
|
41
59
|
static createDegrees(yawDegrees, pitchDegrees, rollDegrees) {
|
|
42
60
|
return new YawPitchRollAngles(Angle.createDegrees(yawDegrees), Angle.createDegrees(pitchDegrees), Angle.createDegrees(rollDegrees));
|
|
43
61
|
}
|
|
44
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* constructor for YawPitchRollAngles with angles in radians.
|
|
64
|
+
* @param yawRadians counterclockwise rotation angle (in radians) around z
|
|
65
|
+
* @param pitchRadians **clockwise** rotation angle (in radians) around y
|
|
66
|
+
* @param rollRadians counterclockwise rotation angle (in radians) around x
|
|
67
|
+
* */
|
|
45
68
|
static createRadians(yawRadians, pitchRadians, rollRadians) {
|
|
46
69
|
return new YawPitchRollAngles(Angle.createRadians(yawRadians), Angle.createRadians(pitchRadians), Angle.createRadians(rollRadians));
|
|
47
70
|
}
|
|
@@ -57,7 +80,10 @@ export class YawPitchRollAngles {
|
|
|
57
80
|
this.pitch = Angle.fromJSON(json.pitch);
|
|
58
81
|
this.roll = Angle.fromJSON(json.roll);
|
|
59
82
|
}
|
|
60
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Convert to a JSON object of form { pitch: 20 , roll: 30 , yaw: 10 }. Angles are in degrees.
|
|
85
|
+
* Any values that are exactly zero (with tolerance `Geometry.smallAngleRadians`) are omitted.
|
|
86
|
+
**/
|
|
61
87
|
toJSON() {
|
|
62
88
|
const val = {};
|
|
63
89
|
if (!this.pitch.isAlmostZero)
|
|
@@ -78,7 +104,7 @@ export class YawPitchRollAngles {
|
|
|
78
104
|
this.roll.setFrom(other.roll);
|
|
79
105
|
}
|
|
80
106
|
/**
|
|
81
|
-
*
|
|
107
|
+
* Compare angles between `this` and `other`.
|
|
82
108
|
* * Comparisons are via `isAlmostEqualAllowPeriodShift`.
|
|
83
109
|
* @param other YawPitchRollAngles source
|
|
84
110
|
*/
|
|
@@ -90,30 +116,47 @@ export class YawPitchRollAngles {
|
|
|
90
116
|
/**
|
|
91
117
|
* Make a copy of this YawPitchRollAngles.
|
|
92
118
|
*/
|
|
93
|
-
clone() {
|
|
119
|
+
clone() {
|
|
120
|
+
return new YawPitchRollAngles(this.yaw.clone(), this.pitch.clone(), this.roll.clone());
|
|
121
|
+
}
|
|
94
122
|
/**
|
|
95
123
|
* Expand the angles into a (rigid rotation) matrix.
|
|
96
124
|
*
|
|
97
|
-
* * The returned matrix is "rigid"
|
|
98
|
-
* * The
|
|
125
|
+
* * The returned matrix is "rigid" (i.e., it has unit length rows and columns, and its transpose is its inverse).
|
|
126
|
+
* * The rigid matrix is always a right handed coordinate system.
|
|
99
127
|
* @param result optional pre-allocated `Matrix3d`
|
|
100
128
|
*/
|
|
101
129
|
toMatrix3d(result) {
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
130
|
+
const cz = Math.cos(this.yaw.radians);
|
|
131
|
+
const sz = Math.sin(this.yaw.radians);
|
|
132
|
+
const cy = Math.cos(this.pitch.radians);
|
|
133
|
+
const sy = Math.sin(this.pitch.radians);
|
|
134
|
+
const cx = Math.cos(this.roll.radians);
|
|
135
|
+
const sx = Math.sin(this.roll.radians);
|
|
136
|
+
/**
|
|
137
|
+
* The axis order is XYZ (i.e., RPY) so the rotation matrix is calculated via rZ*rY*rX where
|
|
138
|
+
* rX, rY, and rZ are base rotation matrixes:
|
|
139
|
+
*
|
|
140
|
+
* const rX = Matrix3d.createRowValues(
|
|
141
|
+
* 1, 0, 0,
|
|
142
|
+
* 0, Math.cos(x), -Math.sin(x),
|
|
143
|
+
* 0, Math.sin(x), Math.cos(x),
|
|
144
|
+
* );
|
|
145
|
+
* const rY = Matrix3d.createRowValues(
|
|
146
|
+
* Math.cos(y), 0, Math.sin(y),
|
|
147
|
+
* 0, 1, 0,
|
|
148
|
+
* -Math.sin(y), 0, Math.cos(y),
|
|
149
|
+
* );
|
|
150
|
+
* const rZ = Matrix3d.createRowValues(
|
|
151
|
+
* Math.cos(z), -Math.sin(z), 0,
|
|
152
|
+
* Math.sin(z), Math.cos(z), 0,
|
|
153
|
+
* 0, 0, 1,
|
|
154
|
+
* );
|
|
155
|
+
*
|
|
156
|
+
* Then we replace sin(y) with -sin(y) because y rotation (i.e., pitch) is clockwise (alternatively, you
|
|
157
|
+
* can use transpose of rY in the matrix multiplication to get the same result)
|
|
158
|
+
*/
|
|
159
|
+
return Matrix3d.createRowValues(cz * cy, -(sz * cx + cz * sy * sx), (sz * sx - cz * sy * cx), sz * cy, (cz * cx - sz * sy * sx), -(cz * sx + sz * sy * cx), sy, cy * sx, cy * cx, result);
|
|
117
160
|
}
|
|
118
161
|
/** Returns true if this rotation does nothing.
|
|
119
162
|
* * If allowPeriodShift is false, any nonzero angle is considered a non-identity
|
|
@@ -129,52 +172,104 @@ export class YawPitchRollAngles {
|
|
|
129
172
|
&& Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.pitch.radians)
|
|
130
173
|
&& Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.roll.radians);
|
|
131
174
|
}
|
|
175
|
+
/** Return the largest angle in radians */
|
|
176
|
+
maxAbsRadians() {
|
|
177
|
+
return Geometry.maxAbsXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);
|
|
178
|
+
}
|
|
179
|
+
/** Return the sum of the angles in squared radians */
|
|
180
|
+
sumSquaredRadians() {
|
|
181
|
+
return Geometry.hypotenuseSquaredXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);
|
|
182
|
+
}
|
|
132
183
|
/** Return the largest difference of angles (in radians) between this and other */
|
|
133
184
|
maxDiffRadians(other) {
|
|
134
185
|
return Math.max(this.yaw.radians - other.yaw.radians, this.pitch.radians - other.pitch.radians, this.roll.radians - other.roll.radians);
|
|
135
186
|
}
|
|
136
187
|
/** Return the largest angle in degrees. */
|
|
137
|
-
maxAbsDegrees() {
|
|
188
|
+
maxAbsDegrees() {
|
|
189
|
+
return Geometry.maxAbsXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees);
|
|
190
|
+
}
|
|
138
191
|
/** Return the sum of squared angles in degrees. */
|
|
139
|
-
sumSquaredDegrees() {
|
|
192
|
+
sumSquaredDegrees() {
|
|
193
|
+
return Geometry.hypotenuseSquaredXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees);
|
|
194
|
+
}
|
|
195
|
+
/** Return the largest difference of angles (in degrees) between this and other */
|
|
196
|
+
maxDiffDegrees(other) {
|
|
197
|
+
return Math.max(this.yaw.degrees - other.yaw.degrees, this.pitch.degrees - other.pitch.degrees, this.roll.degrees - other.roll.degrees);
|
|
198
|
+
}
|
|
140
199
|
/** Return an object from a Transform as an origin and YawPitchRollAngles. */
|
|
141
200
|
static tryFromTransform(transform) {
|
|
142
|
-
// bundle up the transform's origin with the angle data extracted from the transform
|
|
143
201
|
return {
|
|
144
|
-
angles: YawPitchRollAngles.createFromMatrix3d(transform.matrix),
|
|
145
202
|
origin: Point3d.createFrom(transform.origin),
|
|
203
|
+
angles: YawPitchRollAngles.createFromMatrix3d(transform.matrix),
|
|
146
204
|
};
|
|
147
205
|
}
|
|
148
|
-
/** Attempts to create a YawPitchRollAngles object from
|
|
149
|
-
* * This conversion fails if the matrix is not rigid (unit rows and columns, transpose is inverse)
|
|
206
|
+
/** Attempts to create a YawPitchRollAngles object from a Matrix3d
|
|
207
|
+
* * This conversion fails if the matrix is not rigid (unit rows and columns, and transpose is inverse)
|
|
150
208
|
* * In the failure case the method's return value is `undefined`.
|
|
151
|
-
* * In the failure case, if the optional result was supplied, that result will nonetheless be filled with
|
|
209
|
+
* * In the failure case, if the optional result was supplied, that result will nonetheless be filled with
|
|
210
|
+
* a set of angles.
|
|
152
211
|
*/
|
|
153
212
|
static createFromMatrix3d(matrix, result) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
213
|
+
/**
|
|
214
|
+
* The rotation matrix for is
|
|
215
|
+
*
|
|
216
|
+
* Matrix3d.createRowValues(
|
|
217
|
+
* cz * cy, -(sz * cx + cz * sy * sx), (sz * sx - cz * sy * cx),
|
|
218
|
+
* sz * cy, (cz * cx - sz * sy * sx), -(cz * sx + sz * sy * cx),
|
|
219
|
+
* sy, cy * sx, cy * cx
|
|
220
|
+
* );
|
|
221
|
+
*
|
|
222
|
+
* where cx = cos(x), sx = sin(x), cy = cos(y), sy = sin(y), cz = cos(z), and sz = sin(z)
|
|
223
|
+
*/
|
|
224
|
+
const sy = matrix.at(2, 0); // sin(y)
|
|
225
|
+
const cy = Math.sqrt(matrix.at(2, 1) * matrix.at(2, 1) + matrix.at(2, 2) * matrix.at(2, 2)); // |cos(y)|
|
|
226
|
+
const pitchA = Angle.createAtan2(sy, cy); // with positive cosine
|
|
227
|
+
const pitchB = Angle.createAtan2(sy, -cy); // with negative cosine
|
|
228
|
+
const angles = result ? result : new YawPitchRollAngles();
|
|
229
|
+
/**
|
|
230
|
+
* If cos(y) = 0 then y = +-90 degrees so we have a gimbal lock.
|
|
231
|
+
* This means x and z can be anything as long as their sum x + z is constant.
|
|
232
|
+
* so we can pick z = 0 and calculate x (or pick x = 0 and calculate z).
|
|
233
|
+
* Math details can be found
|
|
234
|
+
* https://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles
|
|
235
|
+
*
|
|
236
|
+
* The rotation matrix for y = +-90 degrees and x = 0 becomes
|
|
237
|
+
*
|
|
238
|
+
* Matrix3d.createRowValues(
|
|
239
|
+
* 0, -sz, -+cz,
|
|
240
|
+
* 0, cz, -+sz,
|
|
241
|
+
* +-1, 0, 0
|
|
242
|
+
* );
|
|
243
|
+
*
|
|
244
|
+
* so z = atan(sz/cz) = atan(-matrix.at(0, 1), matrix.at(1, 1))
|
|
245
|
+
*/
|
|
246
|
+
if (cy < Geometry.smallAngleRadians) {
|
|
160
247
|
angles.yaw = Angle.createAtan2(-matrix.at(0, 1), matrix.at(1, 1));
|
|
161
|
-
angles.pitch = pitchA;
|
|
248
|
+
angles.pitch = pitchA; // this is an arbitrary choice. can pick pitchB instead.
|
|
162
249
|
angles.roll = Angle.createRadians(0.0);
|
|
163
250
|
}
|
|
164
251
|
else {
|
|
252
|
+
/**
|
|
253
|
+
* positive cosine
|
|
254
|
+
* z = atan(sz/cz) = atan(matrix.at(1, 0), matrix.at(0, 0))
|
|
255
|
+
* x = atan(sx/cx) = atan(matrix.at(2, 1), matrix.at(2, 2))
|
|
256
|
+
*/
|
|
165
257
|
const yawA = Angle.createAtan2(matrix.at(1, 0), matrix.at(0, 0));
|
|
166
258
|
const rollA = Angle.createAtan2(matrix.at(2, 1), matrix.at(2, 2));
|
|
259
|
+
// similar with negative cosine
|
|
167
260
|
const yawB = Angle.createAtan2(-matrix.at(1, 0), -matrix.at(0, 0));
|
|
168
261
|
const rollB = Angle.createAtan2(-matrix.at(2, 1), -matrix.at(2, 2));
|
|
262
|
+
// create YPR
|
|
169
263
|
const yprA = new YawPitchRollAngles(yawA, pitchA, rollA);
|
|
170
264
|
const yprB = new YawPitchRollAngles(yawB, pitchB, rollB);
|
|
265
|
+
// decide to pick yprA or yprB with smallest magnitude angles
|
|
171
266
|
const absFactor = 0.95;
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
if (
|
|
267
|
+
const maxRadiansA = yprA.maxAbsRadians();
|
|
268
|
+
const maxRadiansB = yprB.maxAbsRadians();
|
|
269
|
+
if (maxRadiansA < absFactor * maxRadiansB) {
|
|
175
270
|
angles.setFrom(yprA);
|
|
176
271
|
}
|
|
177
|
-
else if (
|
|
272
|
+
else if (maxRadiansB < absFactor * maxRadiansA) {
|
|
178
273
|
angles.setFrom(yprB);
|
|
179
274
|
}
|
|
180
275
|
else {
|
|
@@ -188,6 +283,7 @@ export class YawPitchRollAngles {
|
|
|
188
283
|
}
|
|
189
284
|
}
|
|
190
285
|
}
|
|
286
|
+
// sanity check
|
|
191
287
|
const matrix1 = angles.toMatrix3d();
|
|
192
288
|
return matrix.maxDiff(matrix1) < Geometry.smallAngleRadians ? angles : undefined;
|
|
193
289
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YawPitchRollAngles.js","sourceRoot":"","sources":["../../../src/geometry3d/YawPitchRollAngles.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module CartesianGeometry\r\n */\r\n\r\nimport { AngleProps, Geometry } from \"../Geometry\";\r\nimport { Angle } from \"./Angle\";\r\nimport { Matrix3d } from \"./Matrix3d\";\r\nimport { Point3d } from \"./Point3dVector3d\";\r\nimport { Transform } from \"./Transform\";\r\n\r\n/** The properties that define [[YawPitchRollAngles]]. */\r\n/**\r\n * angle properties of a `YawPitchRoll` orientation\r\n * @public\r\n */\r\nexport interface YawPitchRollProps {\r\n /** yaw field */\r\n yaw?: AngleProps;\r\n /** pitch field */\r\n pitch?: AngleProps;\r\n /** roll field */\r\n roll?: AngleProps;\r\n}\r\n// cspell:word Tait\r\n/** Three angles that determine the orientation of an object in space. Sometimes referred to as [Tait–Bryan angles](https://en.wikipedia.org/wiki/Euler_angles).\r\n * * The matrix construction can be replicated by this logic:\r\n * * xyz coordinates have\r\n * * x forward\r\n * * y to left\r\n * * z up\r\n * * Note that this is a right handed coordinate system.\r\n * * yaw is a rotation of x towards y, i.e. around positive z:\r\n * * `yawMatrix = Matrix3d.createRotationAroundAxisIndex(2, Angle.createDegrees(yawDegrees));`\r\n * * pitch is a rotation that raises x towards z, i.e. rotation around negative y:\r\n * * `pitchMatrix = Matrix3d.createRotationAroundAxisIndex(1, Angle.createDegrees(-pitchDegrees));`\r\n * * roll is rotation of y towards z, i.e. rotation around positive x:\r\n * * `rollMatrix = Matrix3d.createRotationAroundAxisIndex(0, Angle.createDegrees(rollDegrees));`\r\n * * The YPR matrix is the product\r\n * * `result = yawMatrix.multiplyMatrixMatrix(pitchMatrix.multiplyMatrixMatrix(rollMatrix));`\r\n * * Note that this is for \"column based\" matrix, with vectors appearing to the right\r\n * * Hence a vector is first rotated by roll, then the pitch, finally yaw.\r\n * @public\r\n */\r\nexport class YawPitchRollAngles {\r\n /** The yaw angle. */\r\n public yaw: Angle;\r\n /** The pitch angle. */\r\n public pitch: Angle;\r\n /** The roll angle. */\r\n public roll: Angle;\r\n\r\n constructor(yaw: Angle = Angle.zero(), pitch: Angle = Angle.zero(), roll: Angle = Angle.zero()) {\r\n this.yaw = yaw;\r\n this.pitch = pitch;\r\n this.roll = roll;\r\n }\r\n /** Freeze this YawPitchRollAngles */\r\n public freeze(): Readonly<this> { this.yaw.freeze(); this.pitch.freeze(); this.roll.freeze(); return Object.freeze(this); }\r\n /** constructor for YawPitchRollAngles with angles in degrees. */\r\n public static createDegrees(yawDegrees: number, pitchDegrees: number, rollDegrees: number): YawPitchRollAngles {\r\n return new YawPitchRollAngles(Angle.createDegrees(yawDegrees), Angle.createDegrees(pitchDegrees), Angle.createDegrees(rollDegrees));\r\n }\r\n /** constructor for YawPitchRollAngles with angles in radians. */\r\n public static createRadians(yawRadians: number, pitchRadians: number, rollRadians: number): YawPitchRollAngles {\r\n return new YawPitchRollAngles(Angle.createRadians(yawRadians), Angle.createRadians(pitchRadians), Angle.createRadians(rollRadians));\r\n }\r\n /** construct a `YawPitchRoll` object from an object with 3 named angles */\r\n public static fromJSON(json?: YawPitchRollProps): YawPitchRollAngles {\r\n json = json ? json : {};\r\n return new YawPitchRollAngles(Angle.fromJSON(json.yaw), Angle.fromJSON(json.pitch), Angle.fromJSON(json.roll));\r\n }\r\n /** populate yaw, pitch and roll fields using `Angle.fromJSON` */\r\n public setFromJSON(json?: YawPitchRollProps): void {\r\n json = json ? json : {};\r\n this.yaw = Angle.fromJSON(json.yaw);\r\n this.pitch = Angle.fromJSON(json.pitch);\r\n this.roll = Angle.fromJSON(json.roll);\r\n }\r\n /** Convert to a JSON object of form { pitch: 20 , roll: 29.999999999999996 , yaw: 10 }. Any values that are exactly zero (with tolerance `Geometry.smallAngleRadians`) are omitted. */\r\n public toJSON(): YawPitchRollProps {\r\n const val: YawPitchRollProps = {};\r\n if (!this.pitch.isAlmostZero)\r\n val.pitch = this.pitch.toJSON();\r\n if (!this.roll.isAlmostZero)\r\n val.roll = this.roll.toJSON();\r\n if (!this.yaw.isAlmostZero)\r\n val.yaw = this.yaw.toJSON();\r\n return val;\r\n }\r\n /**\r\n * Install all rotations from `other` into `this`.\r\n * @param other YawPitchRollAngles source\r\n */\r\n public setFrom(other: YawPitchRollAngles) {\r\n this.yaw.setFrom(other.yaw);\r\n this.pitch.setFrom(other.pitch);\r\n this.roll.setFrom(other.roll);\r\n }\r\n /**\r\n * * Compare angles between `this` and `other`.\r\n * * Comparisons are via `isAlmostEqualAllowPeriodShift`.\r\n * @param other YawPitchRollAngles source\r\n */\r\n public isAlmostEqual(other: YawPitchRollAngles) {\r\n return this.yaw.isAlmostEqualAllowPeriodShift(other.yaw)\r\n && this.pitch.isAlmostEqualAllowPeriodShift(other.pitch)\r\n && this.roll.isAlmostEqualAllowPeriodShift(other.roll);\r\n }\r\n /**\r\n * Make a copy of this YawPitchRollAngles.\r\n */\r\n public clone() { return new YawPitchRollAngles(this.yaw.clone(), this.pitch.clone(), this.roll.clone()); }\r\n /**\r\n * Expand the angles into a (rigid rotation) matrix.\r\n *\r\n * * The returned matrix is \"rigid\" -- unit length rows and columns, and its transpose is its inverse.\r\n * * The \"rigid\" matrix is always a right handed coordinate system.\r\n * @param result optional pre-allocated `Matrix3d`\r\n */\r\n public toMatrix3d(result?: Matrix3d) {\r\n const c0 = Math.cos(this.yaw.radians);\r\n const s0 = Math.sin(this.yaw.radians);\r\n const c1 = Math.cos(this.pitch.radians);\r\n const s1 = Math.sin(this.pitch.radians);\r\n const c2 = Math.cos(this.roll.radians);\r\n const s2 = Math.sin(this.roll.radians);\r\n return Matrix3d.createRowValues(c0 * c1, -(s0 * c2 + c0 * s1 * s2), (s0 * s2 - c0 * s1 * c2), s0 * c1, (c0 * c2 - s0 * s1 * s2), -(c0 * s2 + s0 * s1 * c2), s1, c1 * s2, c1 * c2, result);\r\n }\r\n /** Return the largest angle in radians */\r\n public maxAbsRadians(): number {\r\n return Geometry.maxAbsXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);\r\n }\r\n /** Return the sum of the angles in squared radians */\r\n public sumSquaredRadians(): number {\r\n return Geometry.hypotenuseSquaredXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);\r\n }\r\n /** Returns true if this rotation does nothing.\r\n * * If allowPeriodShift is false, any nonzero angle is considered a non-identity\r\n * * If allowPeriodShift is true, all angles are individually allowed to be any multiple of 360 degrees.\r\n */\r\n public isIdentity(allowPeriodShift: boolean = true): boolean {\r\n if (allowPeriodShift)\r\n return Angle.isAlmostEqualRadiansAllowPeriodShift(0.0, this.yaw.radians)\r\n && Angle.isAlmostEqualRadiansAllowPeriodShift(0.0, this.pitch.radians)\r\n && Angle.isAlmostEqualRadiansAllowPeriodShift(0.0, this.roll.radians);\r\n else\r\n return Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.yaw.radians)\r\n && Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.pitch.radians)\r\n && Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.roll.radians);\r\n }\r\n /** Return the largest difference of angles (in radians) between this and other */\r\n public maxDiffRadians(other: YawPitchRollAngles): number {\r\n return Math.max(this.yaw.radians - other.yaw.radians, this.pitch.radians - other.pitch.radians, this.roll.radians - other.roll.radians);\r\n }\r\n /** Return the largest angle in degrees. */\r\n public maxAbsDegrees(): number { return Geometry.maxAbsXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees); }\r\n /** Return the sum of squared angles in degrees. */\r\n public sumSquaredDegrees(): number { return Geometry.hypotenuseSquaredXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees); }\r\n /** Return an object from a Transform as an origin and YawPitchRollAngles. */\r\n public static tryFromTransform(transform: Transform): {\r\n origin: Point3d;\r\n angles: YawPitchRollAngles | undefined;\r\n } {\r\n // bundle up the transform's origin with the angle data extracted from the transform\r\n return {\r\n angles: YawPitchRollAngles.createFromMatrix3d(transform.matrix),\r\n origin: Point3d.createFrom(transform.origin),\r\n };\r\n }\r\n /** Attempts to create a YawPitchRollAngles object from an Matrix3d\r\n * * This conversion fails if the matrix is not rigid (unit rows and columns, transpose is inverse)\r\n * * In the failure case the method's return value is `undefined`.\r\n * * In the failure case, if the optional result was supplied, that result will nonetheless be filled with a set of angles.\r\n */\r\n public static createFromMatrix3d(matrix: Matrix3d, result?: YawPitchRollAngles): YawPitchRollAngles | undefined {\r\n const s1 = matrix.at(2, 0);\r\n const c1 = Math.sqrt(matrix.at(2, 1) * matrix.at(2, 1) + matrix.at(2, 2) * matrix.at(2, 2));\r\n const pitchA = Angle.createAtan2(s1, c1); // with positive cosine\r\n const pitchB = Angle.createAtan2(s1, -c1); // with negative cosine\r\n const angles = result ? result : new YawPitchRollAngles(); // default undefined . . .\r\n if (c1 < Geometry.smallAngleRadians) { // This is a radians test !!!\r\n angles.yaw = Angle.createAtan2(-matrix.at(0, 1), matrix.at(1, 1));\r\n angles.pitch = pitchA;\r\n angles.roll = Angle.createRadians(0.0);\r\n } else {\r\n const yawA = Angle.createAtan2(matrix.at(1, 0), matrix.at(0, 0));\r\n const rollA = Angle.createAtan2(matrix.at(2, 1), matrix.at(2, 2));\r\n const yawB = Angle.createAtan2(-matrix.at(1, 0), -matrix.at(0, 0));\r\n const rollB = Angle.createAtan2(-matrix.at(2, 1), -matrix.at(2, 2));\r\n const yprA = new YawPitchRollAngles(yawA, pitchA, rollA);\r\n const yprB = new YawPitchRollAngles(yawB, pitchB, rollB);\r\n const absFactor = 0.95;\r\n const radiansA = yprA.maxAbsRadians();\r\n const radiansB = yprB.maxAbsRadians();\r\n if (radiansA < absFactor * radiansB) {\r\n angles.setFrom(yprA);\r\n } else if (radiansB < absFactor * radiansA) {\r\n angles.setFrom(yprB);\r\n } else {\r\n const sumA = yprA.sumSquaredRadians();\r\n const sumB = yprB.sumSquaredRadians();\r\n if (sumA <= sumB) {\r\n angles.setFrom(yprA);\r\n } else {\r\n angles.setFrom(yprB);\r\n }\r\n }\r\n }\r\n const matrix1 = angles.toMatrix3d();\r\n return matrix.maxDiff(matrix1) < Geometry.smallAngleRadians ? angles : undefined;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"YawPitchRollAngles.js","sourceRoot":"","sources":["../../../src/geometry3d/YawPitchRollAngles.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module CartesianGeometry\r\n */\r\n\r\nimport { AngleProps, Geometry } from \"../Geometry\";\r\nimport { Angle } from \"./Angle\";\r\nimport { Matrix3d } from \"./Matrix3d\";\r\nimport { Point3d } from \"./Point3dVector3d\";\r\nimport { Transform } from \"./Transform\";\r\n\r\n// cspell:word Tait\r\n\r\n/**\r\n * angle properties of a `YawPitchRoll` orientation\r\n * @public\r\n */\r\nexport interface YawPitchRollProps {\r\n /** yaw field */\r\n yaw?: AngleProps;\r\n /** pitch field */\r\n pitch?: AngleProps;\r\n /** roll field */\r\n roll?: AngleProps;\r\n}\r\n\r\n/**\r\n * Three angles that determine the orientation of an object in space, sometimes referred to as [Tait–Bryan angles]\r\n * (https://en.wikipedia.org/wiki/Euler_angles).\r\n * * The matrix construction can be replicated by this logic:\r\n * * xyz coordinates have\r\n * * x forward\r\n * * y to left\r\n * * z up\r\n * * Note that this is a right handed coordinate system.\r\n * * yaw is a rotation of x towards y, i.e. around positive z (counterclockwise):\r\n * * `yawMatrix = Matrix3d.createRotationAroundAxisIndex(2, Angle.createDegrees(yawDegrees));`\r\n * * pitch is a rotation that raises x towards z, i.e. rotation around **negative y** (**clockwise**):\r\n * * `pitchMatrix = Matrix3d.createRotationAroundAxisIndex(1, Angle.createDegrees(-pitchDegrees));`\r\n * * roll is rotation of y towards z, i.e. rotation around positive x (counterclockwise):\r\n * * `rollMatrix = Matrix3d.createRotationAroundAxisIndex(0, Angle.createDegrees(rollDegrees));`\r\n * * The YPR matrix is the product\r\n * * `result = yawMatrix.multiplyMatrixMatrix(pitchMatrix.multiplyMatrixMatrix(rollMatrix));`\r\n * * Note that this is for \"column based\" matrix with vectors multiplying on the right of the matrix.\r\n * Hence a vector is first rotated by roll, then the pitch, finally yaw. So multiplication order in\r\n * the sense of AxisOrder is `RPY` (i.e., XYZ), in contrast to the familiar name `YPR`.\r\n * @public\r\n */\r\nexport class YawPitchRollAngles {\r\n /** The yaw angle: counterclockwise rotation angle around z */\r\n public yaw: Angle;\r\n /** The pitch angle: **clockwise** rotation angle around y */\r\n public pitch: Angle;\r\n /** The roll angle: counterclockwise rotation angle around x */\r\n public roll: Angle;\r\n /**\r\n * constructor\r\n * @param yaw counterclockwise rotation angle around z\r\n * @param pitch **clockwise** rotation angle around y\r\n * @param roll counterclockwise rotation angle around x\r\n * */\r\n constructor(yaw: Angle = Angle.zero(), pitch: Angle = Angle.zero(), roll: Angle = Angle.zero()) {\r\n this.yaw = yaw;\r\n this.pitch = pitch;\r\n this.roll = roll;\r\n }\r\n /** Freeze this YawPitchRollAngles */\r\n public freeze(): Readonly<this> {\r\n this.yaw.freeze();\r\n this.pitch.freeze();\r\n this.roll.freeze();\r\n return Object.freeze(this);\r\n }\r\n /**\r\n * constructor for YawPitchRollAngles with angles in degrees.\r\n * @param yawDegrees counterclockwise rotation angle (in degrees) around z\r\n * @param pitchDegrees **clockwise** rotation angle (in degrees) around y\r\n * @param rollDegrees counterclockwise rotation angle (in degrees) around x\r\n * */\r\n public static createDegrees(yawDegrees: number, pitchDegrees: number, rollDegrees: number): YawPitchRollAngles {\r\n return new YawPitchRollAngles(\r\n Angle.createDegrees(yawDegrees),\r\n Angle.createDegrees(pitchDegrees),\r\n Angle.createDegrees(rollDegrees)\r\n );\r\n }\r\n /**\r\n * constructor for YawPitchRollAngles with angles in radians.\r\n * @param yawRadians counterclockwise rotation angle (in radians) around z\r\n * @param pitchRadians **clockwise** rotation angle (in radians) around y\r\n * @param rollRadians counterclockwise rotation angle (in radians) around x\r\n * */\r\n public static createRadians(yawRadians: number, pitchRadians: number, rollRadians: number): YawPitchRollAngles {\r\n return new YawPitchRollAngles(\r\n Angle.createRadians(yawRadians),\r\n Angle.createRadians(pitchRadians),\r\n Angle.createRadians(rollRadians)\r\n );\r\n }\r\n /** construct a `YawPitchRoll` object from an object with 3 named angles */\r\n public static fromJSON(json?: YawPitchRollProps): YawPitchRollAngles {\r\n json = json ? json : {};\r\n return new YawPitchRollAngles(\r\n Angle.fromJSON(json.yaw),\r\n Angle.fromJSON(json.pitch),\r\n Angle.fromJSON(json.roll)\r\n );\r\n }\r\n /** populate yaw, pitch and roll fields using `Angle.fromJSON` */\r\n public setFromJSON(json?: YawPitchRollProps): void {\r\n json = json ? json : {};\r\n this.yaw = Angle.fromJSON(json.yaw);\r\n this.pitch = Angle.fromJSON(json.pitch);\r\n this.roll = Angle.fromJSON(json.roll);\r\n }\r\n /**\r\n * Convert to a JSON object of form { pitch: 20 , roll: 30 , yaw: 10 }. Angles are in degrees.\r\n * Any values that are exactly zero (with tolerance `Geometry.smallAngleRadians`) are omitted.\r\n **/\r\n public toJSON(): YawPitchRollProps {\r\n const val: YawPitchRollProps = {};\r\n if (!this.pitch.isAlmostZero)\r\n val.pitch = this.pitch.toJSON();\r\n if (!this.roll.isAlmostZero)\r\n val.roll = this.roll.toJSON();\r\n if (!this.yaw.isAlmostZero)\r\n val.yaw = this.yaw.toJSON();\r\n return val;\r\n }\r\n /**\r\n * Install all rotations from `other` into `this`.\r\n * @param other YawPitchRollAngles source\r\n */\r\n public setFrom(other: YawPitchRollAngles) {\r\n this.yaw.setFrom(other.yaw);\r\n this.pitch.setFrom(other.pitch);\r\n this.roll.setFrom(other.roll);\r\n }\r\n /**\r\n * Compare angles between `this` and `other`.\r\n * * Comparisons are via `isAlmostEqualAllowPeriodShift`.\r\n * @param other YawPitchRollAngles source\r\n */\r\n public isAlmostEqual(other: YawPitchRollAngles) {\r\n return this.yaw.isAlmostEqualAllowPeriodShift(other.yaw)\r\n && this.pitch.isAlmostEqualAllowPeriodShift(other.pitch)\r\n && this.roll.isAlmostEqualAllowPeriodShift(other.roll);\r\n }\r\n /**\r\n * Make a copy of this YawPitchRollAngles.\r\n */\r\n public clone() {\r\n return new YawPitchRollAngles(\r\n this.yaw.clone(),\r\n this.pitch.clone(),\r\n this.roll.clone()\r\n );\r\n }\r\n /**\r\n * Expand the angles into a (rigid rotation) matrix.\r\n *\r\n * * The returned matrix is \"rigid\" (i.e., it has unit length rows and columns, and its transpose is its inverse).\r\n * * The rigid matrix is always a right handed coordinate system.\r\n * @param result optional pre-allocated `Matrix3d`\r\n */\r\n public toMatrix3d(result?: Matrix3d) {\r\n const cz = Math.cos(this.yaw.radians);\r\n const sz = Math.sin(this.yaw.radians);\r\n const cy = Math.cos(this.pitch.radians);\r\n const sy = Math.sin(this.pitch.radians);\r\n const cx = Math.cos(this.roll.radians);\r\n const sx = Math.sin(this.roll.radians);\r\n /**\r\n * The axis order is XYZ (i.e., RPY) so the rotation matrix is calculated via rZ*rY*rX where\r\n * rX, rY, and rZ are base rotation matrixes:\r\n *\r\n * const rX = Matrix3d.createRowValues(\r\n * 1, 0, 0,\r\n * 0, Math.cos(x), -Math.sin(x),\r\n * 0, Math.sin(x), Math.cos(x),\r\n * );\r\n * const rY = Matrix3d.createRowValues(\r\n * Math.cos(y), 0, Math.sin(y),\r\n * 0, 1, 0,\r\n * -Math.sin(y), 0, Math.cos(y),\r\n * );\r\n * const rZ = Matrix3d.createRowValues(\r\n * Math.cos(z), -Math.sin(z), 0,\r\n * Math.sin(z), Math.cos(z), 0,\r\n * 0, 0, 1,\r\n * );\r\n *\r\n * Then we replace sin(y) with -sin(y) because y rotation (i.e., pitch) is clockwise (alternatively, you\r\n * can use transpose of rY in the matrix multiplication to get the same result)\r\n */\r\n return Matrix3d.createRowValues(\r\n cz * cy, -(sz * cx + cz * sy * sx), (sz * sx - cz * sy * cx),\r\n sz * cy, (cz * cx - sz * sy * sx), -(cz * sx + sz * sy * cx),\r\n sy, cy * sx, cy * cx,\r\n result\r\n );\r\n }\r\n /** Returns true if this rotation does nothing.\r\n * * If allowPeriodShift is false, any nonzero angle is considered a non-identity\r\n * * If allowPeriodShift is true, all angles are individually allowed to be any multiple of 360 degrees.\r\n */\r\n public isIdentity(allowPeriodShift: boolean = true): boolean {\r\n if (allowPeriodShift)\r\n return Angle.isAlmostEqualRadiansAllowPeriodShift(0.0, this.yaw.radians)\r\n && Angle.isAlmostEqualRadiansAllowPeriodShift(0.0, this.pitch.radians)\r\n && Angle.isAlmostEqualRadiansAllowPeriodShift(0.0, this.roll.radians);\r\n else\r\n return Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.yaw.radians)\r\n && Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.pitch.radians)\r\n && Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.roll.radians);\r\n }\r\n /** Return the largest angle in radians */\r\n public maxAbsRadians(): number {\r\n return Geometry.maxAbsXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);\r\n }\r\n /** Return the sum of the angles in squared radians */\r\n public sumSquaredRadians(): number {\r\n return Geometry.hypotenuseSquaredXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);\r\n }\r\n /** Return the largest difference of angles (in radians) between this and other */\r\n public maxDiffRadians(other: YawPitchRollAngles): number {\r\n return Math.max(\r\n this.yaw.radians - other.yaw.radians,\r\n this.pitch.radians - other.pitch.radians,\r\n this.roll.radians - other.roll.radians\r\n );\r\n }\r\n /** Return the largest angle in degrees. */\r\n public maxAbsDegrees(): number {\r\n return Geometry.maxAbsXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees);\r\n }\r\n /** Return the sum of squared angles in degrees. */\r\n public sumSquaredDegrees(): number {\r\n return Geometry.hypotenuseSquaredXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees);\r\n }\r\n /** Return the largest difference of angles (in degrees) between this and other */\r\n public maxDiffDegrees(other: YawPitchRollAngles): number {\r\n return Math.max(\r\n this.yaw.degrees - other.yaw.degrees,\r\n this.pitch.degrees - other.pitch.degrees,\r\n this.roll.degrees - other.roll.degrees\r\n );\r\n }\r\n /** Return an object from a Transform as an origin and YawPitchRollAngles. */\r\n public static tryFromTransform(transform: Transform): {\r\n origin: Point3d;\r\n angles: YawPitchRollAngles | undefined;\r\n } {\r\n return {\r\n origin: Point3d.createFrom(transform.origin),\r\n angles: YawPitchRollAngles.createFromMatrix3d(transform.matrix),\r\n };\r\n }\r\n /** Attempts to create a YawPitchRollAngles object from a Matrix3d\r\n * * This conversion fails if the matrix is not rigid (unit rows and columns, and transpose is inverse)\r\n * * In the failure case the method's return value is `undefined`.\r\n * * In the failure case, if the optional result was supplied, that result will nonetheless be filled with\r\n * a set of angles.\r\n */\r\n public static createFromMatrix3d(matrix: Matrix3d, result?: YawPitchRollAngles): YawPitchRollAngles | undefined {\r\n /**\r\n * The rotation matrix for is\r\n *\r\n * Matrix3d.createRowValues(\r\n * cz * cy, -(sz * cx + cz * sy * sx), (sz * sx - cz * sy * cx),\r\n * sz * cy, (cz * cx - sz * sy * sx), -(cz * sx + sz * sy * cx),\r\n * sy, cy * sx, cy * cx\r\n * );\r\n *\r\n * where cx = cos(x), sx = sin(x), cy = cos(y), sy = sin(y), cz = cos(z), and sz = sin(z)\r\n */\r\n const sy = matrix.at(2, 0); // sin(y)\r\n const cy = Math.sqrt(matrix.at(2, 1) * matrix.at(2, 1) + matrix.at(2, 2) * matrix.at(2, 2)); // |cos(y)|\r\n const pitchA = Angle.createAtan2(sy, cy); // with positive cosine\r\n const pitchB = Angle.createAtan2(sy, -cy); // with negative cosine\r\n const angles = result ? result : new YawPitchRollAngles();\r\n /**\r\n * If cos(y) = 0 then y = +-90 degrees so we have a gimbal lock.\r\n * This means x and z can be anything as long as their sum x + z is constant.\r\n * so we can pick z = 0 and calculate x (or pick x = 0 and calculate z).\r\n * Math details can be found\r\n * https://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles\r\n *\r\n * The rotation matrix for y = +-90 degrees and x = 0 becomes\r\n *\r\n * Matrix3d.createRowValues(\r\n * 0, -sz, -+cz,\r\n * 0, cz, -+sz,\r\n * +-1, 0, 0\r\n * );\r\n *\r\n * so z = atan(sz/cz) = atan(-matrix.at(0, 1), matrix.at(1, 1))\r\n */\r\n if (cy < Geometry.smallAngleRadians) {\r\n angles.yaw = Angle.createAtan2(-matrix.at(0, 1), matrix.at(1, 1));\r\n angles.pitch = pitchA; // this is an arbitrary choice. can pick pitchB instead.\r\n angles.roll = Angle.createRadians(0.0);\r\n } else {\r\n /**\r\n * positive cosine\r\n * z = atan(sz/cz) = atan(matrix.at(1, 0), matrix.at(0, 0))\r\n * x = atan(sx/cx) = atan(matrix.at(2, 1), matrix.at(2, 2))\r\n */\r\n const yawA = Angle.createAtan2(matrix.at(1, 0), matrix.at(0, 0));\r\n const rollA = Angle.createAtan2(matrix.at(2, 1), matrix.at(2, 2));\r\n // similar with negative cosine\r\n const yawB = Angle.createAtan2(-matrix.at(1, 0), -matrix.at(0, 0));\r\n const rollB = Angle.createAtan2(-matrix.at(2, 1), -matrix.at(2, 2));\r\n // create YPR\r\n const yprA = new YawPitchRollAngles(yawA, pitchA, rollA);\r\n const yprB = new YawPitchRollAngles(yawB, pitchB, rollB);\r\n // decide to pick yprA or yprB with smallest magnitude angles\r\n const absFactor = 0.95;\r\n const maxRadiansA = yprA.maxAbsRadians();\r\n const maxRadiansB = yprB.maxAbsRadians();\r\n if (maxRadiansA < absFactor * maxRadiansB) {\r\n angles.setFrom(yprA);\r\n } else if (maxRadiansB < absFactor * maxRadiansA) {\r\n angles.setFrom(yprB);\r\n } else {\r\n const sumA = yprA.sumSquaredRadians();\r\n const sumB = yprB.sumSquaredRadians();\r\n if (sumA <= sumB) {\r\n angles.setFrom(yprA);\r\n } else {\r\n angles.setFrom(yprB);\r\n }\r\n }\r\n }\r\n // sanity check\r\n const matrix1 = angles.toMatrix3d();\r\n return matrix.maxDiff(matrix1) < Geometry.smallAngleRadians ? angles : undefined;\r\n }\r\n}\r\n"]}
|
|
@@ -524,6 +524,18 @@ export declare class SmallSystem {
|
|
|
524
524
|
azx: number, azy: number, azz: number, // second row of matrix
|
|
525
525
|
cx: number, cy: number, cz: number, // right side
|
|
526
526
|
result?: Vector3d): Vector3d | undefined;
|
|
527
|
+
/**
|
|
528
|
+
* Compute the intersection of three planes.
|
|
529
|
+
* @param xyzA point on the first plane
|
|
530
|
+
* @param normalA normal of the first plane
|
|
531
|
+
* @param xyzB point on the second plane
|
|
532
|
+
* @param normalB normal of the second plane
|
|
533
|
+
* @param xyzC point on the third plane
|
|
534
|
+
* @param normalC normal of the third plane
|
|
535
|
+
* @param result optional result
|
|
536
|
+
* @returns intersection point of the three planes (as a Vector3d), or undefined if at least two planes are parallel.
|
|
537
|
+
*/
|
|
538
|
+
static intersect3Planes(xyzA: Point3d, normalA: Vector3d, xyzB: Point3d, normalB: Vector3d, xyzC: Point3d, normalC: Vector3d, result?: Vector3d): Vector3d | undefined;
|
|
527
539
|
/**
|
|
528
540
|
* * in rowB, replace `rowB[j] += a * rowB[pivot] * rowA[j] / rowA[pivot]` for `j>pivot`
|
|
529
541
|
* @param rowA row that does not change
|