@jscad/modeling 2.9.2 → 2.9.5

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 (114) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +4 -4
  3. package/dist/jscad-modeling.min.js +435 -444
  4. package/package.json +3 -2
  5. package/src/colors/colorize.d.ts +6 -5
  6. package/src/colors/colorize.test.js +1 -1
  7. package/src/geometries/geom2/toOutlines.js +66 -52
  8. package/src/geometries/geom2/type.d.ts +3 -2
  9. package/src/geometries/geom3/applyTransforms.js +1 -2
  10. package/src/geometries/geom3/create.js +1 -1
  11. package/src/geometries/geom3/create.test.js +1 -1
  12. package/src/geometries/geom3/fromPoints.js +1 -1
  13. package/src/geometries/geom3/type.d.ts +3 -2
  14. package/src/geometries/path2/index.d.ts +0 -1
  15. package/src/geometries/path2/index.js +0 -1
  16. package/src/geometries/path2/type.d.ts +3 -2
  17. package/src/geometries/poly3/create.js +1 -1
  18. package/src/geometries/poly3/measureBoundingSphere.d.ts +2 -2
  19. package/src/geometries/poly3/measureBoundingSphere.js +46 -8
  20. package/src/geometries/poly3/measureBoundingSphere.test.js +16 -26
  21. package/src/geometries/poly3/type.d.ts +3 -2
  22. package/src/geometries/poly3/validate.js +14 -0
  23. package/src/geometries/types.d.ts +4 -2
  24. package/src/maths/constants.d.ts +1 -0
  25. package/src/maths/constants.js +11 -0
  26. package/src/maths/mat4/fromRotation.js +9 -7
  27. package/src/maths/mat4/fromTaitBryanRotation.js +8 -6
  28. package/src/maths/mat4/fromXRotation.js +4 -2
  29. package/src/maths/mat4/fromYRotation.js +4 -2
  30. package/src/maths/mat4/fromZRotation.js +4 -2
  31. package/src/maths/mat4/isMirroring.js +11 -11
  32. package/src/maths/mat4/rotate.js +9 -5
  33. package/src/maths/mat4/rotateX.js +4 -2
  34. package/src/maths/mat4/rotateY.js +4 -2
  35. package/src/maths/mat4/rotateZ.js +4 -2
  36. package/src/maths/mat4/translate.test.js +2 -3
  37. package/src/maths/utils/aboutEqualNormals.js +1 -5
  38. package/src/maths/utils/index.d.ts +1 -0
  39. package/src/maths/utils/index.js +2 -0
  40. package/src/{utils → maths/utils}/trigonometry.d.ts +0 -0
  41. package/src/{utils → maths/utils}/trigonometry.js +1 -2
  42. package/src/{utils → maths/utils}/trigonometry.test.js +0 -0
  43. package/src/maths/vec2/distance.js +1 -1
  44. package/src/maths/vec2/fromAngleRadians.js +4 -2
  45. package/src/maths/vec2/length.js +1 -1
  46. package/src/maths/vec2/length.test.js +0 -10
  47. package/src/maths/vec3/angle.js +2 -2
  48. package/src/maths/vec3/angle.test.js +0 -12
  49. package/src/maths/vec3/distance.js +1 -1
  50. package/src/maths/vec3/length.js +1 -1
  51. package/src/maths/vec3/length.test.js +0 -10
  52. package/src/operations/booleans/intersectGeom2.test.js +69 -0
  53. package/src/operations/booleans/intersectGeom3.js +2 -1
  54. package/src/operations/booleans/{intersect.test.js → intersectGeom3.test.js} +3 -71
  55. package/src/operations/booleans/subtractGeom2.test.js +72 -0
  56. package/src/operations/booleans/subtractGeom3.js +2 -1
  57. package/src/operations/booleans/{subtract.test.js → subtractGeom3.test.js} +3 -74
  58. package/src/operations/booleans/to3DWalls.js +1 -1
  59. package/src/operations/booleans/trees/PolygonTreeNode.js +2 -2
  60. package/src/operations/booleans/unionGeom2.test.js +166 -0
  61. package/src/operations/booleans/unionGeom3.js +2 -1
  62. package/src/operations/booleans/{union.test.js → unionGeom3.test.js} +3 -168
  63. package/src/operations/expansions/expandGeom3.test.js +14 -14
  64. package/src/operations/expansions/expandShell.js +5 -4
  65. package/src/operations/expansions/extrudePolygon.js +7 -7
  66. package/src/operations/extrusions/extrudeFromSlices.js +3 -2
  67. package/src/operations/extrusions/extrudeFromSlices.test.js +2 -2
  68. package/src/operations/extrusions/extrudeRotate.js +5 -1
  69. package/src/operations/extrusions/extrudeRotate.test.js +47 -47
  70. package/src/operations/extrusions/extrudeWalls.js +2 -2
  71. package/src/operations/extrusions/project.js +11 -14
  72. package/src/operations/extrusions/project.test.js +49 -49
  73. package/src/operations/extrusions/slice/repair.js +62 -0
  74. package/src/operations/hulls/hullChain.test.js +4 -4
  75. package/src/operations/hulls/hullGeom2.js +6 -18
  76. package/src/operations/hulls/hullGeom3.js +5 -18
  77. package/src/operations/hulls/hullPath2.js +4 -14
  78. package/src/operations/hulls/hullPoints2.js +43 -92
  79. package/src/operations/hulls/toUniquePoints.js +34 -0
  80. package/src/operations/modifiers/generalize.js +2 -13
  81. package/src/operations/modifiers/generalize.test.js +0 -32
  82. package/src/operations/modifiers/insertTjunctions.js +1 -1
  83. package/src/operations/modifiers/insertTjunctions.test.js +21 -21
  84. package/src/operations/modifiers/mergePolygons.js +11 -14
  85. package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.js +33 -32
  86. package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.test.js +5 -5
  87. package/src/operations/{booleans → modifiers}/retessellate.js +2 -9
  88. package/src/operations/{booleans → modifiers}/retessellate.test.js +0 -0
  89. package/src/operations/modifiers/snapPolygons.test.js +12 -12
  90. package/src/operations/modifiers/triangulatePolygons.js +3 -3
  91. package/src/operations/transforms/center.js +1 -1
  92. package/src/primitives/circle.test.js +7 -0
  93. package/src/primitives/cuboid.js +1 -1
  94. package/src/primitives/cylinderElliptic.js +5 -3
  95. package/src/primitives/cylinderElliptic.test.js +7 -1
  96. package/src/primitives/ellipse.js +1 -1
  97. package/src/primitives/ellipse.test.js +7 -0
  98. package/src/primitives/ellipsoid.js +3 -3
  99. package/src/primitives/geodesicSphere.js +3 -2
  100. package/src/primitives/polyhedron.js +1 -1
  101. package/src/primitives/roundedCuboid.js +10 -8
  102. package/src/primitives/roundedCylinder.js +2 -2
  103. package/src/primitives/torus.test.js +11 -7
  104. package/src/primitives/triangle.js +1 -2
  105. package/src/utils/index.d.ts +0 -1
  106. package/src/utils/index.js +1 -3
  107. package/src/geometries/path2/eachPoint.d.ts +0 -9
  108. package/src/geometries/path2/eachPoint.js +0 -17
  109. package/src/geometries/path2/eachPoint.test.js +0 -11
  110. package/src/maths/mat4/constants.d.ts +0 -1
  111. package/src/maths/mat4/constants.js +0 -5
  112. package/src/operations/extrusions/slice/repairSlice.js +0 -47
  113. package/src/operations/modifiers/edges.js +0 -195
  114. package/src/operations/modifiers/repairTjunctions.js +0 -44
