@jscad/modeling 2.7.2 → 2.9.1

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 (238) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/jscad-modeling.min.js +443 -398
  3. package/package.json +2 -2
  4. package/src/curves/bezier/tangentAt.test.js +1 -1
  5. package/src/curves/bezier/valueAt.test.js +1 -1
  6. package/src/geometries/geom2/index.d.ts +1 -0
  7. package/src/geometries/geom2/index.js +12 -1
  8. package/src/geometries/geom2/isA.js +2 -2
  9. package/src/geometries/geom2/toCompactBinary.js +4 -4
  10. package/src/geometries/geom2/toString.js +1 -1
  11. package/src/geometries/geom2/transform.test.js +1 -1
  12. package/src/geometries/geom2/validate.d.ts +3 -0
  13. package/src/geometries/geom2/validate.js +36 -0
  14. package/src/geometries/geom3/fromCompactBinary.js +1 -1
  15. package/src/geometries/geom3/index.d.ts +1 -0
  16. package/src/geometries/geom3/index.js +19 -1
  17. package/src/geometries/geom3/isA.js +2 -2
  18. package/src/geometries/geom3/toCompactBinary.js +4 -4
  19. package/src/geometries/geom3/toString.js +1 -1
  20. package/src/geometries/geom3/transform.test.js +1 -1
  21. package/src/geometries/geom3/validate.d.ts +3 -0
  22. package/src/geometries/geom3/validate.js +62 -0
  23. package/src/geometries/index.js +8 -1
  24. package/src/geometries/path2/eachPoint.js +3 -3
  25. package/src/geometries/path2/index.d.ts +1 -0
  26. package/src/geometries/path2/index.js +13 -1
  27. package/src/geometries/path2/isA.js +2 -2
  28. package/src/geometries/path2/reverse.js +4 -4
  29. package/src/geometries/path2/toCompactBinary.js +6 -6
  30. package/src/geometries/path2/toString.js +1 -1
  31. package/src/geometries/path2/transform.test.js +1 -1
  32. package/src/geometries/path2/validate.d.ts +3 -0
  33. package/src/geometries/path2/validate.js +41 -0
  34. package/src/geometries/poly2/arePointsInside.js +0 -35
  35. package/src/geometries/poly2/arePointsInside.test.js +1 -1
  36. package/src/geometries/poly2/index.js +6 -0
  37. package/src/geometries/poly3/index.d.ts +1 -0
  38. package/src/geometries/poly3/index.js +9 -2
  39. package/src/geometries/poly3/invert.js +7 -1
  40. package/src/geometries/poly3/isA.js +2 -2
  41. package/src/geometries/poly3/isConvex.js +2 -2
  42. package/src/geometries/poly3/measureArea.js +4 -4
  43. package/src/geometries/poly3/measureArea.test.js +16 -16
  44. package/src/geometries/poly3/measureBoundingBox.js +2 -2
  45. package/src/geometries/poly3/measureBoundingSphere.js +2 -2
  46. package/src/geometries/poly3/measureBoundingSphere.test.js +8 -8
  47. package/src/geometries/poly3/measureSignedVolume.js +4 -4
  48. package/src/geometries/poly3/toPoints.js +2 -2
  49. package/src/geometries/poly3/toString.js +2 -2
  50. package/src/geometries/poly3/transform.js +2 -2
  51. package/src/geometries/poly3/validate.d.ts +4 -0
  52. package/src/geometries/poly3/validate.js +50 -0
  53. package/src/maths/index.js +1 -1
  54. package/src/maths/line2/equals.js +2 -2
  55. package/src/maths/line2/fromValues.js +2 -2
  56. package/src/maths/line2/intersectPointOfLines.js +1 -1
  57. package/src/maths/line2/intersectPointOfLines.test.js +1 -1
  58. package/src/maths/line2/reverse.test.js +1 -1
  59. package/src/maths/line2/transform.test.js +1 -1
  60. package/src/maths/line3/equals.js +2 -2
  61. package/src/maths/line3/reverse.test.js +1 -1
  62. package/src/maths/line3/transform.test.js +1 -1
  63. package/src/maths/mat4/fromVectorRotation.js +1 -1
  64. package/src/maths/mat4/fromVectorRotation.test.js +1 -1
  65. package/src/maths/mat4/identity.test.js +1 -1
  66. package/src/maths/mat4/invert.js +18 -18
  67. package/src/maths/mat4/isIdentity.js +1 -1
  68. package/src/maths/mat4/isMirroring.js +4 -4
  69. package/src/maths/mat4/isMirroring.test.js +1 -1
  70. package/src/maths/mat4/leftMultiplyVec3.js +2 -2
  71. package/src/maths/mat4/toString.js +2 -2
  72. package/src/maths/mat4/translate.test.js +1 -1
  73. package/src/maths/plane/flip.test.js +1 -1
  74. package/src/maths/plane/fromPoints.d.ts +1 -1
  75. package/src/maths/plane/fromPoints.js +1 -3
  76. package/src/maths/plane/signedDistanceToPoint.js +1 -1
  77. package/src/maths/plane/transform.test.js +1 -1
  78. package/src/maths/utils/aboutEqualNormals.js +2 -2
  79. package/src/maths/vec2/abs.d.ts +1 -1
  80. package/src/maths/vec2/add.test.js +1 -1
  81. package/src/maths/vec2/angleDegrees.d.ts +1 -1
  82. package/src/maths/vec2/angleRadians.d.ts +1 -1
  83. package/src/maths/vec2/create.js +1 -1
  84. package/src/maths/vec2/cross.test.js +1 -1
  85. package/src/maths/vec2/divide.test.js +1 -1
  86. package/src/maths/vec2/fromAngleDegrees.js +1 -1
  87. package/src/maths/vec2/fromScalar.js +1 -1
  88. package/src/maths/vec2/length.d.ts +1 -1
  89. package/src/maths/vec2/length.js +1 -1
  90. package/src/maths/vec2/lerp.test.js +1 -1
  91. package/src/maths/vec2/multiply.test.js +1 -1
  92. package/src/maths/vec2/negate.test.js +1 -1
  93. package/src/maths/vec2/normal.js +1 -1
  94. package/src/maths/vec2/normalize.d.ts +1 -1
  95. package/src/maths/vec2/normalize.test.js +1 -1
  96. package/src/maths/vec2/rotate.test.js +1 -1
  97. package/src/maths/vec2/squaredLength.d.ts +1 -1
  98. package/src/maths/vec2/squaredLength.js +3 -3
  99. package/src/maths/vec2/subtract.test.js +1 -1
  100. package/src/maths/vec2/toString.js +1 -1
  101. package/src/maths/vec2/transform.test.js +1 -1
  102. package/src/maths/vec3/abs.d.ts +1 -1
  103. package/src/maths/vec3/add.test.js +1 -1
  104. package/src/maths/vec3/cross.test.js +1 -1
  105. package/src/maths/vec3/divide.test.js +1 -1
  106. package/src/maths/vec3/fromScalar.js +1 -1
  107. package/src/maths/vec3/fromVec2.d.ts +1 -1
  108. package/src/maths/vec3/fromVec2.js +3 -3
  109. package/src/maths/vec3/length.d.ts +1 -1
  110. package/src/maths/vec3/length.js +4 -4
  111. package/src/maths/vec3/lerp.test.js +1 -1
  112. package/src/maths/vec3/multiply.test.js +1 -1
  113. package/src/maths/vec3/negate.d.ts +1 -1
  114. package/src/maths/vec3/negate.test.js +1 -1
  115. package/src/maths/vec3/normalize.d.ts +1 -1
  116. package/src/maths/vec3/normalize.test.js +1 -1
  117. package/src/maths/vec3/rotateX.test.js +1 -1
  118. package/src/maths/vec3/rotateY.test.js +1 -1
  119. package/src/maths/vec3/rotateZ.test.js +1 -1
  120. package/src/maths/vec3/scale.test.js +1 -1
  121. package/src/maths/vec3/squaredLength.d.ts +1 -1
  122. package/src/maths/vec3/squaredLength.js +4 -4
  123. package/src/maths/vec3/subtract.test.js +1 -1
  124. package/src/maths/vec3/toString.js +1 -1
  125. package/src/maths/vec3/transform.test.js +1 -1
  126. package/src/maths/vec4/toString.js +1 -1
  127. package/src/maths/vec4/transform.test.js +1 -1
  128. package/src/measurements/measureBoundingSphere.js +4 -4
  129. package/src/measurements/measureCenterOfMass.js +1 -1
  130. package/src/measurements/measureCenterOfMass.test.js +2 -2
  131. package/src/operations/booleans/intersect.test.js +8 -0
  132. package/src/operations/booleans/mayOverlap.js +3 -3
  133. package/src/operations/booleans/retessellate.js +2 -2
  134. package/src/operations/booleans/scission.js +1 -1
  135. package/src/operations/booleans/scission.test.js +4 -4
  136. package/src/operations/booleans/subtract.js +1 -1
  137. package/src/operations/booleans/subtract.test.js +8 -0
  138. package/src/operations/booleans/trees/Node.js +10 -16
  139. package/src/operations/booleans/trees/PolygonTreeNode.js +13 -14
  140. package/src/operations/booleans/trees/Tree.js +1 -2
  141. package/src/operations/booleans/trees/splitPolygonByPlane.js +2 -3
  142. package/src/operations/booleans/union.test.js +28 -1
  143. package/src/operations/booleans/unionGeom3Sub.js +1 -1
  144. package/src/operations/expansions/expand.js +2 -2
  145. package/src/operations/expansions/expand.test.js +32 -55
  146. package/src/operations/expansions/expandShell.js +24 -18
  147. package/src/operations/expansions/offset.js +1 -1
  148. package/src/operations/expansions/offset.test.js +50 -89
  149. package/src/operations/expansions/offsetFromPoints.js +11 -6
  150. package/src/operations/extrusions/earcut/assignHoles.js +91 -0
  151. package/src/operations/extrusions/earcut/assignHoles.test.js +74 -0
  152. package/src/operations/extrusions/earcut/eliminateHoles.js +131 -0
  153. package/src/operations/extrusions/earcut/index.js +252 -0
  154. package/src/operations/extrusions/earcut/linkedList.js +58 -0
  155. package/src/operations/extrusions/earcut/linkedListSort.js +54 -0
  156. package/src/operations/extrusions/earcut/linkedPolygon.js +197 -0
  157. package/src/operations/extrusions/earcut/polygonHierarchy.js +64 -0
  158. package/src/operations/extrusions/earcut/triangle.js +16 -0
  159. package/src/operations/extrusions/extrudeFromSlices.js +10 -3
  160. package/src/operations/extrusions/extrudeFromSlices.test.js +47 -31
  161. package/src/operations/extrusions/extrudeLinear.js +10 -5
  162. package/src/operations/extrusions/extrudeLinear.test.js +91 -35
  163. package/src/operations/extrusions/extrudeLinearGeom2.js +5 -2
  164. package/src/operations/extrusions/extrudeLinearPath2.js +24 -0
  165. package/src/operations/extrusions/extrudeRectangular.js +1 -1
  166. package/src/operations/extrusions/extrudeRectangular.test.js +22 -15
  167. package/src/operations/extrusions/extrudeRotate.test.js +31 -27
  168. package/src/operations/extrusions/project.js +1 -1
  169. package/src/operations/extrusions/project.test.js +5 -5
  170. package/src/operations/extrusions/slice/calculatePlane.js +7 -4
  171. package/src/operations/extrusions/slice/isA.js +2 -2
  172. package/src/operations/extrusions/slice/repairSlice.js +47 -0
  173. package/src/operations/extrusions/slice/toPolygons.js +24 -60
  174. package/src/operations/hulls/hull.test.js +25 -2
  175. package/src/operations/hulls/hullChain.js +1 -1
  176. package/src/operations/hulls/hullChain.test.js +6 -4
  177. package/src/operations/hulls/hullGeom2.js +1 -1
  178. package/src/operations/hulls/hullPath2.js +6 -4
  179. package/src/operations/hulls/hullPath2.test.js +16 -0
  180. package/src/operations/hulls/hullPoints2.test.js +1 -1
  181. package/src/operations/modifiers/edges.js +1 -1
  182. package/src/operations/modifiers/generalize.js +1 -1
  183. package/src/operations/modifiers/generalize.test.js +6 -0
  184. package/src/operations/modifiers/snap.test.js +3 -3
  185. package/src/operations/transforms/align.d.ts +1 -1
  186. package/src/operations/transforms/align.test.js +12 -0
  187. package/src/operations/transforms/center.js +17 -17
  188. package/src/operations/transforms/center.test.js +12 -0
  189. package/src/operations/transforms/mirror.js +12 -12
  190. package/src/operations/transforms/mirror.test.js +16 -0
  191. package/src/operations/transforms/rotate.js +12 -12
  192. package/src/operations/transforms/rotate.test.js +10 -0
  193. package/src/operations/transforms/scale.js +19 -19
  194. package/src/operations/transforms/scale.test.js +15 -0
  195. package/src/operations/transforms/transform.js +3 -3
  196. package/src/operations/transforms/transform.test.js +5 -0
  197. package/src/operations/transforms/translate.js +14 -14
  198. package/src/operations/transforms/translate.test.js +16 -0
  199. package/src/primitives/arc.js +1 -1
  200. package/src/primitives/arc.test.js +11 -0
  201. package/src/primitives/circle.test.js +15 -9
  202. package/src/primitives/cube.test.js +3 -0
  203. package/src/primitives/cuboid.test.js +9 -24
  204. package/src/primitives/cylinder.test.js +7 -4
  205. package/src/primitives/cylinderElliptic.js +13 -6
  206. package/src/primitives/cylinderElliptic.test.js +72 -52
  207. package/src/primitives/ellipse.js +3 -1
  208. package/src/primitives/ellipse.test.js +14 -8
  209. package/src/primitives/ellipsoid.js +7 -5
  210. package/src/primitives/ellipsoid.test.js +84 -82
  211. package/src/primitives/geodesicSphere.d.ts +0 -1
  212. package/src/primitives/geodesicSphere.test.js +3 -0
  213. package/src/primitives/line.test.js +1 -0
  214. package/src/primitives/polygon.test.js +15 -10
  215. package/src/primitives/polyhedron.js +1 -1
  216. package/src/primitives/polyhedron.test.js +14 -42
  217. package/src/primitives/rectangle.test.js +3 -0
  218. package/src/primitives/roundedCuboid.test.js +5 -0
  219. package/src/primitives/roundedCylinder.js +6 -4
  220. package/src/primitives/roundedCylinder.test.js +40 -36
  221. package/src/primitives/roundedRectangle.test.js +5 -0
  222. package/src/primitives/sphere.test.js +52 -73
  223. package/src/primitives/square.test.js +3 -0
  224. package/src/primitives/star.test.js +6 -0
  225. package/src/primitives/torus.d.ts +0 -1
  226. package/src/primitives/torus.test.js +8 -1
  227. package/src/primitives/triangle.js +1 -1
  228. package/src/primitives/triangle.test.js +7 -0
  229. package/src/text/vectorText.js +2 -2
  230. package/src/utils/areAllShapesTheSameType.js +2 -2
  231. package/src/utils/areAllShapesTheSameType.test.js +17 -0
  232. package/src/utils/index.d.ts +1 -0
  233. package/src/utils/index.js +3 -1
  234. package/src/utils/padArrayToLength.js +1 -1
  235. package/src/utils/trigonometry.d.ts +2 -0
  236. package/src/utils/trigonometry.js +35 -0
  237. package/src/utils/trigonometry.test.js +25 -0
  238. package/test/helpers/nearlyEqual.js +4 -1
