@itwin/core-geometry 5.0.0-dev.2 → 5.0.0-dev.22

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.
Files changed (278) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/lib/cjs/bspline/BSplineCurveOps.d.ts.map +1 -1
  3. package/lib/cjs/bspline/BSplineCurveOps.js +18 -21
  4. package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
  5. package/lib/cjs/curve/Arc3d.d.ts +30 -7
  6. package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
  7. package/lib/cjs/curve/Arc3d.js +53 -7
  8. package/lib/cjs/curve/Arc3d.js.map +1 -1
  9. package/lib/cjs/curve/CurveCollection.d.ts +16 -2
  10. package/lib/cjs/curve/CurveCollection.d.ts.map +1 -1
  11. package/lib/cjs/curve/CurveCollection.js +33 -2
  12. package/lib/cjs/curve/CurveCollection.js.map +1 -1
  13. package/lib/cjs/curve/CurveFactory.d.ts +81 -53
  14. package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
  15. package/lib/cjs/curve/CurveFactory.js +190 -103
  16. package/lib/cjs/curve/CurveFactory.js.map +1 -1
  17. package/lib/cjs/curve/LineString3d.d.ts +12 -8
  18. package/lib/cjs/curve/LineString3d.d.ts.map +1 -1
  19. package/lib/cjs/curve/LineString3d.js +29 -8
  20. package/lib/cjs/curve/LineString3d.js.map +1 -1
  21. package/lib/cjs/curve/Loop.d.ts +12 -6
  22. package/lib/cjs/curve/Loop.d.ts.map +1 -1
  23. package/lib/cjs/curve/Loop.js +12 -6
  24. package/lib/cjs/curve/Loop.js.map +1 -1
  25. package/lib/cjs/curve/Query/CylindricalRange.d.ts +8 -6
  26. package/lib/cjs/curve/Query/CylindricalRange.d.ts.map +1 -1
  27. package/lib/cjs/curve/Query/CylindricalRange.js +13 -9
  28. package/lib/cjs/curve/Query/CylindricalRange.js.map +1 -1
  29. package/lib/cjs/curve/StrokeOptions.d.ts +1 -1
  30. package/lib/cjs/curve/StrokeOptions.d.ts.map +1 -1
  31. package/lib/cjs/curve/StrokeOptions.js.map +1 -1
  32. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.d.ts.map +1 -1
  33. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.js +24 -18
  34. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.js.map +1 -1
  35. package/lib/cjs/geometry3d/AngleSweep.d.ts +1 -1
  36. package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
  37. package/lib/cjs/geometry3d/AngleSweep.js +1 -1
  38. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  39. package/lib/cjs/geometry3d/BarycentricTriangle.d.ts +14 -8
  40. package/lib/cjs/geometry3d/BarycentricTriangle.d.ts.map +1 -1
  41. package/lib/cjs/geometry3d/BarycentricTriangle.js +17 -8
  42. package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
  43. package/lib/cjs/geometry3d/FrameBuilder.js +4 -4
  44. package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
  45. package/lib/cjs/geometry3d/GrowableFloat64Array.d.ts +2 -0
  46. package/lib/cjs/geometry3d/GrowableFloat64Array.d.ts.map +1 -1
  47. package/lib/cjs/geometry3d/GrowableFloat64Array.js +4 -0
  48. package/lib/cjs/geometry3d/GrowableFloat64Array.js.map +1 -1
  49. package/lib/cjs/geometry3d/GrowableXYZArray.d.ts +32 -10
  50. package/lib/cjs/geometry3d/GrowableXYZArray.d.ts.map +1 -1
  51. package/lib/cjs/geometry3d/GrowableXYZArray.js +54 -16
  52. package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
  53. package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts +13 -2
  54. package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
  55. package/lib/cjs/geometry3d/IndexedXYZCollection.js +24 -10
  56. package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
  57. package/lib/cjs/geometry3d/Matrix3d.d.ts +11 -8
  58. package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
  59. package/lib/cjs/geometry3d/Matrix3d.js +28 -26
  60. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  61. package/lib/cjs/geometry3d/Point3dArrayCarrier.js +1 -1
  62. package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
  63. package/lib/cjs/geometry3d/Point3dVector3d.d.ts +6 -6
  64. package/lib/cjs/geometry3d/Point3dVector3d.js +6 -6
  65. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  66. package/lib/cjs/geometry3d/PolygonOps.d.ts +12 -6
  67. package/lib/cjs/geometry3d/PolygonOps.d.ts.map +1 -1
  68. package/lib/cjs/geometry3d/PolygonOps.js +94 -47
  69. package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
  70. package/lib/cjs/geometry3d/PolylineOps.d.ts +7 -4
  71. package/lib/cjs/geometry3d/PolylineOps.d.ts.map +1 -1
  72. package/lib/cjs/geometry3d/PolylineOps.js +7 -4
  73. package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
  74. package/lib/cjs/geometry4d/MomentData.d.ts +72 -73
  75. package/lib/cjs/geometry4d/MomentData.d.ts.map +1 -1
  76. package/lib/cjs/geometry4d/MomentData.js +62 -64
  77. package/lib/cjs/geometry4d/MomentData.js.map +1 -1
  78. package/lib/cjs/numerics/Polynomials.d.ts +5 -5
  79. package/lib/cjs/numerics/Polynomials.js +6 -6
  80. package/lib/cjs/numerics/Polynomials.js.map +1 -1
  81. package/lib/cjs/polyface/AuxData.d.ts +2 -2
  82. package/lib/cjs/polyface/AuxData.d.ts.map +1 -1
  83. package/lib/cjs/polyface/AuxData.js +11 -3
  84. package/lib/cjs/polyface/AuxData.js.map +1 -1
  85. package/lib/cjs/polyface/Polyface.d.ts +3 -5
  86. package/lib/cjs/polyface/Polyface.d.ts.map +1 -1
  87. package/lib/cjs/polyface/Polyface.js +6 -13
  88. package/lib/cjs/polyface/Polyface.js.map +1 -1
  89. package/lib/cjs/polyface/PolyfaceBuilder.d.ts +13 -6
  90. package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
  91. package/lib/cjs/polyface/PolyfaceBuilder.js +65 -38
  92. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  93. package/lib/cjs/polyface/PolyfaceData.d.ts +13 -3
  94. package/lib/cjs/polyface/PolyfaceData.d.ts.map +1 -1
  95. package/lib/cjs/polyface/PolyfaceData.js +21 -4
  96. package/lib/cjs/polyface/PolyfaceData.js.map +1 -1
  97. package/lib/cjs/polyface/PolyfaceQuery.d.ts +2 -2
  98. package/lib/cjs/polyface/PolyfaceQuery.d.ts.map +1 -1
  99. package/lib/cjs/polyface/PolyfaceQuery.js +4 -3
  100. package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
  101. package/lib/cjs/serialization/GeometrySamples.d.ts +5 -5
  102. package/lib/cjs/serialization/GeometrySamples.d.ts.map +1 -1
  103. package/lib/cjs/serialization/GeometrySamples.js +5 -5
  104. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  105. package/lib/cjs/solid/Box.d.ts +9 -3
  106. package/lib/cjs/solid/Box.d.ts.map +1 -1
  107. package/lib/cjs/solid/Box.js +10 -5
  108. package/lib/cjs/solid/Box.js.map +1 -1
  109. package/lib/cjs/solid/Cone.d.ts +3 -2
  110. package/lib/cjs/solid/Cone.d.ts.map +1 -1
  111. package/lib/cjs/solid/Cone.js +3 -3
  112. package/lib/cjs/solid/Cone.js.map +1 -1
  113. package/lib/cjs/solid/LinearSweep.d.ts +9 -3
  114. package/lib/cjs/solid/LinearSweep.d.ts.map +1 -1
  115. package/lib/cjs/solid/LinearSweep.js +9 -4
  116. package/lib/cjs/solid/LinearSweep.js.map +1 -1
  117. package/lib/cjs/solid/RotationalSweep.d.ts +15 -4
  118. package/lib/cjs/solid/RotationalSweep.d.ts.map +1 -1
  119. package/lib/cjs/solid/RotationalSweep.js +20 -7
  120. package/lib/cjs/solid/RotationalSweep.js.map +1 -1
  121. package/lib/cjs/solid/RuledSweep.d.ts +35 -26
  122. package/lib/cjs/solid/RuledSweep.d.ts.map +1 -1
  123. package/lib/cjs/solid/RuledSweep.js +41 -28
  124. package/lib/cjs/solid/RuledSweep.js.map +1 -1
  125. package/lib/cjs/solid/SolidPrimitive.d.ts +12 -11
  126. package/lib/cjs/solid/SolidPrimitive.d.ts.map +1 -1
  127. package/lib/cjs/solid/SolidPrimitive.js +8 -5
  128. package/lib/cjs/solid/SolidPrimitive.js.map +1 -1
  129. package/lib/cjs/solid/Sphere.d.ts +17 -7
  130. package/lib/cjs/solid/Sphere.d.ts.map +1 -1
  131. package/lib/cjs/solid/Sphere.js +22 -16
  132. package/lib/cjs/solid/Sphere.js.map +1 -1
  133. package/lib/cjs/solid/SweepContour.d.ts +1 -1
  134. package/lib/cjs/solid/SweepContour.js +1 -1
  135. package/lib/cjs/solid/SweepContour.js.map +1 -1
  136. package/lib/cjs/solid/TorusPipe.d.ts +8 -2
  137. package/lib/cjs/solid/TorusPipe.d.ts.map +1 -1
  138. package/lib/cjs/solid/TorusPipe.js +9 -5
  139. package/lib/cjs/solid/TorusPipe.js.map +1 -1
  140. package/lib/esm/bspline/BSplineCurveOps.d.ts.map +1 -1
  141. package/lib/esm/bspline/BSplineCurveOps.js +18 -21
  142. package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
  143. package/lib/esm/curve/Arc3d.d.ts +30 -7
  144. package/lib/esm/curve/Arc3d.d.ts.map +1 -1
  145. package/lib/esm/curve/Arc3d.js +53 -7
  146. package/lib/esm/curve/Arc3d.js.map +1 -1
  147. package/lib/esm/curve/CurveCollection.d.ts +16 -2
  148. package/lib/esm/curve/CurveCollection.d.ts.map +1 -1
  149. package/lib/esm/curve/CurveCollection.js +33 -2
  150. package/lib/esm/curve/CurveCollection.js.map +1 -1
  151. package/lib/esm/curve/CurveFactory.d.ts +81 -53
  152. package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
  153. package/lib/esm/curve/CurveFactory.js +190 -103
  154. package/lib/esm/curve/CurveFactory.js.map +1 -1
  155. package/lib/esm/curve/LineString3d.d.ts +12 -8
  156. package/lib/esm/curve/LineString3d.d.ts.map +1 -1
  157. package/lib/esm/curve/LineString3d.js +29 -8
  158. package/lib/esm/curve/LineString3d.js.map +1 -1
  159. package/lib/esm/curve/Loop.d.ts +12 -6
  160. package/lib/esm/curve/Loop.d.ts.map +1 -1
  161. package/lib/esm/curve/Loop.js +12 -6
  162. package/lib/esm/curve/Loop.js.map +1 -1
  163. package/lib/esm/curve/Query/CylindricalRange.d.ts +8 -6
  164. package/lib/esm/curve/Query/CylindricalRange.d.ts.map +1 -1
  165. package/lib/esm/curve/Query/CylindricalRange.js +13 -9
  166. package/lib/esm/curve/Query/CylindricalRange.js.map +1 -1
  167. package/lib/esm/curve/StrokeOptions.d.ts +1 -1
  168. package/lib/esm/curve/StrokeOptions.d.ts.map +1 -1
  169. package/lib/esm/curve/StrokeOptions.js.map +1 -1
  170. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.d.ts.map +1 -1
  171. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js +24 -18
  172. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js.map +1 -1
  173. package/lib/esm/geometry3d/AngleSweep.d.ts +1 -1
  174. package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
  175. package/lib/esm/geometry3d/AngleSweep.js +1 -1
  176. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  177. package/lib/esm/geometry3d/BarycentricTriangle.d.ts +14 -8
  178. package/lib/esm/geometry3d/BarycentricTriangle.d.ts.map +1 -1
  179. package/lib/esm/geometry3d/BarycentricTriangle.js +17 -8
  180. package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
  181. package/lib/esm/geometry3d/FrameBuilder.js +4 -4
  182. package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
  183. package/lib/esm/geometry3d/GrowableFloat64Array.d.ts +2 -0
  184. package/lib/esm/geometry3d/GrowableFloat64Array.d.ts.map +1 -1
  185. package/lib/esm/geometry3d/GrowableFloat64Array.js +4 -0
  186. package/lib/esm/geometry3d/GrowableFloat64Array.js.map +1 -1
  187. package/lib/esm/geometry3d/GrowableXYZArray.d.ts +32 -10
  188. package/lib/esm/geometry3d/GrowableXYZArray.d.ts.map +1 -1
  189. package/lib/esm/geometry3d/GrowableXYZArray.js +54 -16
  190. package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
  191. package/lib/esm/geometry3d/IndexedXYZCollection.d.ts +13 -2
  192. package/lib/esm/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
  193. package/lib/esm/geometry3d/IndexedXYZCollection.js +24 -10
  194. package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
  195. package/lib/esm/geometry3d/Matrix3d.d.ts +11 -8
  196. package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
  197. package/lib/esm/geometry3d/Matrix3d.js +28 -26
  198. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  199. package/lib/esm/geometry3d/Point3dArrayCarrier.js +1 -1
  200. package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
  201. package/lib/esm/geometry3d/Point3dVector3d.d.ts +6 -6
  202. package/lib/esm/geometry3d/Point3dVector3d.js +6 -6
  203. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  204. package/lib/esm/geometry3d/PolygonOps.d.ts +12 -6
  205. package/lib/esm/geometry3d/PolygonOps.d.ts.map +1 -1
  206. package/lib/esm/geometry3d/PolygonOps.js +94 -47
  207. package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
  208. package/lib/esm/geometry3d/PolylineOps.d.ts +7 -4
  209. package/lib/esm/geometry3d/PolylineOps.d.ts.map +1 -1
  210. package/lib/esm/geometry3d/PolylineOps.js +7 -4
  211. package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
  212. package/lib/esm/geometry4d/MomentData.d.ts +72 -73
  213. package/lib/esm/geometry4d/MomentData.d.ts.map +1 -1
  214. package/lib/esm/geometry4d/MomentData.js +62 -64
  215. package/lib/esm/geometry4d/MomentData.js.map +1 -1
  216. package/lib/esm/numerics/Polynomials.d.ts +5 -5
  217. package/lib/esm/numerics/Polynomials.js +6 -6
  218. package/lib/esm/numerics/Polynomials.js.map +1 -1
  219. package/lib/esm/polyface/AuxData.d.ts +2 -2
  220. package/lib/esm/polyface/AuxData.d.ts.map +1 -1
  221. package/lib/esm/polyface/AuxData.js +11 -3
  222. package/lib/esm/polyface/AuxData.js.map +1 -1
  223. package/lib/esm/polyface/Polyface.d.ts +3 -5
  224. package/lib/esm/polyface/Polyface.d.ts.map +1 -1
  225. package/lib/esm/polyface/Polyface.js +6 -13
  226. package/lib/esm/polyface/Polyface.js.map +1 -1
  227. package/lib/esm/polyface/PolyfaceBuilder.d.ts +13 -6
  228. package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
  229. package/lib/esm/polyface/PolyfaceBuilder.js +65 -38
  230. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  231. package/lib/esm/polyface/PolyfaceData.d.ts +13 -3
  232. package/lib/esm/polyface/PolyfaceData.d.ts.map +1 -1
  233. package/lib/esm/polyface/PolyfaceData.js +21 -4
  234. package/lib/esm/polyface/PolyfaceData.js.map +1 -1
  235. package/lib/esm/polyface/PolyfaceQuery.d.ts +2 -2
  236. package/lib/esm/polyface/PolyfaceQuery.d.ts.map +1 -1
  237. package/lib/esm/polyface/PolyfaceQuery.js +4 -3
  238. package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
  239. package/lib/esm/serialization/GeometrySamples.d.ts +5 -5
  240. package/lib/esm/serialization/GeometrySamples.d.ts.map +1 -1
  241. package/lib/esm/serialization/GeometrySamples.js +5 -5
  242. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  243. package/lib/esm/solid/Box.d.ts +9 -3
  244. package/lib/esm/solid/Box.d.ts.map +1 -1
  245. package/lib/esm/solid/Box.js +10 -5
  246. package/lib/esm/solid/Box.js.map +1 -1
  247. package/lib/esm/solid/Cone.d.ts +3 -2
  248. package/lib/esm/solid/Cone.d.ts.map +1 -1
  249. package/lib/esm/solid/Cone.js +3 -3
  250. package/lib/esm/solid/Cone.js.map +1 -1
  251. package/lib/esm/solid/LinearSweep.d.ts +9 -3
  252. package/lib/esm/solid/LinearSweep.d.ts.map +1 -1
  253. package/lib/esm/solid/LinearSweep.js +9 -4
  254. package/lib/esm/solid/LinearSweep.js.map +1 -1
  255. package/lib/esm/solid/RotationalSweep.d.ts +15 -4
  256. package/lib/esm/solid/RotationalSweep.d.ts.map +1 -1
  257. package/lib/esm/solid/RotationalSweep.js +20 -7
  258. package/lib/esm/solid/RotationalSweep.js.map +1 -1
  259. package/lib/esm/solid/RuledSweep.d.ts +35 -26
  260. package/lib/esm/solid/RuledSweep.d.ts.map +1 -1
  261. package/lib/esm/solid/RuledSweep.js +41 -28
  262. package/lib/esm/solid/RuledSweep.js.map +1 -1
  263. package/lib/esm/solid/SolidPrimitive.d.ts +12 -11
  264. package/lib/esm/solid/SolidPrimitive.d.ts.map +1 -1
  265. package/lib/esm/solid/SolidPrimitive.js +8 -5
  266. package/lib/esm/solid/SolidPrimitive.js.map +1 -1
  267. package/lib/esm/solid/Sphere.d.ts +17 -7
  268. package/lib/esm/solid/Sphere.d.ts.map +1 -1
  269. package/lib/esm/solid/Sphere.js +22 -16
  270. package/lib/esm/solid/Sphere.js.map +1 -1
  271. package/lib/esm/solid/SweepContour.d.ts +1 -1
  272. package/lib/esm/solid/SweepContour.js +1 -1
  273. package/lib/esm/solid/SweepContour.js.map +1 -1
  274. package/lib/esm/solid/TorusPipe.d.ts +8 -2
  275. package/lib/esm/solid/TorusPipe.d.ts.map +1 -1
  276. package/lib/esm/solid/TorusPipe.js +9 -5
  277. package/lib/esm/solid/TorusPipe.js.map +1 -1
  278. package/package.json +4 -4
