@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
@@ -22,6 +22,7 @@ test('star (defaults)', (t) => {
22
22
  [0.3090169943749474, -0.22451398828979277]
23
23
  ]
24
24
 
25
+ t.notThrows(() => geom2.validate(geometry))
25
26
  t.deepEqual(pts.length, 10)
26
27
  t.true(comparePoints(pts, exp))
27
28
  })
@@ -43,6 +44,7 @@ test('star (options)', (t) => {
43
44
  [6.545084971874736, 3.8774300585510364]
44
45
  ]
45
46
 
47
+ t.notThrows(() => geom2.validate(geometry))
46
48
  t.deepEqual(pts.length, 10)
47
49
  t.true(comparePoints(pts, exp))
48
50
 
@@ -68,6 +70,7 @@ test('star (options)', (t) => {
68
70
  [3.535533905932737, -1.464466094067265]
69
71
  ]
70
72
 
73
+ t.notThrows(() => geom2.validate(geometry))
71
74
  t.deepEqual(pts.length, 16)
72
75
  t.true(comparePoints(pts, exp))
73
76
 
@@ -93,6 +96,7 @@ test('star (options)', (t) => {
93
96
  [2.4999999999999996, -1.0355339059327393]
94
97
  ]
95
98
 
99
+ t.notThrows(() => geom2.validate(geometry))
96
100
  t.deepEqual(pts.length, 16)
97
101
  t.true(comparePoints(pts, exp))
98
102
 
@@ -118,6 +122,7 @@ test('star (options)', (t) => {
118
122
  [0.9238795325112865, -0.3826834323650904]
119
123
  ]
120
124
 
125
+ t.notThrows(() => geom2.validate(geometry))
121
126
  t.deepEqual(pts.length, 16)
122
127
  t.true(comparePoints(pts, exp))
123
128
 
@@ -137,6 +142,7 @@ test('star (options)', (t) => {
137
142
  [0.2987632431673025, -1.8863168790768006]
138
143
  ]
139
144
 
145
+ t.notThrows(() => geom2.validate(geometry))
140
146
  t.deepEqual(pts.length, 10)
141
147
  t.true(comparePoints(pts, exp))
142
148
  })
@@ -1,4 +1,3 @@
1
- import Vec3 from '../maths/vec3/type'
2
1
  import Geom3 from '../geometries/geom3/type'
3
2
 
4
3
  export default torus
@@ -10,30 +10,36 @@ test('torus (defaults)', (t) => {
10
10
  const obs = torus()
11
11
  const pts = geom3.toPoints(obs)
12
12
 
13
+ t.notThrows.skip(() => geom3.validate(obs))
13
14
  t.is(pts.length, 2048) // 32 * 32 * 2 (polys/segment) = 2048
14
15
 
15
16
  const bounds = measureBoundingBox(obs)
16
17
  const expectedBounds = [[-5, -5, -1], [5, 5, 1]]
18
+ t.notThrows.skip(() => geom3.validate(obs))
17
19
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
18
20
  })
19
21
 
20
22
  test('torus (Simple options)', (t) => {
21
23
  const obs = torus({ innerRadius: 0.5, innerSegments: 4, outerRadius: 5, outerSegments: 8 })
22
24
  const pts = geom3.toPoints(obs)
25
+ t.notThrows.skip(() => geom3.validate(obs))
23
26
  t.is(pts.length, 64) // 4 * 8 * 2 (polys/segment) = 64
24
27
 
25
28
  const bounds = measureBoundingBox(obs)
26
29
  const expectedBounds = [[-5.5, -5.5, -0.5], [5.5, 5.5, 0.5]]
30
+ t.notThrows.skip(() => geom3.validate(obs))
27
31
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
28
32
  })
29
33
 
30
34
  test('torus (complex options)', (t) => {
31
35
  const obs = torus({ innerRadius: 1, outerRadius: 5, innerSegments: 32, outerSegments: 72, startAngle: Math.PI / 2, outerRotation: Math.PI / 2 })
32
36
  const pts = geom3.toPoints(obs)
33
- t.is(pts.length, 1154)
37
+ t.notThrows(() => geom3.validate(obs))
38
+ t.is(pts.length, 1212)
34
39
 
35
40
  const bounds = measureBoundingBox(obs)
36
41
  const expectedBounds = [[-6, 0, -1], [0, 6, 1]]
42
+ t.notThrows(() => geom3.validate(obs))
37
43
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
38
44
  })
39
45
 
@@ -42,5 +48,6 @@ test('torus (square by square)', (t) => {
42
48
 
43
49
  const bounds = measureBoundingBox(obs)
44
50
  const expectedBounds = [[-5, -5, -1], [5, 5, 1]]
51
+ t.notThrows.skip(() => geom3.validate(obs))
45
52
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
46
53
  })
@@ -119,7 +119,7 @@ const createTriangle = (A, B, C, a, b, c) => {
119
119
  * The triangle is always constructed CCW from the origin, [0, 0, 0].
120
120
  * @see https://www.mathsisfun.com/algebra/trig-solving-triangles.html
121
121
  * @param {Object} [options] - options for construction
122
- * @param {String} [options.type='SSS' - type of triangle to construct; A ~ angle, S ~ side
122
+ * @param {String} [options.type='SSS'] - type of triangle to construct; A ~ angle, S ~ side
123
123
  * @param {Array} [options.values=[1,1,1]] - angle (radians) of corners or length of sides
124
124
  * @returns {geom2} new 2D geometry
125
125
  * @alias module:modeling/primitives.triangle
@@ -16,6 +16,7 @@ test('triangle (defaults)', (t) => {
16
16
  [0.5000000000000002, 0.8660254037844387]
17
17
  ]
18
18
 
19
+ t.notThrows(() => geom2.validate(geometry))
19
20
  t.deepEqual(obs.length, 3)
20
21
  t.true(comparePoints(obs, exp))
21
22
  })
@@ -30,6 +31,7 @@ test('triangle (options)', (t) => {
30
31
  [1.5, 5.809475019311125]
31
32
  ]
32
33
 
34
+ t.notThrows(() => geom2.validate(geometry))
33
35
  t.deepEqual(obs.length, 3)
34
36
  t.true(comparePoints(obs, exp))
35
37
 
@@ -42,6 +44,7 @@ test('triangle (options)', (t) => {
42
44
  [0, 1.0000000000000002]
43
45
  ]
44
46
 
47
+ t.notThrows(() => geom2.validate(geometry))
45
48
  t.deepEqual(obs.length, 3)
46
49
  t.true(comparePoints(obs, exp))
47
50
 
@@ -54,6 +57,7 @@ test('triangle (options)', (t) => {
54
57
  [2.1348320069064197, 4.015035054457325]
55
58
  ]
56
59
 
60
+ t.notThrows(() => geom2.validate(geometry))
57
61
  t.deepEqual(obs.length, 3)
58
62
  t.true(comparePoints(obs, exp))
59
63
 
@@ -66,6 +70,7 @@ test('triangle (options)', (t) => {
66
70
  [1.295667368233083, 5.196637976713814]
67
71
  ]
68
72
 
73
+ t.notThrows(() => geom2.validate(geometry))
69
74
  t.deepEqual(obs.length, 3)
70
75
  t.true(comparePoints(obs, exp))
71
76
 
@@ -78,6 +83,7 @@ test('triangle (options)', (t) => {
78
83
  [0.4075867970664495, 5.282967061559405]
79
84
  ]
80
85
 
86
+ t.notThrows(() => geom2.validate(geometry))
81
87
  t.deepEqual(obs.length, 3)
82
88
  t.true(comparePoints(obs, exp))
83
89
 
@@ -90,6 +96,7 @@ test('triangle (options)', (t) => {
90
96
  [8.494946725906148, 12.990574573070846]
91
97
  ]
92
98
 
99
+ t.notThrows(() => geom2.validate(geometry))
93
100
  t.deepEqual(obs.length, 3)
94
101
  t.true(comparePoints(obs, exp))
95
102
  })
@@ -26,7 +26,7 @@ const translateLine = (options, line) => {
26
26
  * @param {Float} [options.height=21] - font size (uppercase height)
27
27
  * @param {Float} [options.lineSpacing=1.4] - line spacing expressed as a percentage of font size
28
28
  * @param {Float} [options.letterSpacing=1] - extra letter spacing expressed as a percentage of font size
29
- * @param {String} [options.align='left'] - multi-line text alignement: left, center or right
29
+ * @param {String} [options.align='left'] - multi-line text alignment: left, center, right
30
30
  * @param {Float} [options.extrudeOffset=0] - width of the extrusion that will be applied (manually) after the creation of the character
31
31
  * @param {String} [options.input='?'] - ascii string (ignored/overwrited if provided as seconds parameter)
32
32
  * @param {String} [text='?'] - ascii string
@@ -47,7 +47,7 @@ const vectorText = (options, text) => {
47
47
  xOffset, yOffset, input, font, height, align, extrudeOffset, lineSpacing, letterSpacing
48
48
  } = vectorParams(options, text)
49
49
  let [x, y] = [xOffset, yOffset]
50
- let [i, il, char, vect, width, diff] = []
50
+ let i, il, char, vect, width, diff
51
51
  let line = { width: 0, segments: [] }
52
52
  const lines = []
53
53
  let output = []
@@ -10,7 +10,7 @@ const path2 = require('../geometries/path2')
10
10
  */
11
11
  const areAllShapesTheSameType = (shapes) => {
12
12
  let previousType
13
- shapes.forEach((shape) => {
13
+ for (const shape of shapes) {
14
14
  let currentType = 0
15
15
  if (geom2.isA(shape)) currentType = 1
16
16
  if (geom3.isA(shape)) currentType = 2
@@ -18,7 +18,7 @@ const areAllShapesTheSameType = (shapes) => {
18
18
 
19
19
  if (previousType && currentType !== previousType) return false
20
20
  previousType = currentType
21
- })
21
+ }
22
22
  return true
23
23
  }
24
24
 
@@ -0,0 +1,17 @@
1
+ const test = require('ava')
2
+
3
+ const { cube, square } = require('../primitives')
4
+
5
+ const { areAllShapesTheSameType } = require('./index')
6
+
7
+ test('utils: areAllShapesTheSameType() should return correct values', (t) => {
8
+ const geometry2 = square()
9
+ const geometry3 = cube()
10
+
11
+ t.true(areAllShapesTheSameType([]))
12
+ t.true(areAllShapesTheSameType([geometry2]))
13
+ t.true(areAllShapesTheSameType([geometry3]))
14
+ t.true(areAllShapesTheSameType([geometry2, geometry2]))
15
+ t.true(areAllShapesTheSameType([geometry3, geometry3]))
16
+ t.false(areAllShapesTheSameType([geometry2, geometry3]))
17
+ })
@@ -5,5 +5,6 @@ export { default as fnNumberSort } from './fnNumberSort'
5
5
  export { default as insertSorted } from './insertSorted'
6
6
  export { default as radiusToSegments } from './radiusToSegments'
7
7
  export { default as radToDeg } from './radToDeg'
8
+ export * from './trigonometry'
8
9
 
9
10
  export as namespace utils
@@ -6,10 +6,12 @@
6
6
  */
7
7
  module.exports = {
8
8
  areAllShapesTheSameType: require('./areAllShapesTheSameType'),
9
+ cos: require('./trigonometry').cos,
9
10
  degToRad: require('./degToRad'),
10
11
  flatten: require('./flatten'),
11
12
  fnNumberSort: require('./fnNumberSort'),
12
13
  insertSorted: require('./insertSorted'),
13
14
  radiusToSegments: require('./radiusToSegments'),
14
- radToDeg: require('./radToDeg')
15
+ radToDeg: require('./radToDeg'),
16
+ sin: require('./trigonometry').sin
15
17
  }
@@ -3,7 +3,7 @@
3
3
  * @param {Array} anArray - the source array to copy into the result.
4
4
  * @param {*} padding - the value to add to the new array to reach the desired length.
5
5
  * @param {Number} targetLength - The desired length of the return array.
6
- * @returns {Array} an array of at least 'targetLength" length
6
+ * @returns {Array} an array of at least 'targetLength' length
7
7
  * @alias module:modeling/utils.padArrayToLength
8
8
  */
9
9
  const padArrayToLength = (anArray, padding, targetLength) => {
@@ -0,0 +1,2 @@
1
+ export function cos(radians: number): number
2
+ export function sin(radians: number): number
@@ -0,0 +1,35 @@
1
+
2
+ const NEPS = 1e-13
3
+
4
+ /*
5
+ * Returns zero if n is within epsilon of zero, otherwise return n
6
+ */
7
+ const rezero = (n) => Math.abs(n) < NEPS ? 0 : n
8
+
9
+ /**
10
+ * Return Math.sin but accurate for 90 degree rotations.
11
+ * Fixes rounding errors when sin should be 0.
12
+ *
13
+ * @param {Number} radians - angle in radians
14
+ * @returns {Number} sine of the given angle
15
+ * @alias module:modeling/utils.sin
16
+ * @example
17
+ * sin(Math.PI) == 0
18
+ * sin(2 * Math.PI) == 0
19
+ */
20
+ const sin = (radians) => rezero(Math.sin(radians))
21
+
22
+ /**
23
+ * Return Math.cos but accurate for 90 degree rotations.
24
+ * Fixes rounding errors when cos should be 0.
25
+ *
26
+ * @param {Number} radians - angle in radians
27
+ * @returns {Number} cosine of the given angle
28
+ * @alias module:modeling/utils.cos
29
+ * @example
30
+ * cos(0.5 * Math.PI) == 0
31
+ * cos(1.5 * Math.PI) == 0
32
+ */
33
+ const cos = (radians) => rezero(Math.cos(radians))
34
+
35
+ module.exports = { sin, cos }
@@ -0,0 +1,25 @@
1
+ const test = require('ava')
2
+
3
+ const { cos, sin } = require('./trigonometry')
4
+
5
+ test('utils: sin() should return rounded values', (t) => {
6
+ t.is(sin(0), 0)
7
+ t.is(sin(9), Math.sin(9))
8
+ t.is(sin(0.5 * Math.PI), 1)
9
+ t.is(sin(1.0 * Math.PI), 0)
10
+ t.is(sin(1.5 * Math.PI), -1)
11
+ t.is(sin(2.0 * Math.PI), 0)
12
+ t.is(sin(NaN), NaN)
13
+ t.is(sin(Infinity), NaN)
14
+ })
15
+
16
+ test('utils: cos() should return rounded values', (t) => {
17
+ t.is(cos(0), 1)
18
+ t.is(cos(9), Math.cos(9))
19
+ t.is(cos(0.5 * Math.PI), 0)
20
+ t.is(cos(1.0 * Math.PI), -1)
21
+ t.is(cos(1.5 * Math.PI), 0)
22
+ t.is(cos(2.0 * Math.PI), 1)
23
+ t.is(cos(NaN), NaN)
24
+ t.is(cos(Infinity), NaN)
25
+ })
@@ -1,7 +1,10 @@
1
1
  // Compare two numeric values for near equality.
2
2
  // the given test is fails if the numeric values are outside the given epsilon
3
3
  const nearlyEqual = (t, a, b, epsilon, failMessage) => {
4
- if (a === b) { // shortcut, also handles infinities and NaNs
4
+ if (typeof t !== 'object') {
5
+ throw new Error('first argument must be a test object')
6
+ }
7
+ if (a === b) { // shortcut, also handles infinities
5
8
  return true
6
9
  }
7
10