@@ -7,10 +7,10 @@ const geom3 = require('../../geometries/geom3')
7
7
  const path2 = require('../../geometries/path2')
8
8
 
9
9
  /**
10
- * Translate the given geometries using the given options.
11
- * @param {Array} offset - offset (vector) of which to translate the geometries
12
- * @param {...Object} geometries - the geometries to translate
13
- * @return {Object|Array} the translated geometry, or a list of translated geometries
10
+ * Translate the given objects using the given options.
11
+ * @param {Array} offset - offset (vector) of which to translate the objects
12
+ * @param {...Object} objects - the objects to translate
13
+ * @return {Object|Array} the translated object, or a list of translated objects
14
14
  * @alias module:modeling/transforms.translate
15
15
  *
16
16
  * @example
@@ -38,28 +38,28 @@ const translate = (offset, ...objects) => {
38
38
  }
39
39
 
40
40
  /**
41
- * Translate the given geometries along the X axis using the given options.
42
- * @param {Number} offset - X offset of which to translate the geometries
43
- * @param {...Object} geometries - the geometries to translate
44
- * @return {Object|Array} the translated geometry, or a list of translated geometries
41
+ * Translate the given objects along the X axis using the given options.
42
+ * @param {Number} offset - X offset of which to translate the objects
43
+ * @param {...Object} objects - the objects to translate
44
+ * @return {Object|Array} the translated object, or a list of translated objects
45
45
  * @alias module:modeling/transforms.translateX
46
46
  */