@@ -5,7 +5,6 @@
5
5
  /** @packageDocumentation
6
6
  * @module Curve
7
7
  */
8
- // import { Geometry, Angle, AngleSweep } from "../Geometry";
9
8
  import { AxisIndex, AxisOrder, Geometry } from "../Geometry";
10
9
  import { Angle } from "../geometry3d/Angle";
11
10
  import { AngleSweep } from "../geometry3d/AngleSweep";
@@ -30,6 +29,7 @@ import { LineSegment3d } from "./LineSegment3d";
30
29
  import { LineString3d } from "./LineString3d";
31
30
  import { Loop } from "./Loop";
32
31
  import { Path } from "./Path";
32
+ import { RegionOps } from "./RegionOps";
33
33
  import { IntegratedSpiral3d } from "./spiral/IntegratedSpiral3d";
34
34
  /**
35
35
  * Enumeration of geometric output for [CurveFactory.createMiteredSweepSections].
@@ -44,12 +44,13 @@ export var MiteredSweepOutputSelect;
44
44
  /** Output planes and sections, as well as the assembled ruled sweep and its stroked mesh. */
45
45
  MiteredSweepOutputSelect[MiteredSweepOutputSelect["AlsoMesh"] = 2] = "AlsoMesh";
46
46
  })(MiteredSweepOutputSelect || (MiteredSweepOutputSelect = {}));