@@ -7,49 +7,49 @@ const snapPolygons = require('./snapPolygons')
7
7
  test('snapPolygons: snap of polygons produces expected results', (t) => {
8
8
  const polygons = [
9
9
  // valid polygons
10
- poly3.fromPoints([[0, 0, 0], [0, 10, 0], [0, 10, 10]]), // OK
11
- poly3.fromPoints([[0, 0, 0], [0, 10, 0], [0, 10, 10], [0, 0, 10]]), // OK
10
+ poly3.create([[0, 0, 0], [0, 10, 0], [0, 10, 10]]), // OK
11
+ poly3.create([[0, 0, 0], [0, 10, 0], [0, 10, 10], [0, 0, 10]]), // OK
12
12
  // invalid polygons
13
13
  poly3.create(),
14
- poly3.fromPoints([[0, 0, 0]]),
15
- poly3.fromPoints([[0, 0, 0], [0, 10, 0]]),
14
+ poly3.create([[0, 0, 0]]),
15
+ poly3.create([[0, 0, 0], [0, 10, 0]]),
16
16
  // duplicated vertices
17
- poly3.fromPoints([
17
+ poly3.create([
18
18
  [-24.445112000000115, 19.346837333333426, 46.47572533333356],
19
19
  [-24.44446933333345, 19.346837333333426, 46.47508266666689],
20
20
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
21
21
  [-23.70540266666678, 18.79864266666676, 39.56448800000019]
22
22
  ]), // OK
23
- poly3.fromPoints([
23
+ poly3.create([
24
24
  [-24.445112000000115, 19.346837333333426, 46.47572533333356],
25
25
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
26
26
  [-23.70540266666678, 18.79864266666676, 39.56448800000019]
27
27
  ]),
28
- poly3.fromPoints([
28
+ poly3.create([
29
29
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
30
30
  [-23.70540266666678, 18.79864266666676, 39.56448800000019]
31
31
  ]),
32
32
  // duplicate vertices after snap
33
- poly3.fromPoints([
33
+ poly3.create([
34
34
  [-24.445112000000115, 19.346837333333426, 46.47572533333356],
35
35
  [-24.44446933333345, 19.346837333333426, 46.47508266666689],
36
36
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
37
37
  [-23.70540266666678 - 0.00001234, 18.79864266666676 + 0.000001234, 39.56448800000019 + 0.00001234]
38
38
  ]), // OK
39
- poly3.fromPoints([
39
+ poly3.create([
40
40
  [-24.445112000000115, 19.346837333333426, 46.47572533333356],
41
41
  [-23.70540266666678 - 0.00001234, 18.79864266666676 + 0.000001234, 39.56448800000019 + 0.00001234],
42
42
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
43
43
  [-23.70540266666678 - 0.00001234, 18.79864266666676 + 0.000001234, 39.56448800000019 + 0.00001234]
44
44
  ]),
45
- poly3.fromPoints([
45
+ poly3.create([
46
46
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
47
47
  [-23.70540266666678 - 0.00001234, 18.79864266666676 + 0.000001234, 39.56448800000019 + 0.00001234],
48
48
  [-23.70540266666678, 18.79864266666676, 39.56448800000019],
49
49
  [-23.70540266666678 - 0.00001234, 18.79864266666676 + 0.000001234, 39.56448800000019 + 0.00001234]
50
50
  ]),
51
51
  // inverted polygon
52
- poly3.fromPoints([
52
+ poly3.create([
53
53
  [20.109133333333336, -4.894033333333335, -1.0001266666666668],
54
54
  [20.021120000000003, -5.1802133333333344, -1.0001266666666668],
55
55
  [20.020300000000002, -5.182946666666668, -1.0001266666666668],
@@ -61,7 +61,7 @@ test('snapPolygons: snap of polygons produces expected results', (t) => {
61
61
  const results = snapPolygons(0.0001, polygons)
62
62
  t.is(results.length, 5)
63
63
 
64
- const exp3 = poly3.fromPoints([
64
+ const exp3 = poly3.create([
65
65
  [-24.4451, 19.3468, 46.4757],
66
66
  [-24.4445, 19.3468, 46.475100000000005],
67
67
  [-23.7054, 18.7986, 39.5645]
@@ -10,15 +10,15 @@ const triangulatePolygon = (epsilon, polygon, triangles) => {
10
10
  polygon.vertices.forEach((vertice) => vec3.add(midpoint, midpoint, vertice))
11
11
  vec3.snap(midpoint, vec3.divide(midpoint, midpoint, [nv, nv, nv]), epsilon)
12
12
  for (let i = 0; i < nv; i++) {
13
- const poly = poly3.fromPoints([midpoint, polygon.vertices[i], polygon.vertices[(i + 1) % nv]])
13
+ const poly = poly3.create([midpoint, polygon.vertices[i], polygon.vertices[(i + 1) % nv]])
14
14
  if (polygon.color) poly.color = polygon.color
15
15
  triangles.push(poly)
16
16
  }
17
17
  return
18
18
  }
19
19
  // exactly 4 vertices, use simple triangulation
20
- const poly0 = poly3.fromPoints([polygon.vertices[0], polygon.vertices[1], polygon.vertices[2]])
21
- const poly1 = poly3.fromPoints([polygon.vertices[0], polygon.vertices[2], polygon.vertices[3]])
20
+ const poly0 = poly3.create([polygon.vertices[0], polygon.vertices[1], polygon.vertices[2]])
21
+ const poly1 = poly3.create([polygon.vertices[0], polygon.vertices[2], polygon.vertices[3]])
22
22
  if (polygon.color) {
23
23
  poly0.color = polygon.color
24
24
  poly1.color = polygon.color
@@ -39,7 +39,7 @@ const center = (options, ...objects) => {
39
39
  const defaults = {
40
40
  axes: [true, true, true],
41
41
  relativeTo: [0, 0, 0]
42
- // TODO : Add addition 'methods' of centering; midpoint, centeriod
42
+ // TODO: Add additional 'methods' of centering: midpoint, centroid
43
43
  }
44
44
  const { axes, relativeTo } = Object.assign({}, defaults, options)
45
45
 
@@ -123,6 +123,13 @@ test('circle (options)', (t) => {
123
123
  t.deepEqual(pts.length, 6)
124
124
  t.true(comparePoints(pts, exp))
125
125
 
126
+ // test full rotation with non-zero startAngle
127
+ geometry = circle({ startAngle: 1, endAngle: 1 + 2 * Math.PI })
128
+ pts = geom2.toPoints(geometry)
129
+
130
+ t.notThrows(() => geom2.validate(geometry))
131
+ t.deepEqual(pts.length, 32)
132
+
126
133
  // test segments
127
134
  geometry = circle({ radius: 3.5, segments: 5 })
128
135
  pts = geom2.toPoints(geometry)
@@ -43,7 +43,7 @@ const cuboid = (options) => {
43
43
  ]
44
44
  return pos
45
45
  })
46
- return poly3.fromPoints(points)
46
+ return poly3.create(points)
47
47
  })
48
48
  )
49
49
  return result
@@ -5,7 +5,7 @@ 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')
8
+ const { sin, cos } = require('../maths/utils/trigonometry')
9
9
 
10
10
  const { isGT, isGTE, isNumberArray } = require('./commonChecks')
11
11
 
@@ -90,13 +90,15 @@ const cylinderElliptic = (options) => {
90
90
  // adjust the points to center
91
91
  const fromPoints = (...points) => {
92
92
  const newpoints = points.map((point) => vec3.add(vec3.create(), point, center))
93
- return poly3.fromPoints(newpoints)
93
+ return poly3.create(newpoints)
94
94
  }
95
95
 
96
96
  const polygons = []
97
97
  for (let i = 0; i < slices; i++) {
98
98
  const t0 = i / slices
99
- const t1 = (i + 1) / slices
99
+ let t1 = (i + 1) / slices
100
+ // fix rounding error when rotating 2 * PI radians
101
+ if (rotation === 2 * Math.PI && i === slices - 1) t1 = 0
100
102
 
101
103
  if (endRadius[0] === startRadius[0] && endRadius[1] === startRadius[1]) {
102
104
  polygons.push(fromPoints(start, point(0, t1, endRadius), point(0, t0, endRadius)))
@@ -137,7 +137,13 @@ test('cylinderElliptic (options)', (t) => {
137
137
 
138
138
  t.notThrows(() => geom3.validate(obs))
139
139
  t.is(pts.length, 28)
140
- // t.true(comparePolygonsAsPoints(pts, exp))
140
+
141
+ // test startAngle and endAngle
142
+ obs = cylinderElliptic({ startAngle: 1, endAngle: 1 + 2 * Math.PI })
143
+ pts = geom3.toPoints(obs)
144
+
145
+ t.notThrows(() => geom3.validate(obs))
146
+ t.is(pts.length, 96)
141
147
 
142
148
  // test segments
143
149
  obs = cylinderElliptic({ segments: 8 })
@@ -4,7 +4,7 @@ const vec2 = require('../maths/vec2')
4
4
 
5
5
  const geom2 = require('../geometries/geom2')
6
6
 
7
- const { sin, cos } = require('../utils/trigonometry')
7
+ const { sin, cos } = require('../maths/utils/trigonometry')
8
8
 
9
9
  const { isGTE, isNumberArray } = require('./commonChecks')
10
10
 
@@ -123,6 +123,13 @@ test('ellipse (options)', (t) => {
123
123
  t.deepEqual(obs.length, 6)
124
124
  t.true(comparePoints(obs, exp))
125
125
 
126
+ // test full rotation with non-zero startAngle
127
+ geometry = ellipse({ startAngle: 1, endAngle: 1 + 2 * Math.PI })
128
+ obs = geom2.toPoints(geometry)
129
+
130
+ t.notThrows(() => geom2.validate(geometry))
131
+ t.deepEqual(obs.length, 32)
132
+
126
133
  // test segments
127
134
  geometry = ellipse({ segments: 72 })
128
135
  obs = geom2.toPoints(geometry)
@@ -3,7 +3,7 @@ const vec3 = require('../maths/vec3')
3
3
  const geom3 = require('../geometries/geom3')
4
4
  const poly3 = require('../geometries/poly3')
5
5
 
6
- const { sin, cos } = require('../utils/trigonometry')
6
+ const { sin, cos } = require('../maths/utils/trigonometry')
7
7
 
8
8
  const { isGTE, isNumberArray } = require('./commonChecks')
9
9
 
@@ -66,7 +66,7 @@ const ellipsoid = (options) => {
66
66
  point = vec3.subtract(vec3.create(), vec3.scale(p1, prevcylinderpoint, cospitch), vec3.scale(p2, zvector, sinpitch))
67
67
  points.push(vec3.add(point, point, center))
68
68
 
69
- polygons.push(poly3.fromPoints(points))
69
+ polygons.push(poly3.create(points))
70
70
 
71
71
  points = []
72
72
  point = vec3.add(vec3.create(), vec3.scale(p1, prevcylinderpoint, prevcospitch), vec3.scale(p2, zvector, prevsinpitch))
@@ -81,7 +81,7 @@ const ellipsoid = (options) => {
81
81
  points.push(vec3.add(vec3.create(), center, point))
82
82
  points.reverse()
83
83
 
84
- polygons.push(poly3.fromPoints(points))
84
+ polygons.push(poly3.create(points))
85
85
  }
86
86
  prevcospitch = cospitch
87
87
  prevsinpitch = sinpitch
@@ -1,4 +1,5 @@
1
1
  const mat4 = require('../maths/mat4')
2
+ const vec3 = require('../maths/vec3')
2
3
 
3
4
  const geom3 = require('../geometries/geom3')
4
5
 
@@ -79,7 +80,7 @@ const geodesicSphere = (options) => {
79
80
 
80
81
  // -- normalize
81
82
  for (let k = 0; k < 3; k++) {
82
- const r = Math.hypot(q[k][0], q[k][1], q[k][2])
83
+ const r = vec3.length(q[k])
83
84
  for (let l = 0; l < 3; l++) {
84
85
  q[k][l] /= r
85
86
  }
@@ -95,7 +96,7 @@ const geodesicSphere = (options) => {
95
96
 
96
97
  // -- normalize
97
98
  for (let k = 0; k < 3; k++) {
98
- const r = Math.hypot(q[k][0], q[k][1], q[k][2])
99
+ const r = vec3.length(q[k])
99
100
  for (let l = 0; l < 3; l++) {
100
101
  q[k][l] /= r
101
102
  }
@@ -60,7 +60,7 @@ const polyhedron = (options) => {
60
60
  }
61
61
 
62
62
  const polygons = faces.map((face, findex) => {
63
- const polygon = poly3.fromPoints(face.map((pindex) => points[pindex]))
63
+ const polygon = poly3.create(face.map((pindex) => points[pindex]))
64
64
  if (colors && colors[findex]) polygon.color = colors[findex]
65
65
  return polygon
66
66
  })
@@ -6,12 +6,14 @@ const vec3 = require('../maths/vec3')
6
6
  const geom3 = require('../geometries/geom3')
7
7
  const poly3 = require('../geometries/poly3')
8
8
 
9
+ const { sin, cos } = require('../maths/utils/trigonometry')
10
+
9
11
  const { isGT, isGTE, isNumberArray } = require('./commonChecks')
10
12
 
11
13
  const createCorners = (center, size, radius, segments, slice, positive) => {
12
14
  const pitch = (Math.PI / 2) * slice / segments
13
- const cospitch = Math.cos(pitch)
14
- const sinpitch = Math.sin(pitch)
15
+ const cospitch = cos(pitch)
16
+ const sinpitch = sin(pitch)
15
17
 
16
18
  const layersegments = segments - slice
17
19
  let layerradius = radius * cospitch
@@ -57,10 +59,10 @@ const stitchCorners = (previousCorners, currentCorners) => {
57
59
  const previous = previousCorners[i]
58
60
  const current = currentCorners[i]
59
61
  for (let j = 0; j < (previous.length - 1); j++) {
60
- polygons.push(poly3.fromPoints([previous[j], previous[j + 1], current[j]]))
62
+ polygons.push(poly3.create([previous[j], previous[j + 1], current[j]]))
61
63
 
62
64
  if (j < (current.length - 1)) {
63
- polygons.push(poly3.fromPoints([current[j], previous[j + 1], current[j + 1]]))
65
+ polygons.push(poly3.create([current[j], previous[j + 1], current[j + 1]]))
64
66
  }
65
67
  }
66
68
  }
@@ -81,7 +83,7 @@ const stitchWalls = (previousCorners, currentCorners) => {
81
83
  const p1 = previous[0]
82
84
  const c1 = current[0]
83
85
 
84
- polygons.push(poly3.fromPoints([p0, p1, c1, c0]))
86
+ polygons.push(poly3.create([p0, p1, c1, c0]))
85
87
  }
86
88
  return polygons
87
89
  }
@@ -104,7 +106,7 @@ const stitchSides = (bottomCorners, topCorners) => {
104
106
  const polygons = []
105
107
  for (let i = 0; i < topPoints.length; i++) {
106
108
  const j = (i + 1) % topPoints.length
107
- polygons.push(poly3.fromPoints([bottomPoints[i], bottomPoints[j], topPoints[j], topPoints[i]]))
109
+ polygons.push(poly3.create([bottomPoints[i], bottomPoints[j], topPoints[j], topPoints[i]]))
108
110
  }
109
111
  return polygons
110
112
  }
@@ -168,10 +170,10 @@ const roundedCuboid = (options) => {
168
170
  if (slice === segments) {
169
171
  // add the top
170
172
  let points = cornersPos.map((corner) => corner[0])
171
- polygons.push(poly3.fromPoints(points))
173
+ polygons.push(poly3.create(points))
172
174
  // add the bottom
173
175
  points = cornersNeg.map((corner) => corner[0])
174
- polygons.push(poly3.fromPoints(points))
176
+ polygons.push(poly3.create(points))
175
177
  }
176
178
 
177
179
  prevCornersPos = cornersPos
@@ -5,7 +5,7 @@ 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')
8
+ const { sin, cos } = require('../maths/utils/trigonometry')
9
9
 
10
10
  const { isGT, isGTE, isNumberArray } = require('./commonChecks')
11
11
 
@@ -66,7 +66,7 @@ const roundedCylinder = (options) => {
66
66
  const fromPoints = (points) => {
67
67
  // adjust the points to center
68
68
  const newpoints = points.map((point) => vec3.add(point, point, center))
69
- return poly3.fromPoints(newpoints)
69
+ return poly3.create(newpoints)
70
70
  }
71
71
 
72
72
  const polygons = []
@@ -10,24 +10,22 @@ 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
+ t.notThrows(() => geom3.validate(obs))
14
14
  t.is(pts.length, 2048) // 32 * 32 * 2 (polys/segment) = 2048
15
15
 
16
16
  const bounds = measureBoundingBox(obs)
17
17
  const expectedBounds = [[-5, -5, -1], [5, 5, 1]]
18
- t.notThrows.skip(() => geom3.validate(obs))
19
18
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
20
19
  })
21
20
 
22
- test('torus (Simple options)', (t) => {
21
+ test('torus (simple options)', (t) => {
23
22
  const obs = torus({ innerRadius: 0.5, innerSegments: 4, outerRadius: 5, outerSegments: 8 })
24
23
  const pts = geom3.toPoints(obs)
25
- t.notThrows.skip(() => geom3.validate(obs))
24
+ t.notThrows(() => geom3.validate(obs))
26
25
  t.is(pts.length, 64) // 4 * 8 * 2 (polys/segment) = 64
27
26
 
28
27
  const bounds = measureBoundingBox(obs)
29
28
  const expectedBounds = [[-5.5, -5.5, -0.5], [5.5, 5.5, 0.5]]
30
- t.notThrows.skip(() => geom3.validate(obs))
31
29
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
32
30
  })
33
31
 
@@ -39,15 +37,21 @@ test('torus (complex options)', (t) => {
39
37
 
40
38
  const bounds = measureBoundingBox(obs)
41
39
  const expectedBounds = [[-6, 0, -1], [0, 6, 1]]
42
- t.notThrows(() => geom3.validate(obs))
43
40
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
44
41
  })
45
42
 
43
+ test('torus (startAngle)', (t) => {
44
+ const obs = torus({ startAngle: 1, endAngle: 1 + 2 * Math.PI })
45
+ const pts = geom3.toPoints(obs)
46
+ t.notThrows(() => geom3.validate(obs))
47
+ t.is(pts.length, 2048)
48
+ })
49
+
46
50
  test('torus (square by square)', (t) => {
47
51
  const obs = torus({ innerSegments: 4, outerSegments: 4, innerRotation: Math.PI / 2 })
48
52
 
49
53
  const bounds = measureBoundingBox(obs)
50
54
  const expectedBounds = [[-5, -5, -1], [5, 5, 1]]
51
- t.notThrows.skip(() => geom3.validate(obs))
55
+ t.notThrows(() => geom3.validate(obs))
52
56
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected: ' + JSON.stringify(bounds))
53
57
  })
@@ -1,11 +1,10 @@
1
+ const { NEPS } = require('../maths/constants')
1
2
  const vec2 = require('../maths/vec2')
2
3
 
3
4
  const geom2 = require('../geometries/geom2')
4
5
 
5
6
  const { isNumberArray } = require('./commonChecks')
6
7
 
7
- const NEPS = 1e-13
8
-
9
8
  // returns angle C
10
9
  const solveAngleFromSSS = (a, b, c) => Math.acos(((a * a) + (b * b) - (c * c)) / (2 * a * b))
11
10
 
@@ -5,6 +5,5 @@ 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'
9
8
 
10
9
  export as namespace utils
@@ -6,12 +6,10 @@
6
6
  */
7
7
  module.exports = {
8
8
  areAllShapesTheSameType: require('./areAllShapesTheSameType'),
9
- cos: require('./trigonometry').cos,
10
9
  degToRad: require('./degToRad'),
11
10
  flatten: require('./flatten'),
12
11
  fnNumberSort: require('./fnNumberSort'),
13
12
  insertSorted: require('./insertSorted'),
14
13
  radiusToSegments: require('./radiusToSegments'),
15
- radToDeg: require('./radToDeg'),
16
- sin: require('./trigonometry').sin
14
+ radToDeg: require('./radToDeg')
17
15
  }
@@ -1,9 +0,0 @@
1
- import Path2 from './type'
2
- import Vec2 from '../../maths/vec2/type'
3
-
4
- export default eachPoint
5
-
6
- export interface EachPointOptions {}
7
- export type EachPointThunk = (value: Vec2, index: number, array: Array<Vec2>) => void
8
-
9
- declare function eachPoint(options: EachPointOptions, thunk: EachPointThunk, path: Path2): void
@@ -1,17 +0,0 @@
1
- const toPoints = require('./toPoints')
2
-
3
- /**
4
- * Calls a function for each point in the path.
5
- * @param {Object} options - options
6
- * @param {Function} thunk - the function to call
7
- * @param {path2} path - the path to traverse
8
- * @alias module:modeling/geometries/path2.eachPoint
9
- *
10
- * @example
11
- * eachPoint({}, accumulate, path)
12
- */
13
- const eachPoint = (options, thunk, path) => {
14
- toPoints(path).forEach(thunk)
15
- }
16
-
17
- module.exports = eachPoint
@@ -1,11 +0,0 @@
1
- const test = require('ava')
2
-
3
- const vec2 = require('../../maths/vec2')
4
-
5
- const { eachPoint, fromPoints } = require('./index')
6
-
7
- test('eachPoint: Each point is emitted', (t) => {
8
- const collector = []
9
- eachPoint({}, (point) => collector.push(point), fromPoints({}, [[1, 1], [2, 2]]))
10
- t.deepEqual(collector, [vec2.fromValues(1, 1), vec2.fromValues(2, 2)])
11
- })
@@ -1 +0,0 @@
1
- export const EPSILON: number
@@ -1,5 +0,0 @@
1
- const EPSILON = 0.000001
2
-
3
- module.exports = {
4
- EPSILON
5
- }
@@ -1,47 +0,0 @@
1
- const vec3 = require('../../../maths/vec3')
2
-
3
- /*
4
- * Mend gaps in a 2D slice to make it a closed polygon
5
- */
6
- const repairSlice = (slice) => {
7
- if (!slice.edges) return slice
8
- const vertexMap = {} // string key to vertex map
9
- const edgeCount = {} // count of (in - out) edges
10
- slice.edges.forEach((edge) => {
11
- const inKey = edge[0].toString()
12
- const outKey = edge[1].toString()
13
- vertexMap[inKey] = edge[0]
14
- vertexMap[outKey] = edge[1]
15
- edgeCount[inKey] = (edgeCount[inKey] || 0) + 1 // in
16
- edgeCount[outKey] = (edgeCount[outKey] || 0) - 1 // out
17
- })
18
- // find vertices which are missing in or out edges
19
- const missingIn = Object.keys(edgeCount).filter((e) => edgeCount[e] < 0)
20
- const missingOut = Object.keys(edgeCount).filter((e) => edgeCount[e] > 0)
21
- // pairwise distance of bad vertices
22
- missingIn.forEach((key1) => {
23
- const v1 = vertexMap[key1]
24
- // find the closest vertex that is missing an out edge
25
- let bestDistance = Infinity
26
- let bestReplacement
27
- missingOut.forEach((key2) => {
28
- const v2 = vertexMap[key2]
29
- const distance = Math.hypot(v1[0] - v2[0], v1[1] - v2[1])
30
- if (distance < bestDistance) {
31
- bestDistance = distance
32
- bestReplacement = v2
33
- }
34
- })
35
- console.warn(`repairSlice: repairing vertex gap ${v1} to ${bestReplacement} distance ${bestDistance}`)
36
- // merge broken vertices
37
- slice.edges.forEach((edge) => {
38
- if (edge[0].toString() === key1) edge[0] = bestReplacement
39
- if (edge[1].toString() === key1) edge[1] = bestReplacement
40
- })
41
- })
42
- // Remove self-edges
43
- slice.edges = slice.edges.filter((e) => !vec3.equals(e[0], e[1]))
44
- return slice
45
- }
46
-
47
- module.exports = repairSlice