47
47
  const translateX = (offset, ...objects) => translate([offset, 0, 0], objects)
48
48
 
49
49
  /**
50
- * Translate the given geometries along the Y axis using the given options.
50
+ * Translate the given objects along the Y axis using the given options.
51
51
  * @param {Number} offset - Y offset of which to translate the geometries
52
- * @param {...Object} geometries - the geometries to translate
53
- * @return {Object|Array} the translated geometry, or a list of translated geometries
52
+ * @param {...Object} objects - the objects to translate
53
+ * @return {Object|Array} the translated object, or a list of translated objects
54
54
  * @alias module:modeling/transforms.translateY
55
55
  */
56
56
  const translateY = (offset, ...objects) => translate([0, offset, 0], objects)
57
57
 
58
58
  /**
59
- * Translate the given geometries along the Z axis using the given options.
59
+ * Translate the given objects along the Z axis using the given options.
60
60
  * @param {Number} offset - Z offset of which to translate the geometries
61
- * @param {...Object} geometries - the geometries to translate
62
- * @return {Object|Array} the translated geometry, or a list of translated geometries
61
+ * @param {...Object} objects - the objects to translate
62
+ * @return {Object|Array} the translated object, or a list of translated objects
63
63
  * @alias module:modeling/transforms.translateZ
64
64
  */