47
+ ;
47
48
  /**
48
49
  * The `CurveFactory` class contains methods for specialized curve constructions.
49
50
  * @public
50
51
  */
51
52
  export class CurveFactory {
52
- /** (cautiously) construct and save a line segment between fractional positions. */
53
+ /** (Cautiously) construct and save a line segment between fractional positions. */
53
54
  static addPartialSegment(path, allowBackup, pointA, pointB, fraction0, fraction1) {
54
55
  if (allowBackup || (fraction1 > fraction0)) {
55
56
  if (pointA !== undefined && pointB !== undefined && !Geometry.isAlmostEqualNumber(fraction0, fraction1))
@@ -146,10 +147,11 @@ export class CurveFactory {
146
147
  }
147
148
  return path;
148
149
  }
149
- /** Create a `Loop` with given xy corners and fixed z.
150
+ /**
151
+ * Create a `Loop` with given xy corners and fixed z.
150
152
  * * The corners always proceed counter clockwise from lower left.
151
153
  * * If the radius is too large for the outer rectangle size, it is reduced to half of the the smaller x or y size.
152
- */
154
+ */
153
155
  static createRectangleXY(x0, y0, x1, y1, z = 0, filletRadius) {
154
156
  let radius = Geometry.correctSmallMetricDistance(filletRadius);
155
157
  const xMin = Math.min(x0, x1);
@@ -158,7 +160,13 @@ export class CurveFactory {
158
160
  const yMax = Math.max(y0, y1);
159
161
  radius = Math.min(Math.abs(radius), 0.5 * (xMax - xMin), 0.5 * (yMax - yMin));
160
162
  if (radius === 0.0)
161
- return Loop.createPolygon([Point3d.create(xMin, yMin, z), Point3d.create(xMax, yMin, z), Point3d.create(xMax, yMax, z), Point3d.create(xMin, yMax, z), Point3d.create(xMin, yMin, z)]);
163
+ return Loop.createPolygon([
164
+ Point3d.create(xMin, yMin, z),
165
+ Point3d.create(xMax, yMin, z),
166
+ Point3d.create(xMax, yMax, z),
167
+ Point3d.create(xMin, yMax, z),
168
+ Point3d.create(xMin, yMin, z),
169
+ ]);
162
170
  else {
163
171
  const vectorU = Vector3d.create(radius, 0, 0);
164
172
  const vectorV = Vector3d.create(0, radius, 0);
@@ -166,7 +174,12 @@ export class CurveFactory {
166
174
  const y0A = yMin + radius;
167
175
  const x1A = xMax - radius;
168
176
  const y1A = yMax - radius;
169
- const centers = [Point3d.create(x1A, y1A, z), Point3d.create(x0A, y1A, z), Point3d.create(x0A, y0A, z), Point3d.create(x1A, y0A, z)];
177
+ const centers = [
178
+ Point3d.create(x1A, y1A, z),
179
+ Point3d.create(x0A, y1A, z),
180
+ Point3d.create(x0A, y0A, z),
181
+ Point3d.create(x1A, y0A, z),
182
+ ];
170
183
  const loop = Loop.create();
171
184
  for (let i = 0; i < 4; i++) {
172
185
  const center = centers[i];
@@ -186,10 +199,10 @@ export class CurveFactory {
186
199
  /**
187
200
  * If `arcB` is a continuation of `arcA`, extend `arcA` (in place) to include the range of `arcB`
188
201
  * * This only succeeds if the two arcs are part of identical complete arcs and end of `arcA` matches the beginning of `arcB`.
189
- * @param arcA first arc, modified in place
190
- * @param arcB second arc, unmodified
191
- * @param allowReversed whether to consolidate even when second arc is reversed
192
- * @returns whether `arcA` was modified
202
+ * @param arcA first arc, modified in place.
203
+ * @param arcB second arc, unmodified.
204
+ * @param allowReversed whether to consolidate even when second arc is reversed.
205
+ * @returns whether `arcA` was modified.
193
206
  */
194
207
  static appendToArcInPlace(arcA, arcB, allowReverse = false) {
195
208
  if (arcA.center.isAlmostEqual(arcB.center)) {
@@ -205,7 +218,7 @@ export class CurveFactory {
205
218
  arcA.sweep.setStartEndRadians(arcA.sweep.startRadians, arcA.sweep.startRadians + arcA.sweep.sweepRadians + sweepSign * arcB.sweep.sweepRadians);
206
219
  return true;
207
220
  }
208
- // Also ok if negated tangent . ..
221
+ // Also ok if negated tangent
209
222
  if (allowReverse) {
210
223
  startB.direction.scaleInPlace(-1.0);
211
224
  if (endA.isAlmostEqual(startB)) {
@@ -218,7 +231,8 @@ export class CurveFactory {
218
231
  }
219
232
  /**
220
233
  * Return a `Path` containing arcs are on the surface of an ellipsoid and pass through a sequence of points.
221
- * * Each arc passes through the two given endpoints and in the plane containing the true surface normal at given `fractionForIntermediateNormal`
234
+ * * Each arc passes through the two given endpoints and in the plane containing the true surface normal at
235
+ * given `fractionForIntermediateNormal`
222
236
  * @param ellipsoid
223
237
  * @param pathPoints
224
238
  * @param fractionForIntermediateNormal fractional position for surface normal used to create the section plane.
@@ -241,7 +255,7 @@ export class CurveFactory {
241
255
  }
242
256
  /**
243
257
  * Create solid primitives for pipe segments (e.g. Cone or TorusPipe) around line and arc primitives.
244
- * @param centerline centerline geometry/
258
+ * @param centerline centerline geometry.
245
259
  * @param pipeRadius radius of pipe.
246
260
  */
247
261
  static createPipeSegments(centerline, pipeRadius) {
@@ -267,16 +281,22 @@ export class CurveFactory {
267
281
  return undefined;
268
282
  }
269
283
  /**
270
- * * Create section arcs for mitered pipe.
271
- * * At each end of each pipe, the pipe is cut by the plane that bisects the angle between successive pipe centerlines.
272
- * * The arc definitions are constructed so that lines between corresponding fractional positions on the arcs are
273
- * axial lines on the pipes.
274
- * * This means that each arc definition axes (aka vector0 and vector90) are _not_ perpendicular to each other.
275
- * * Circular or elliptical pipe cross sections can be specified by supplying either a radius, a pair of semi-axis lengths, or a full Arc3d.
276
- * * For semi-axis length input, x corresponds to an ellipse local axis nominally situated parallel to the xy-plane.
277
- * * The center of Arc3d input is translated to the centerline start point to act as initial cross section.
278
- * @param centerline centerline of pipe
279
- * @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d
284
+ * Create section arcs for mitered pipe.
285
+ * * At the end of each pipe segment, the pipe is mitered by the plane that bisects the angle between successive
286
+ * centerline segments.
287
+ * * The section arcs are constructed so that lines between corresponding fractional positions on the arcs are
288
+ * axial lines on the pipes.
289
+ * * This means that the initial arc's vector0 and vector90 lengths and angular separation are _not_ preserved in
290
+ * the section arcs.
291
+ * * Circular or elliptical pipe cross sections can be specified by supplying either a radius, a pair of semi-axis
292
+ * lengths, or an Arc3d:
293
+ * * For semi-axis length input, x and y correspond to ellipse local axes perpendicular to each other and to the
294
+ * start tangent.
295
+ * * For Arc3d input, the center is translated to the centerline start point, but otherwise the arc is used as-is
296
+ * for the first section. For best results, the arc should be perpendicular to the centerline start tangent.
297
+ * @param centerline centerline of pipe. For best results, ensure no successive duplicate points with e.g.,
298
+ * [[GrowableXYZArray.createCompressed]].
299
+ * @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d (if not full, function makes it full).
280
300
  */
281
301
  static createMiteredPipeSections(centerline, sectionData) {
282
302
  const arcs = [];
@@ -285,15 +305,15 @@ export class CurveFactory {
285
305
  const vector0 = Vector3d.create();
286
306
  const vector90 = Vector3d.create();
287
307
  const vectorBC = Vector3d.create();
288
- const currentCenter = Point3d.create();
289
- centerline.vectorIndexIndex(0, 1, vectorBC);
290
- centerline.getPoint3dAtUncheckedPointIndex(0, currentCenter);
291
- let initialSection;
308
+ const sweep = AngleSweep.create360();
309
+ centerline.vectorIndexIndex(0, 1, vectorBC); // initially, the start tangent
292
310
  if (sectionData instanceof Arc3d) {
293
- initialSection = sectionData.clone();
294
- initialSection.center.setFrom(currentCenter);
295
311
  vector0.setFrom(sectionData.vector0);
296
312
  vector90.setFrom(sectionData.vector90);
313
+ sweep.setFrom(sectionData.sweep); // allow e.g., half-pipe
314
+ const sectionFacesForward = sectionData.matrixRef.columnDotXYZ(AxisIndex.Z, vectorBC.x, vectorBC.y, vectorBC.z) > 0;
315
+ if (sectionFacesForward !== sectionData.sweep.isCCW)
316
+ sweep.reverseInPlace();
297
317
  }
298
318
  else if (typeof sectionData === "number" || Point3d.isXAndY(sectionData)) {
299
319
  const length0 = (typeof sectionData === "number") ? sectionData : sectionData.x;
@@ -301,87 +321,161 @@ export class CurveFactory {
301
321
  const baseFrame = Matrix3d.createRigidHeadsUp(vectorBC, AxisOrder.ZXY);
302
322
  baseFrame.columnX(vector0).scaleInPlace(length0);
303
323
  baseFrame.columnY(vector90).scaleInPlace(length90);
304
- initialSection = Arc3d.create(currentCenter, vector0, vector90, AngleSweep.create360());
305
324
  }
306
325
  else {
307
326
  return [];
308
327
  }
328
+ // ASSUME: initial section normal points toward sweep direction for subsequent facet creation
329
+ const initialSection = Arc3d.create(undefined, vector0, vector90, sweep);
330
+ centerline.getPoint3dAtUncheckedPointIndex(0, initialSection.centerRef);
309
331
  arcs.push(initialSection);
310
332
  const vectorAB = Vector3d.create();
311
333
  const bisector = Vector3d.create();
334
+ const center = Point3d.create();
312
335
  for (let i = 1; i < centerline.length; i++) {
313
336
  vectorAB.setFromVector3d(vectorBC);
314
- centerline.getPoint3dAtUncheckedPointIndex(i, currentCenter);
315
- if (i + 1 < centerline.length) {
337
+ centerline.getPoint3dAtUncheckedPointIndex(i, center);
338
+ if (i + 1 < centerline.length)
316
339
  centerline.vectorIndexIndex(i, i + 1, vectorBC);
317
- }
318
- else {
340
+ else
319
341
  vectorBC.setFromVector3d(vectorAB);
320
- }
321
342
  if (vectorAB.normalizeInPlace() && vectorBC.normalizeInPlace()) {
322
343
  vectorAB.interpolate(0.5, vectorBC, bisector);
323
- // On the end ellipse for this pipe section. ..
324
- // center comes directly from centerline[i]
325
- // vector0 and vector90 are obtained by sweeping the corresponding vectors of the start ellipse to the split plane.
344
+ // At pipe end, the ellipse center comes directly from centerline[i], and vector0/vector90 are
345
+ // obtained by sweeping the corresponding vectors of the pipe start ellipse to the bisector plane.
326
346
  moveVectorToPlane(vector0, vectorAB, bisector, vector0);
327
347
  moveVectorToPlane(vector90, vectorAB, bisector, vector90);
328
- arcs.push(Arc3d.create(currentCenter, vector0, vector90, AngleSweep.create360()));
348
+ arcs.push(Arc3d.create(center, vector0, vector90, sweep));
329
349
  }
330
350
  }
331
351
  return arcs;
332
352
  }
353
+ /** For a smooth curve, stroke and return unnormalized start/end tangents. */
354
+ static strokeSmoothCurve(curve, options) {
355
+ let startTangent, endTangent;
356
+ if (curve instanceof CurvePrimitive) {
357
+ startTangent = curve.fractionToPointAndDerivative(0.0).direction;
358
+ endTangent = curve.fractionToPointAndDerivative(1.0).direction;
359
+ const strokes = LineString3d.create();
360
+ curve.emitStrokes(strokes, options);
361
+ curve = strokes.packedPoints;
362
+ }
363
+ else if (curve instanceof CurveChain) {
364
+ startTangent = curve.startPointAndDerivative()?.direction;
365
+ endTangent = curve.endPointAndDerivative()?.direction;
366
+ const strokes = curve.getPackedStrokes(options);
367
+ if (!strokes)
368
+ return undefined;
369
+ curve = strokes;
370
+ }
371
+ else if (Array.isArray(curve))
372
+ curve = new Point3dArrayCarrier(curve);
373
+ return { strokes: curve, startTangent, endTangent };
374
+ }
375
+ /**
376
+ * Align two bisector plane normals to given smooth rail tangents or optional overrides.
377
+ * * Optionally average the normals for physically closed rail.
378
+ */
379
+ static alignFirstAndLastBisectorPlanes(firstPlane, lastPlane, smoothRailData, options) {
380
+ const normal0 = options?.startTangent ?? (smoothRailData?.startTangent ?? firstPlane.getNormalRef());
381
+ const normal1 = options?.endTangent ?? (smoothRailData?.endTangent ?? lastPlane.getNormalRef());
382
+ if (options?.wrapIfPhysicallyClosed && firstPlane.getOriginRef().isAlmostEqual(lastPlane.getOriginRef())) {
383
+ const avgNormal = normal0.plus(normal1);
384
+ if (avgNormal.tryNormalizeInPlace()) { // ignore cusp at seam
385
+ firstPlane.getNormalRef().setFrom(avgNormal);
386
+ lastPlane.getNormalRef().setFrom(avgNormal);
387
+ return;
388
+ }
389
+ }
390
+ if (normal0.tryNormalizeInPlace())
391
+ firstPlane.getNormalRef().setFrom(normal0);
392
+ if (normal1.tryNormalizeInPlace())
393
+ lastPlane.getNormalRef().setFrom(normal1);
394
+ }
395
+ /** Reverse a closed curve or region if necessary so that its orientation is CCW with respect to the plane normal. */
396
+ static alignClosedCurveToPlane(curve, planeNormal) {
397
+ let closedCurve;
398
+ if (curve instanceof CurvePrimitive) {
399
+ if (curve.startPoint().isAlmostEqual(curve.endPoint()))
400
+ closedCurve = Loop.create(curve);
401
+ }
402
+ else if (curve.isAnyRegion())
403
+ closedCurve = curve;
404
+ if (closedCurve) {
405
+ // The alignment condition is equivalent to positive projected curve area computed wrt to the plane normal.
406
+ const toLocal = Matrix3d.createRigidHeadsUp(planeNormal).transpose();
407
+ const projection = closedCurve.cloneTransformed(Transform.createOriginAndMatrix(undefined, toLocal));
408
+ if (projection) { // now we can ignore z-coords
409
+ const areaXY = RegionOps.computeXYArea(projection);
410
+ if (areaXY && areaXY < 0)
411
+ curve.reverseInPlace();
412
+ }
413
+ }
414
+ }
333
415
  /**
334
- * Sweep the initialSection along each segment of the centerLine until it hits the bisector plane at the next vertex.
335
- * * The caller should place the initialSection on a plane perpendicular to the first edge.
336
- * * This plane is commonly (but not necessarily) through the start point itself.
337
- * * If the geometry is not "on a perpendicular plane", the output geometry will still be flattened onto the various planes.
338
- * * In the "open path" case (i.e when wrapIfPhysicallyClosed is false or the path does not have matched first and last points)
339
- * the first/last output plane will be at the start/end of the first/last edge and on a perpendicular plane.
340
- * * In the "closed path" case, the output plane for the first and last point is the bisector of the start and end planes from the "open path" case,
341
- * and the first/last section geometry may be different from `initialSection`.
342
- * * The centerline path does NOT have to be planar, however twisting effects effects will appear in the various bisector planes.
343
- * @param centerline sweep path, e.g., as stroked from a smooth centerline curve
344
- * @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the first segment of the centerline.
345
- * @param options options for computation and output
346
- * @return array of sections, starting with `initialSection` projected along the first edge to the first plane.
416
+ * Projection to target plane, constructing sweep direction from two given planes.
417
+ * * If successful, push the target plane and swept section to the output arrays and return the swept section.
418
+ * * If unsuccessful, leave the output arrays alone and return the input section.
419
+ */
420
+ static doSweepToPlane(output, edgePlane0, edgePlane1, targetPlane, section) {
421
+ const sweepVector = Vector3d.createStartEnd(edgePlane0.getOriginRef(), edgePlane1.getOriginRef());
422
+ const transform = Transform.createFlattenAlongVectorToPlane(sweepVector, targetPlane.getOriginRef(), targetPlane.getNormalRef());
423
+ if (transform === undefined)
424
+ return section;
425
+ const transformedSection = section.cloneTransformed(transform);
426
+ if (transformedSection === undefined)
427
+ return section;
428
+ output.planes.push(targetPlane);
429
+ output.sections.push(transformedSection);
430
+ return transformedSection;
431
+ }
432
+ /**
433
+ * Sweep the `initialSection` along each segment of the (stroked) `centerline` until it hits the bisector plane at
434
+ * the next vertex.
435
+ * * For best results, the caller should place `initialSection` in a plane perpendicular to the `centerline`
436
+ * start tangent.
437
+ * * This plane is commonly (but not necessarily) through the centerline start point itself.
438
+ * * To compute the sections, `initialSection` is projected in the direction of the centerline start tangent onto
439
+ * the first bisector plane at the centerline start. The result of this projection will be likewise projected onto
440
+ * the second plane, and so on in sequence.
441
+ * * By default, the first/last bisector plane normals are set to the centerline start/end tangents. The caller can
442
+ * override these with tangents supplied in `options`. If the centerline is physically closed and
443
+ * `options.wrapIfPhysicallyClosed` is true, the first and last plane normals are averaged and equated.
444
+ * * The centerline path does NOT have to be planar, however non-planarity will result in twisting of the sections
445
+ * in the bisector planes.
446
+ * @param centerline sweep path. Will be stroked if smooth.
447
+ * @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the
448
+ * centerline start tangent.
449
+ * @param options options for computation and output.
450
+ * @return array of sections, formed from projecting `initialSection` successively onto the bisector planes.
347
451
  */
348
452
  static createMiteredSweepSections(centerline, initialSection, options) {
453
+ const rail = this.strokeSmoothCurve(centerline, options.strokeOptions);
454
+ if (!rail)
455
+ return undefined;
456
+ const planes = PolylineOps.createBisectorPlanesForDistinctPoints(rail.strokes);
457
+ if (!planes || planes.length < 2)
458
+ return undefined;
459
+ this.alignFirstAndLastBisectorPlanes(planes[0], planes[planes.length - 1], rail, options);
460
+ // RuledSweep facet construction assumes the contours are oriented CCW with respect to the sweep direction so that
461
+ // facet normals point outward. We only have to align the first contour; the rest will inherit its orientation.
462
+ this.alignClosedCurveToPlane(initialSection, planes[0].getNormalRef());
349
463
  const sectionData = { sections: [], planes: [] };
350
- const planes = PolylineOps.createBisectorPlanesForDistinctPoints(centerline, options.wrapIfPhysicallyClosed);
351
- if (planes !== undefined && planes.length > 1) {
352
- // Projection to target plane, constructing sweep direction from two given planes.
353
- // If successful, push the target plane and swept section to the output arrays and return the swept section.
354
- // If unsuccessful, leave the output arrays alone and return the input section.
355
- const doSweepToPlane = function (edgePlane0, edgePlane1, targetPlane, section) {
356
- const sweepVector = Vector3d.createStartEnd(edgePlane0.getOriginRef(), edgePlane1.getOriginRef());
357
- const transform = Transform.createFlattenAlongVectorToPlane(sweepVector, targetPlane.getOriginRef(), targetPlane.getNormalRef());
358
- if (transform === undefined)
359
- return section;
360
- const section1 = section.cloneTransformed(transform);
361
- if (section1 === undefined)
362
- return section;
363
- sectionData.planes.push(targetPlane);
364
- sectionData.sections.push(section1);
365
- return section1;
366
- };
367
- let currentSection = doSweepToPlane(planes[0], planes[1], planes[0], initialSection);
368
- for (let i = 1; i < planes.length; i++) {
369
- currentSection = doSweepToPlane(planes[i - 1], planes[i], planes[i], currentSection);
370
- }
371
- if (options.outputSelect) {
372
- const ruledSweep = RuledSweep.create(sectionData.sections, options.capped ?? false);
373
- if (ruledSweep) {
374
- sectionData.ruledSweep = ruledSweep;
375
- if (MiteredSweepOutputSelect.AlsoMesh === options.outputSelect) {
376
- const builder = PolyfaceBuilder.create(options.strokeOptions);
377
- builder.addRuledSweep(ruledSweep);
378
- sectionData.mesh = builder.claimPolyface();
379
- }
464
+ let currentSection = this.doSweepToPlane(sectionData, planes[0], planes[1], planes[0], initialSection);
465
+ for (let i = 1; i < planes.length; i++)
466
+ currentSection = this.doSweepToPlane(sectionData, planes[i - 1], planes[i], planes[i], currentSection);
467
+ if (options.outputSelect) {
468
+ const ruledSweep = RuledSweep.create(sectionData.sections, options.capped ?? false);
469
+ if (ruledSweep) {
470
+ sectionData.ruledSweep = ruledSweep;
471
+ if (MiteredSweepOutputSelect.AlsoMesh === options.outputSelect) {
472
+ const builder = PolyfaceBuilder.create(options.strokeOptions);
473
+ builder.addRuledSweep(ruledSweep);
474
+ sectionData.mesh = builder.claimPolyface();
380
475
  }
381
476
  }
382
- return sectionData;
383
477
  }
384
- return undefined;
478
+ return sectionData;
385
479
  }
386
480
  /**
387
481
  * Create a circular arc from start point, tangent at start, radius, optional plane normal, arc sweep.
@@ -398,11 +492,11 @@ export class CurveFactory {
398
492
  /**
399
493
  * Compute 2 spirals (all in XY) for a symmetric line-to-line transition.
400
494
  * * First spiral begins at given start point.
401
- * * first tangent aims at shoulder
495
+ * * first tangent aims at shoulder.
402
496
  * * outbound spiral joins line from shoulder to target.
403
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
497
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
404
498
  * @param startPoint inbound start point.
405
- * @param shoulder point target point for (both) spiral-to-line tangencies
499
+ * @param shoulder point target point for (both) spiral-to-line tangencies.
406
500
  * @return array with the computed spirals, or undefined if failure.
407
501
  */
408
502
  static createLineSpiralSpiralLine(spiralType, startPoint, shoulderPoint, targetPoint) {
@@ -440,9 +534,9 @@ export class CurveFactory {
440
534
  * Compute 2 spirals (all in XY) for a symmetric line-to-line transition.
441
535
  * * Spiral length is given.
442
536
  * * tangency points float on both lines.
443
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
537
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
444
538
  * @param pointA inbound start point.
445
- * @param shoulder point target point for (both) spiral-to-line tangencies
539
+ * @param shoulder point target point for (both) spiral-to-line tangencies.
446
540
  * @param spiralLength for each part of the spiral pair.
447
541
  * @return array with the computed spirals, or undefined if failure.
448
542
  */
@@ -480,12 +574,12 @@ export class CurveFactory {
480
574
  }
481
575
  /**
482
576
  * Compute 2 spirals and an arc (all in XY) for a symmetric line-to-line transition.
483
- * Spiral lengths and arc radius are given. (e.g. from design speed standards.)
484
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
577
+ * Spiral lengths and arc radius are given (e.g., from design speed standards).
578
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
485
579
  * @param pointA inbound start point.
486
- * @param pointB shoulder (target) point for (both) spiral-to-line tangencies
487
- * @param lengthA inbound spiral length
488
- * @param lengthB outbound spiral length
580
+ * @param pointB shoulder (target) point for (both) spiral-to-line tangencies.
581
+ * @param lengthA inbound spiral length.
582
+ * @param lengthB outbound spiral length.
489
583
  * @return array with the computed spirals, or undefined if failure.
490
584
  */
491
585
  static createLineSpiralArcSpiralLine(spiralType, pointA, pointB, pointC, lengthA, lengthB, arcRadius) {
@@ -535,12 +629,7 @@ export class CurveFactory {
535
629
  }
536
630
  return undefined;
537
631
  }
538
- /**
539
- * Return the intersection point of 3 planes.
540
- * @param planeA
541
- * @param planeB
542
- * @param planeC
543
- */
632
+ /** Return the intersection point of 3 planes. */
544
633
  static planePlaneIntersectionRay(planeA, planeB) {
545
634
  const altitudeA = planeA.altitudeXYZ(0, 0, 0);
546
635
  const altitudeB = planeB.altitudeXYZ(0, 0, 0);
@@ -560,9 +649,7 @@ export class CurveFactory {
560
649
  return undefined;
561
650
  }
562
651
  }
563
- /**
564
- * Starting at vectorR, move parallel to vectorV until perpendicular to planeNormal
565
- */
652
+ /** Starting at vectorR, move parallel to vectorV until perpendicular to planeNormal. */
566
653
  function moveVectorToPlane(vectorR, vectorV, planeNormal, result) {
567
654
  // find s such that (vectorR + s * vectorV) DOT planeNormal = 0.
568
655
  const dotRN = vectorR.dotProduct(planeNormal);