65
65
  const translateZ = (offset, ...objects) => translate([0, 0, offset], objects)
@@ -13,20 +13,24 @@ test('translate: translating of a path2 produces expected changes to points', (t
13
13
  let translated = translate([1], line)
14
14
  let obs = path2.toPoints(translated)
15
15
  let exp = [[1, 0], [2, 0]]
16
+ t.notThrows(() => path2.validate(translated))
16
17
  t.true(comparePoints(obs, exp))
17
18
 
18
19
  translated = translateX(1, line)
19
20
  obs = path2.toPoints(translated)
21
+ t.notThrows(() => path2.validate(translated))
20
22
  t.true(comparePoints(obs, exp))
21
23
 
22
24
  // translate Y
23
25
  translated = translate([0, 1], line)
24
26
  obs = path2.toPoints(translated)
25
27
  exp = [[0, 1], [1, 1]]
28
+ t.notThrows(() => path2.validate(translated))
26
29
  t.true(comparePoints(obs, exp))
27
30
 
28
31
  translated = translateY(1, line)
29
32
  obs = path2.toPoints(translated)
33
+ t.notThrows(() => path2.validate(translated))
30
34
  t.true(comparePoints(obs, exp))
31
35
  })
32
36
 
@@ -37,20 +41,24 @@ test('translate: translating of a geom2 produces expected changes to points', (t
37
41
  let translated = translate([1], geometry)
38
42
  let obs = geom2.toPoints(translated)
39
43
  let exp = [[1, 0], [2, 0], [1, 1]]
44
+ t.notThrows(() => geom2.validate(translated))
40
45
  t.true(comparePoints(obs, exp))
41
46
 
42
47
  translated = translateX(1, geometry)
43
48
  obs = geom2.toPoints(translated)
49
+ t.notThrows(() => geom2.validate(translated))
44
50
  t.true(comparePoints(obs, exp))
45
51
 
46
52
  // translate Y
47
53
  translated = translate([0, 1], geometry)
48
54
  obs = geom2.toPoints(translated)
49
55
  exp = [[0, 1], [1, 1], [0, 2]]
56
+ t.notThrows(() => geom2.validate(translated))
50
57
  t.true(comparePoints(obs, exp))
51
58
 
52
59
  translated = translateY(1, geometry)
53
60
  obs = geom2.toPoints(translated)
61
+ t.notThrows(() => geom2.validate(translated))
54
62
  t.true(comparePoints(obs, exp))
55
63
  })
56
64
 
@@ -76,10 +84,12 @@ test('translate: translating of a geom3 produces expected changes to polygons',
76
84
  [[1, -7, -12], [1, 13, -12], [11, 13, -12], [11, -7, -12]],
77
85
  [[1, -7, 18], [11, -7, 18], [11, 13, 18], [1, 13, 18]]
78
86
  ]
87
+ t.notThrows(() => geom3.validate(translated))
79
88
  t.true(comparePolygonsAsPoints(obs, exp))
80
89
 
81
90
  translated = translateX(3, geometry)
82
91
  obs = geom3.toPoints(translated)
92
+ t.notThrows(() => geom3.validate(translated))
83
93
  t.true(comparePolygonsAsPoints(obs, exp))
84
94
 
85
95
  // translated Y
@@ -93,10 +103,12 @@ test('translate: translating of a geom3 produces expected changes to polygons',
93
103
  [[-2, -4, -12], [-2, 16, -12], [8, 16, -12], [8, -4, -12]],
94
104
  [[-2, -4, 18], [8, -4, 18], [8, 16, 18], [-2, 16, 18]]
95
105
  ]
106
+ t.notThrows(() => geom3.validate(translated))
96
107
  t.true(comparePolygonsAsPoints(obs, exp))
97
108
 
98
109
  translated = translateY(3, geometry)
99
110
  obs = geom3.toPoints(translated)
111
+ t.notThrows(() => geom3.validate(translated))
100
112
  t.true(comparePolygonsAsPoints(obs, exp))
101
113
 
102
114
  // translate Z
@@ -110,10 +122,12 @@ test('translate: translating of a geom3 produces expected changes to polygons',
110
122
  [[-2, -7, -9], [-2, 13, -9], [8, 13, -9], [8, -7, -9]],
111
123
  [[-2, -7, 21], [8, -7, 21], [8, 13, 21], [-2, 13, 21]]
112
124
  ]
125
+ t.notThrows(() => geom3.validate(translated))
113
126
  t.true(comparePolygonsAsPoints(obs, exp))
114
127
 
115
128
  translated = translateZ(3, geometry)
116
129
  obs = geom3.toPoints(translated)
130
+ t.notThrows(() => geom3.validate(translated))
117
131
  t.true(comparePolygonsAsPoints(obs, exp))
118
132
  })
119
133
 
@@ -127,9 +141,11 @@ test('translate: translating of multiple objects produces expected changes', (t)
127
141
 
128
142
  let obs = path2.toPoints(translated[1])
129
143
  let exp = [[-2, 8], [8, 8], [-2, -2], [13, -2]]
144
+ t.notThrows(() => path2.validate(translated[1]))
130
145
  t.true(comparePoints(obs, exp))
131
146
 
132
147
  obs = geom2.toPoints(translated[2])
133
148
  exp = [[-2, -2], [3, 8], [13, -2]]
149
+ t.notThrows(() => geom2.validate(translated[2]))
134
150
  t.true(comparePoints(obs, exp))
135
151
  })
@@ -78,7 +78,7 @@ const arc = (options) => {
78
78
  pointArray.push(point)
79
79
  }
80
80
  }
81
- return path2.fromPoints({ close: false }, pointArray)
81
+ return path2.fromPoints({ closed: false }, pointArray)
82
82
  }
83
83
 
84
84
  module.exports = arc
@@ -10,6 +10,7 @@ test('arc (defaults)', (t) => {
10
10
  const geometry = arc()
11
11
  const obs = path2.toPoints(geometry)
12
12
 
13
+ t.notThrows(() => path2.validate(geometry))
13
14
  t.deepEqual(obs.length, 33)
14
15
  })
15
16
 
@@ -37,6 +38,7 @@ test('arc (options)', (t) => {
37
38
  let geometry = arc({ center: [2, 2], segments: 16 })
38
39
  let obs = path2.toPoints(geometry)
39
40
 
41
+ t.notThrows(() => path2.validate(geometry))
40
42
  t.deepEqual(obs.length, 17)
41
43
  t.true(comparePoints(obs, exp))
42
44
 
@@ -63,6 +65,7 @@ test('arc (options)', (t) => {
63
65
  geometry = arc({ radius: 2, segments: 16 })
64
66
  obs = path2.toPoints(geometry)
65
67
 
68
+ t.notThrows(() => path2.validate(geometry))
66
69
  t.deepEqual(obs.length, 17)
67
70
  t.true(comparePoints(obs, exp))
68
71
 
@@ -86,6 +89,7 @@ test('arc (options)', (t) => {
86
89
  geometry = arc({ startAngle: Math.PI / 2, segments: 16 })
87
90
  obs = path2.toPoints(geometry)
88
91
 
92
+ t.notThrows(() => path2.validate(geometry))
89
93
  t.deepEqual(obs.length, 14)
90
94
  t.true(comparePoints(obs, exp))
91
95
 
@@ -101,6 +105,7 @@ test('arc (options)', (t) => {
101
105
  geometry = arc({ endAngle: Math.PI / 2, segments: 16 })
102
106
  obs = path2.toPoints(geometry)
103
107
 
108
+ t.notThrows(() => path2.validate(geometry))
104
109
  t.deepEqual(obs.length, 6)
105
110
  t.true(comparePoints(obs, exp))
106
111
 
@@ -129,6 +134,7 @@ test('arc (options)', (t) => {
129
134
  geometry = arc({ makeTangent: true, segments: 16 })
130
135
  obs = path2.toPoints(geometry)
131
136
 
137
+ t.notThrows(() => path2.validate(geometry))
132
138
  t.deepEqual(obs.length, 19)
133
139
  t.true(comparePoints(obs, exp))
134
140
 
@@ -147,6 +153,7 @@ test('arc (options)', (t) => {
147
153
  geometry = arc({ segments: 8 })
148
154
  obs = path2.toPoints(geometry)
149
155
 
156
+ t.notThrows(() => path2.validate(geometry))
150
157
  t.deepEqual(obs.length, 9)
151
158
  t.true(comparePoints(obs, exp))
152
159
  })
@@ -163,6 +170,7 @@ test('arc (rotations)', (t) => {
163
170
  let geometry = arc({ startAngle: Math.PI / 2, endAngle: Math.PI, segments: 16 })
164
171
  let obs = path2.toPoints(geometry)
165
172
 
173
+ t.notThrows(() => path2.validate(geometry))
166
174
  t.deepEqual(obs.length, 6)
167
175
  t.true(comparePoints(obs, exp))
168
176
 
@@ -181,6 +189,7 @@ test('arc (rotations)', (t) => {
181
189
  geometry = arc({ startAngle: Math.PI, endAngle: Math.PI * 2, segments: 16 })
182
190
  obs = path2.toPoints(geometry)
183
191
 
192
+ t.notThrows(() => path2.validate(geometry))
184
193
  t.deepEqual(obs.length, 10)
185
194
  t.true(comparePoints(obs, exp))
186
195
 
@@ -199,6 +208,7 @@ test('arc (rotations)', (t) => {
199
208
  geometry = arc({ startAngle: Math.PI * 2 * 0.75, endAngle: Math.PI / 2, segments: 16 })
200
209
  obs = path2.toPoints(geometry)
201
210
 
211
+ t.notThrows(() => path2.validate(geometry))
202
212
  t.deepEqual(obs.length, 10)
203
213
  t.true(comparePoints(obs, exp))
204
214
 
@@ -206,6 +216,7 @@ test('arc (rotations)', (t) => {
206
216
  geometry = arc({ startAngle: Math.PI * 2 * 0.75, endAngle: 270.000000005 * 0.017453292519943295, segments: 16 })
207
217
  obs = path2.toPoints(geometry)
208
218
 
219
+ t.notThrows(() => path2.validate(geometry))
209
220
  t.deepEqual(obs.length, 1)
210
221
  t.true(comparePoints(obs, exp))
211
222
  })
@@ -10,6 +10,7 @@ test('circle (defaults)', (t) => {
10
10
  const geometry = circle()
11
11
  const pts = geom2.toPoints(geometry)
12
12
 
13
+ t.notThrows(() => geom2.validate(geometry))
13
14
  t.deepEqual(pts.length, 32)
14
15
  })
15
16
 
@@ -42,7 +43,7 @@ test('circle (options)', (t) => {
42
43
  [4.555504184431392, 3.5898563569410915],
43
44
  [5.160607986722184, 3.266421636210497],
44
45
  [5.817183872943549, 3.067251518588694],
45
- [6.499999999999999, 3],
46
+ [6.5, 3],
46
47
  [7.182816127056449, 3.0672515185886935],
47
48
  [7.8393920132778145, 3.266421636210497],
48
49
  [8.444495815568606, 3.589856356941091],
@@ -52,6 +53,7 @@ test('circle (options)', (t) => {
52
53
  [9.932748481411306, 5.817183872943549]
53
54
  ]
54
55
 
56
+ t.notThrows(() => geom2.validate(geometry))
55
57
  t.deepEqual(pts.length, 32)
56
58
  t.true(comparePoints(pts, exp))
57
59
 
@@ -63,20 +65,21 @@ test('circle (options)', (t) => {
63
65
  [3.2335783637895035, 1.3393920132778143],
64
66
  [2.4748737341529163, 2.474873734152916],
65
67
  [1.3393920132778145, 3.2335783637895035],
66
- [2.143131898507868e-16, 3.5],
68
+ [0, 3.5],
67
69
  [-1.339392013277814, 3.2335783637895035],
68
70
  [-2.474873734152916, 2.4748737341529163],
69
71
  [-3.2335783637895035, 1.3393920132778145],
70
- [-3.5, 4.286263797015736e-16],
72
+ [-3.5, 0],
71
73
  [-3.233578363789504, -1.3393920132778139],
72
74
  [-2.474873734152917, -2.474873734152916],
73
75
  [-1.339392013277816, -3.233578363789503],
74
- [-6.429395695523604e-16, -3.5],
76
+ [0, -3.5],
75
77
  [1.339392013277815, -3.233578363789503],
76
78
  [2.474873734152916, -2.474873734152917],
77
79
  [3.233578363789503, -1.3393920132778163]
78
80
  ]
79
81
 
82
+ t.notThrows(() => geom2.validate(geometry))
80
83
  t.deepEqual(pts.length, 16)
81
84
  t.true(comparePoints(pts, exp))
82
85
 
@@ -84,22 +87,23 @@ test('circle (options)', (t) => {
84
87
  geometry = circle({ radius: 3.5, startAngle: Math.PI / 2, segments: 16 })
85
88
  pts = geom2.toPoints(geometry)
86
89
  exp = [
87
- [2.143131898507868e-16, 3.5],
90
+ [0, 3.5],
88
91
  [-1.339392013277814, 3.2335783637895035],
89
92
  [-2.474873734152916, 2.4748737341529163],
90
93
  [-3.2335783637895035, 1.3393920132778145],
91
- [-3.5, 4.286263797015736e-16],
94
+ [-3.5, 0],
92
95
  [-3.233578363789504, -1.3393920132778139],
93
96
  [-2.474873734152917, -2.474873734152916],
94
97
  [-1.339392013277816, -3.233578363789503],
95
- [-6.429395695523604e-16, -3.5],
98
+ [0, -3.5],
96
99
  [1.339392013277815, -3.233578363789503],
97
100
  [2.474873734152916, -2.474873734152917],
98
101
  [3.233578363789503, -1.3393920132778163],
99
- [3.5, -8.572527594031472e-16],
102
+ [3.5, 0],
100
103
  [0, 0]
101
104
  ]
102
105
 
106
+ t.notThrows(() => geom2.validate(geometry))
103
107
  t.deepEqual(pts.length, 14)
104
108
  t.true(comparePoints(pts, exp))
105
109
 
@@ -111,10 +115,11 @@ test('circle (options)', (t) => {
111
115
  [3.2335783637895035, 1.3393920132778143],
112
116
  [2.4748737341529163, 2.474873734152916],
113
117
  [1.3393920132778145, 3.2335783637895035],
114
- [2.143131898507868e-16, 3.5],
118
+ [0, 3.5],
115
119
  [0, 0]
116
120
  ]
117
121
 
122
+ t.notThrows(() => geom2.validate(geometry))
118
123
  t.deepEqual(pts.length, 6)
119
124
  t.true(comparePoints(pts, exp))
120
125
 
@@ -129,6 +134,7 @@ test('circle (options)', (t) => {
129
134
  [1.0815594803123152, -3.3286978070330377]
130
135
  ]
131
136
 
137
+ t.notThrows(() => geom2.validate(geometry))
132
138
  t.deepEqual(pts.length, 5)
133
139
  t.true(comparePoints(pts, exp))
134
140
  })
@@ -9,6 +9,7 @@ const comparePolygonsAsPoints = require('../../test/helpers/comparePolygonsAsPoi
9
9
  test('cube (defaults)', (t) => {
10
10
  const obs = cube()
11
11
  const pts = geom3.toPoints(obs)
12
+ t.notThrows(() => geom3.validate(obs))
12
13
  t.is(pts.length, 6)
13
14
  })
14
15
 
@@ -25,6 +26,7 @@ test('cube (options)', (t) => {
25
26
  [[3, 3, 10], [10, 3, 10], [10, 10, 10], [3, 10, 10]]
26
27
  ]
27
28
 
29
+ t.notThrows(() => geom3.validate(obs))
28
30
  t.is(pts.length, 6)
29
31
  t.true(comparePolygonsAsPoints(pts, exp))
30
32
 
@@ -40,6 +42,7 @@ test('cube (options)', (t) => {
40
42
  [[-3.5, -3.5, 3.5], [3.5, -3.5, 3.5], [3.5, 3.5, 3.5], [-3.5, 3.5, 3.5]]
41
43
  ]
42
44
 
45
+ t.notThrows(() => geom3.validate(obs))
43
46
  t.is(pts.length, 6)
44
47
  t.true(comparePolygonsAsPoints(pts, exp))
45
48
  })
@@ -10,31 +10,14 @@ test('cuboid (defaults)', (t) => {
10
10
  const obs = cuboid()
11
11
  const pts = geom3.toPoints(obs)
12
12
  const exp = [
13
- [[-1.0000000, -1.0000000, -1.0000000],
14
- [-1.0000000, -1.0000000, 1.0000000],
15
- [-1.0000000, 1.0000000, 1.0000000],
16
- [-1.0000000, 1.0000000, -1.0000000]],
17
- [[1.0000000, -1.0000000, -1.0000000],
18
- [1.0000000, 1.0000000, -1.0000000],
19
- [1.0000000, 1.0000000, 1.0000000],
20
- [1.0000000, -1.0000000, 1.0000000]],
21
- [[-1.0000000, -1.0000000, -1.0000000],
22
- [1.0000000, -1.0000000, -1.0000000],
23
- [1.0000000, -1.0000000, 1.0000000],
24
- [-1.0000000, -1.0000000, 1.0000000]],
25
- [[-1.0000000, 1.0000000, -1.0000000],
26
- [-1.0000000, 1.0000000, 1.0000000],
27
- [1.0000000, 1.0000000, 1.0000000],
28
- [1.0000000, 1.0000000, -1.0000000]],
29
- [[-1.0000000, -1.0000000, -1.0000000],
30
- [-1.0000000, 1.0000000, -1.0000000],
31
- [1.0000000, 1.0000000, -1.0000000],
32
- [1.0000000, -1.0000000, -1.0000000]],
33
- [[-1.0000000, -1.0000000, 1.0000000],
34
- [1.0000000, -1.0000000, 1.0000000],
35
- [1.0000000, 1.0000000, 1.0000000],
36
- [-1.0000000, 1.0000000, 1.0000000]]
13
+ [[-1, -1, -1], [-1, -1, 1], [-1, 1, 1], [-1, 1, -1]],
14
+ [[1, -1, -1], [1, 1, -1], [1, 1, 1], [1, -1, 1]],
15
+ [[-1, -1, -1], [1, -1, -1], [1, -1, 1], [-1, -1, 1]],
16
+ [[-1, 1, -1], [-1, 1, 1], [1, 1, 1], [1, 1, -1]],
17
+ [[-1, -1, -1], [-1, 1, -1], [1, 1, -1], [1, -1, -1]],
18
+ [[-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]]
37
19
  ]
20
+ t.notThrows(() => geom3.validate(obs))
38
21
  t.is(pts.length, 6)
39
22
  t.true(comparePolygonsAsPoints(pts, exp))
40
23
  })
@@ -52,6 +35,7 @@ test('cuboid (options)', (t) => {
52
35
  [[0, 2, 10], [6, 2, 10], [6, 8, 10], [0, 8, 10]]
53
36
  ]
54
37
 
38
+ t.notThrows(() => geom3.validate(obs))
55
39
  t.is(pts.length, 6)
56
40
  t.true(comparePolygonsAsPoints(pts, exp))
57
41
 
@@ -67,6 +51,7 @@ test('cuboid (options)', (t) => {
67
51
  [[-2.25, -0.75, 3.5], [2.25, -0.75, 3.5], [2.25, 0.75, 3.5], [-2.25, 0.75, 3.5]]
68
52
  ]
69
53
 
54
+ t.notThrows(() => geom3.validate(obs))
70
55
  t.is(pts.length, 6)
71
56
  t.true(comparePolygonsAsPoints(pts, exp))
72
57
  })
@@ -10,6 +10,7 @@ test('cylinder (defaults)', (t) => {
10
10
  const obs = cylinder()
11
11
  const pts = geom3.toPoints(obs)
12
12
 
13
+ t.notThrows(() => geom3.validate(obs))
13
14
  t.is(pts.length, 96)
14
15
  })
15
16
 
@@ -33,12 +34,13 @@ test('cylinder (options)', (t) => {
33
34
  [[1.236067977499789, -3.8042260651806146, -5], [1.236067977499789, -3.8042260651806146, 5],
34
35
  [-3.23606797749979, -2.351141009169892, 5], [-3.23606797749979, -2.351141009169892, -5]],
35
36
  [[0, 0, 5], [-3.23606797749979, -2.351141009169892, 5], [1.236067977499789, -3.8042260651806146, 5]],
36
- [[0, 0, -5], [4, -9.797174393178826e-16, -5], [1.236067977499789, -3.8042260651806146, -5]],
37
- [[4, -9.797174393178826e-16, -5], [4, -9.797174393178826e-16, 5],
38
- [1.236067977499789, -3.8042260651806146, 5], [1.236067977499789, -3.8042260651806146, -5]],
39
- [[0, 0, 5], [1.236067977499789, -3.8042260651806146, 5], [4, -9.797174393178826e-16, 5]]
37
+ [[0, 0, -5], [4, 0, -5], [1.236067977499789, -3.8042260651806146, -5]],
38
+ [[4, 0, -5], [4, 0, 5], [1.236067977499789, -3.8042260651806146, 5],
39
+ [1.236067977499789, -3.8042260651806146, -5]],
40
+ [[0, 0, 5], [1.236067977499789, -3.8042260651806146, 5], [4, 0, 5]]
40
41
  ]
41
42
 
43
+ t.notThrows(() => geom3.validate(obs))
42
44
  t.is(pts.length, 15)
43
45
  t.true(comparePolygonsAsPoints(pts, exp))
44
46
 
@@ -68,6 +70,7 @@ test('cylinder (options)', (t) => {
68
70
  [[-5, -5, -4], [-4.6909830056250525, -5.951056516295154, -4], [-4, -5, -4]]
69
71
  ]
70
72
 
73
+ t.notThrows(() => geom3.validate(obs))
71
74
  t.is(pts.length, 15)
72
75
  t.true(comparePolygonsAsPoints(pts, exp))
73
76
  })
@@ -5,6 +5,8 @@ const vec3 = require('../maths/vec3')
5
5
  const geom3 = require('../geometries/geom3')
6
6
  const poly3 = require('../geometries/poly3')
7
7
 
8
+ const { sin, cos } = require('../utils/trigonometry')
9
+
8
10
  const { isGT, isGTE, isNumberArray } = require('./commonChecks')
9
11
 
10
12
  /**
@@ -38,9 +40,10 @@ const cylinderElliptic = (options) => {
38
40
  if (!isNumberArray(center, 3)) throw new Error('center must be an array of X, Y and Z values')
39
41
  if (!isGT(height, 0)) throw new Error('height must be greater then zero')
40
42
  if (!isNumberArray(startRadius, 2)) throw new Error('startRadius must be an array of X and Y values')
41
- if (!startRadius.every((n) => n > 0)) throw new Error('startRadius values must be greater than zero')
43
+ if (!startRadius.every((n) => n >= 0)) throw new Error('startRadius values must be positive')
42
44
  if (!isNumberArray(endRadius, 2)) throw new Error('endRadius must be an array of X and Y values')
43
- if (!endRadius.every((n) => n > 0)) throw new Error('endRadius values must be greater than zero')
45
+ if (!endRadius.every((n) => n >= 0)) throw new Error('endRadius values must be positive')
46
+ if (endRadius.every((n) => n === 0) && startRadius.every((n) => n === 0)) throw new Error('at least one radius must be positive')
44
47
  if (!isGTE(startAngle, 0)) throw new Error('startAngle must be positive')
45
48
  if (!isGTE(endAngle, 0)) throw new Error('endAngle must be positive')
46
49
  if (!isGTE(segments, 4)) throw new Error('segments must be four or more')
@@ -75,8 +78,8 @@ const cylinderElliptic = (options) => {
75
78
  const v3 = vec3.create()
76
79
  const point = (stack, slice, radius) => {
77
80
  const angle = slice * rotation + startAngle
78
- vec3.scale(v1, axisX, radius[0] * Math.cos(angle))
79
- vec3.scale(v2, axisY, radius[1] * Math.sin(angle))
81
+ vec3.scale(v1, axisX, radius[0] * cos(angle))
82
+ vec3.scale(v2, axisY, radius[1] * sin(angle))
80
83
  vec3.add(v1, v1, v2)
81
84
 
82
85
  vec3.scale(v3, ray, stack)
@@ -100,12 +103,16 @@ const cylinderElliptic = (options) => {
100
103
  polygons.push(fromPoints(point(0, t1, endRadius), point(1, t1, endRadius), point(1, t0, endRadius), point(0, t0, endRadius)))
101
104
  polygons.push(fromPoints(end, point(1, t0, endRadius), point(1, t1, endRadius)))
102
105
  } else {
103
- if (startRadius[0] > 0) {
106
+ if (startRadius[0] > 0 && startRadius[1] > 0) {
104
107
  polygons.push(fromPoints(start, point(0, t1, startRadius), point(0, t0, startRadius)))
108
+ }
109
+ if (startRadius[0] > 0 || startRadius[1] > 0) {
105
110
  polygons.push(fromPoints(point(0, t0, startRadius), point(0, t1, startRadius), point(1, t0, endRadius)))
106
111
  }
107
- if (endRadius[0] > 0) {
112
+ if (endRadius[0] > 0 && endRadius[1] > 0) {
108
113
  polygons.push(fromPoints(end, point(1, t0, endRadius), point(1, t1, endRadius)))
114
+ }
115
+ if (endRadius[0] > 0 || endRadius[1] > 0) {
109
116
  polygons.push(fromPoints(point(1, t0, endRadius), point(0, t1, startRadius), point(1, t1, endRadius)))
110
117
  }
111
118
  }