@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
@@ -1,3 +1,5 @@
1
+ const { sin, cos } = require('../utils/trigonometry')
2
+
1
3
  /**
2
4
  * Creates a matrix from the given angle around the Z axis.
3
5
  * This is equivalent to (but much faster than):
@@ -13,8 +15,8 @@
13
15
  * let matrix = fromZRotation(create(), Math.PI / 2)
14
16
  */
15
17
  const fromZRotation = (out, radians) => {
16
- const s = Math.sin(radians)
17
- const c = Math.cos(radians)
18
+ const s = sin(radians)
19
+ const c = cos(radians)
18
20
 
19
21
  // Perform axis-specific matrix multiplication
20
22
  out[0] = c
@@ -1,7 +1,3 @@
1
- const cross = require('../vec3/cross')
2
- const dot = require('../vec3/dot')
3
- const fromValues = require('../vec3/fromValues')
4
-
5
1
  /**
6
2
  * Determine whether the given matrix is a mirroring transformation.
7
3
  *
@@ -10,15 +6,19 @@ const fromValues = require('../vec3/fromValues')
10
6
  * @alias module:modeling/maths/mat4.isMirroring
11
7
  */
12
8
  const isMirroring = (matrix) => {
13
- const u = fromValues(matrix[0], matrix[4], matrix[8])
14
- const v = fromValues(matrix[1], matrix[5], matrix[9])
15
- const w = fromValues(matrix[2], matrix[6], matrix[10])
9
+ // const xVector = [matrix[0], matrix[4], matrix[8]]
10
+ // const yVector = [matrix[1], matrix[5], matrix[9]]
11
+ // const zVector = [matrix[2], matrix[6], matrix[10]]
16
12
 
17
- // for a true orthogonal, non-mirrored base, u.cross(v) == w
13
+ // for a true orthogonal, non-mirrored base, xVector.cross(yVector) == zVector
18
14
  // If they have an opposite direction then we are mirroring
19
- const mirrorvalue = dot(cross(u, u, v), w)
20
- const ismirror = (mirrorvalue < 0)
21
- return ismirror
15
+ // calcuate xVector.cross(yVector)
16
+ const x = matrix[4] * matrix[9] - matrix[8] * matrix[5]
17
+ const y = matrix[8] * matrix[1] - matrix[0] * matrix[9]
18
+ const z = matrix[0] * matrix[5] - matrix[4] * matrix[1]
19
+ // calcualte dot(cross, zVector)
20
+ const d = x * matrix[2] + y * matrix[6] + z * matrix[10]
21
+ return (d < 0)
22
22
  }
23
23
 
24
24
  module.exports = isMirroring
@@ -1,3 +1,7 @@
1
+ const { EPS } = require('../constants')
2
+
3
+ const { sin, cos } = require('../utils/trigonometry')
4
+
1
5
  const copy = require('./copy')
2
6
 
3
7
  /**
@@ -12,20 +16,20 @@ const copy = require('./copy')
12
16
  */
13
17
  const rotate = (out, matrix, radians, axis) => {
14
18
  let [x, y, z] = axis
15
- let len = Math.hypot(x, y, z)
19
+ const lengthSquared = x * x + y * y + z * z
16
20
 
17
- if (Math.abs(len) < 0.000001) {
21
+ if (Math.abs(lengthSquared) < EPS) {
18
22
  // axis is 0,0,0 or almost
19
23
  return copy(out, matrix)
20
24
  }
21
25
 
22
- len = 1 / len
26
+ const len = 1 / Math.sqrt(lengthSquared)
23
27
  x *= len
24
28
  y *= len
25
29
  z *= len
26
30
 
27
- const s = Math.sin(radians)
28
- const c = Math.cos(radians)
31
+ const s = sin(radians)
32
+ const c = cos(radians)
29
33
  const t = 1 - c
30
34
 
31
35
  const a00 = matrix[0]
@@ -1,3 +1,5 @@
1
+ const { sin, cos } = require('../utils/trigonometry')
2
+
1
3
  /**
2
4
  * Rotates a matrix by the given angle around the X axis.
3
5
  *
@@ -8,8 +10,8 @@
8
10
  * @alias module:modeling/maths/mat4.rotateX
9
11
  */
10
12
  const rotateX = (out, matrix, radians) => {
11
- const s = Math.sin(radians)
12
- const c = Math.cos(radians)
13
+ const s = sin(radians)
14
+ const c = cos(radians)
13
15
  const a10 = matrix[4]
14
16
  const a11 = matrix[5]
15
17
  const a12 = matrix[6]
@@ -1,3 +1,5 @@
1
+ const { sin, cos } = require('../utils/trigonometry')
2
+
1
3
  /**
2
4
  * Rotates a matrix by the given angle around the Y axis.
3
5
  *
@@ -8,8 +10,8 @@
8
10
  * @alias module:modeling/maths/mat4.rotateY
9
11
  */
10
12
  const rotateY = (out, matrix, radians) => {
11
- const s = Math.sin(radians)
12
- const c = Math.cos(radians)
13
+ const s = sin(radians)
14
+ const c = cos(radians)
13
15
  const a00 = matrix[0]
14
16
  const a01 = matrix[1]
15
17
  const a02 = matrix[2]
@@ -1,3 +1,5 @@
1
+ const { sin, cos } = require('../utils/trigonometry')
2
+
1
3
  /**
2
4
  * Rotates a matrix by the given angle around the Z axis.
3
5
  *
@@ -8,8 +10,8 @@
8
10
  * @alias module:modeling/maths/mat4.rotateZ
9
11
  */
10
12
  const rotateZ = (out, matrix, radians) => {
11
- const s = Math.sin(radians)
12
- const c = Math.cos(radians)
13
+ const s = sin(radians)
14
+ const c = cos(radians)
13
15
  const a00 = matrix[0]
14
16
  const a01 = matrix[1]
15
17
  const a02 = matrix[2]
@@ -52,10 +52,9 @@ test('mat4: translate() called with three parameters should update a mat4 with c
52
52
  t.true(compareVectors(obs4, [1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 2, 9, 30, 1]))
53
53
  t.true(compareVectors(ret4, [1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 2, 9, 30, 1]))
54
54
 
55
- const r = (90 * 0.017453292519943295)
56
55
  const rotateZMatrix = [
57
- Math.cos(r), -Math.sin(r), 0, 0,
58
- Math.sin(r), Math.cos(r), 0, 0,
56
+ 0, -1, 0, 0,
57
+ 1, 0, 0, 0,
59
58
  0, 0, 1, 0,
60
59
  0, 0, 0, 1
61
60
  ]
@@ -1,8 +1,4 @@
1
- // Normals are directional vectors with component values from 0 to 1.0, requiring specialized comparison
2
- // This EPS is derived from a series of tests to determine the optimal precision for comparing coplanar polygons,
3
- // as provided by the sphere primitive at high segmentation
4
- // This EPS is for 64 bit Number values
5
- const NEPS = 1e-13
1
+ const { NEPS } = require('../constants')
6
2
 
7
3
  /**
8
4
  * Compare two normals (unit vectors) for near equality.
@@ -3,5 +3,6 @@ export { default as area } from './area'
3
3
  export { default as interpolateBetween2DPointsForY } from './interpolateBetween2DPointsForY'
4
4
  export { default as intersect } from './intersect'
5
5
  export { default as solve2Linear } from './solve2Linear'
6
+ export { sin, cos } from './trigonometry'
6
7
 
7
8
  export as namespace utils
@@ -7,7 +7,9 @@
7
7
  module.exports = {
8
8
  aboutEqualNormals: require('./aboutEqualNormals'),
9
9
  area: require('./area'),
10
+ cos: require('./trigonometry').cos,
10
11
  interpolateBetween2DPointsForY: require('./interpolateBetween2DPointsForY'),
11
12
  intersect: require('./intersect'),
13
+ sin: require('./trigonometry').sin,
12
14
  solve2Linear: require('./solve2Linear')
13
15
  }
File without changes
@@ -1,5 +1,4 @@
1
-
2
- const NEPS = 1e-13
1
+ const { NEPS } = require('../constants')
3
2
 
4
3
  /*
5
4
  * Returns zero if n is within epsilon of zero, otherwise return n
File without changes
@@ -9,7 +9,7 @@
9
9
  const distance = (a, b) => {
10
10
  const x = b[0] - a[0]
11
11
  const y = b[1] - a[1]
12
- return Math.hypot(x, y)
12
+ return Math.sqrt(x * x + y * y)
13
13
  }
14
14
 
15
15
  module.exports = distance
@@ -1,3 +1,5 @@
1
+ const { sin, cos } = require('../utils/trigonometry')
2
+
1
3
  /**
2
4
  * Create a new vector in the direction of the given angle.
3
5
  *
@@ -7,8 +9,8 @@
7
9
  * @alias module:modeling/maths/vec2.fromAngleRadians
8
10
  */
9
11
  const fromAngleRadians = (out, radians) => {
10
- out[0] = Math.cos(radians)
11
- out[1] = Math.sin(radians)
12
+ out[0] = cos(radians)
13
+ out[1] = sin(radians)
12
14
  return out
13
15
  }
14
16
 
@@ -5,6 +5,6 @@
5
5
  * @returns {Number} length
6
6
  * @alias module:modeling/maths/vec2.length
7
7
  */
8
- const length = (vector) => Math.hypot(vector[0], vector[1])
8
+ const length = (vector) => Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1])
9
9
 
10
10
  module.exports = length
@@ -25,15 +25,5 @@ test('vec2: length() should return correct values', (t) => {
25
25
  const length5 = length(vec5)
26
26
  nearlyEqual(t, length5, 2.23606, EPS)
27
27
 
28
- // huge vector
29
- const vec6 = fromValues(1e200, 1e200)
30
- const length6 = length(vec6)
31
- nearlyEqual(t, length6, Math.SQRT2 * 1e200, EPS)
32
-
33
- // tiny vector
34
- const vec7 = fromValues(1e-200, 1e-200)
35
- const length7 = length(vec7)
36
- nearlyEqual(t, length7, Math.SQRT2 * 1e-200, EPS)
37
-
38
28
  t.true(true)
39
29
  })
@@ -15,8 +15,8 @@ const angle = (a, b) => {
15
15
  const bx = b[0]
16
16
  const by = b[1]
17
17
  const bz = b[2]
18
- const mag1 = Math.hypot(ax, ay, az)
19
- const mag2 = Math.hypot(bx, by, bz)
18
+ const mag1 = Math.sqrt(ax * ax + ay * ay + az * az)
19
+ const mag2 = Math.sqrt(bx * bx + by * by + bz * bz)
20
20
  const mag = mag1 * mag2
21
21
  const cosine = mag && dot(a, b) / mag
22
22
  return Math.acos(Math.min(Math.max(cosine, -1), 1))
@@ -30,17 +30,5 @@ test('vec3: angle() should return correct values', (t) => {
30
30
  const angle5 = angle(vec5a, vec5b)
31
31
  nearlyEqual(t, angle5, 0.785398, EPS)
32
32
 
33
- // tiny values
34
- const vec6a = fromValues(1, 0, 0)
35
- const vec6b = fromValues(1e-200, 1e-200, 0)
36
- const angle6 = angle(vec6a, vec6b)
37
- nearlyEqual(t, angle6, 0.785398, EPS)
38
-
39
- // huge values
40
- const vec7a = fromValues(1, 0, 0)
41
- const vec7b = fromValues(1e200, 1e200, 0)
42
- const angle7 = angle(vec7a, vec7b)
43
- nearlyEqual(t, angle7, 0.785398, EPS)
44
-
45
33
  t.true(true)
46
34
  })
@@ -10,7 +10,7 @@ const distance = (a, b) => {
10
10
  const x = b[0] - a[0]
11
11
  const y = b[1] - a[1]
12
12
  const z = b[2] - a[2]
13
- return Math.hypot(x, y, z)
13
+ return Math.sqrt(x * x + y * y + z * z)
14
14
  }
15
15
 
16
16
  module.exports = distance
@@ -9,7 +9,7 @@ const length = (vector) => {
9
9
  const x = vector[0]
10
10
  const y = vector[1]
11
11
  const z = vector[2]
12
- return Math.hypot(x, y, z)
12
+ return Math.sqrt(x * x + y * y + z * z)
13
13
  }
14
14
 
15
15
  module.exports = length
@@ -41,15 +41,5 @@ test('vec3: length() should return correct values', (t) => {
41
41
  const length9 = length(vec9)
42
42
  nearlyEqual(t, length9, 3.74165, EPS)
43
43
 
44
- // huge vector
45
- const vec10 = fromValues(1e200, 0, 1e200)
46
- const length10 = length(vec10)
47
- nearlyEqual(t, length10, Math.SQRT2 * 1e200, EPS)
48
-
49
- // tiny vector
50
- const vec11 = fromValues(1e-200, 0, 1e-200)
51
- const length11 = length(vec11)
52
- nearlyEqual(t, length11, Math.SQRT2 * 1e-200, EPS)
53
-
54
44
  t.true(true)
55
45
  })
@@ -0,0 +1,69 @@
1
+ const test = require('ava')
2
+
3
+ const { comparePoints } = require('../../../test/helpers')
4
+
5
+ const { geom2 } = require('../../geometries')
6
+
7
+ const { circle, rectangle } = require('../../primitives')
8
+
9
+ const { intersect } = require('./index')
10
+
11
+ const { center } = require('../transforms/center')
12
+
13
+ test('intersect: intersect of one or more geom2 objects produces expected geometry', (t) => {
14
+ const geometry1 = circle({ radius: 2, segments: 8 })
15
+
16
+ // intersect of one object
17
+ const result1 = intersect(geometry1)
18
+ let obs = geom2.toPoints(result1)
19
+ let exp = [
20
+ [2, 0],
21
+ [1.4142000000000001, 1.4142000000000001],
22
+ [0, 2],
23
+ [-1.4142000000000001, 1.4142000000000001],
24
+ [-2, 0],
25
+ [-1.4142000000000001, -1.4142000000000001],
26
+ [0, -2],
27
+ [1.4142000000000001, -1.4142000000000001]
28
+ ]
29
+ t.notThrows(() => geom2.validate(result1))
30
+ t.is(obs.length, 8)
31
+ t.true(comparePoints(obs, exp))
32
+
33
+ // intersect of two non-overlapping objects
34
+ const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
35
+
36
+ const result2 = intersect(geometry1, geometry2)
37
+ obs = geom2.toPoints(result2)
38
+ t.notThrows(() => geom2.validate(result2))
39
+ t.is(obs.length, 0)
40
+
41
+ // intersect of two partially overlapping objects
42
+ const geometry3 = rectangle({ size: [18, 18] })
43
+
44
+ const result3 = intersect(geometry2, geometry3)
45
+ obs = geom2.toPoints(result3)
46
+ exp = [
47
+ [9, 9], [8, 9], [8, 8], [9, 8]
48
+ ]
49
+ t.notThrows(() => geom2.validate(result3))
50
+ t.is(obs.length, 4)
51
+ t.true(comparePoints(obs, exp))
52
+
53
+ // intersect of two completely overlapping objects
54
+ const result4 = intersect(geometry1, geometry3)
55
+ obs = geom2.toPoints(result4)
56
+ exp = [
57
+ [2, 0],
58
+ [1.4142000000000001, 1.4142000000000001],
59
+ [0, 2],
60
+ [-1.4142000000000001, 1.4142000000000001],
61
+ [-2, 0],
62
+ [-1.4142000000000001, -1.4142000000000001],
63
+ [0, -2],
64
+ [1.4142000000000001, -1.4142000000000001]
65
+ ]
66
+ t.notThrows(() => geom2.validate(result4))
67
+ t.is(obs.length, 8)
68
+ t.true(comparePoints(obs, exp))
69
+ })
@@ -1,6 +1,7 @@
1
1
  const flatten = require('../../utils/flatten')
2
2
 
3
- const retessellate = require('./retessellate')
3
+ const retessellate = require('../modifiers/retessellate')
4
+
4
5
  const intersectSub = require('./intersectGeom3Sub')
5
6
 
6
7
  /*
@@ -1,83 +1,15 @@
1
1
  const test = require('ava')
2
2
 
3
- const { comparePolygonsAsPoints, comparePoints } = require('../../../test/helpers')
3
+ const { comparePolygonsAsPoints } = require('../../../test/helpers')
4
4
 
5
- const { geom2, geom3 } = require('../../geometries')
5
+ const { geom3 } = require('../../geometries')
6
6
 
7
- const { circle, rectangle, sphere, cuboid } = require('../../primitives')
7
+ const { sphere, cuboid } = require('../../primitives')
8
8
 
9
9
  const { intersect } = require('./index')
10
10
 
11
11
  const { center } = require('../transforms/center')
12
12
 
13
- // test('intersect: intersect of a path produces expected changes to points', (t) => {
14
- // let geometry = path.fromPoints({}, [[0, 1, 0], [1, 0, 0]])
15
- //
16
- // geometry = intersect({normal: [1, 0, 0]}, geometry)
17
- // let obs = path.toPoints(geometry)
18
- // let exp = []
19
- //
20
- // t.deepEqual(obs, exp)
21
- // })
22
-
23
- test('intersect: intersect of one or more geom2 objects produces expected geometry', (t) => {
24
- const geometry1 = circle({ radius: 2, segments: 8 })
25
-
26
- // intersect of one object
27
- const result1 = intersect(geometry1)
28
- let obs = geom2.toPoints(result1)
29
- let exp = [
30
- [2, 0],
31
- [1.4142000000000001, 1.4142000000000001],
32
- [0, 2],
33
- [-1.4142000000000001, 1.4142000000000001],
34
- [-2, 0],
35
- [-1.4142000000000001, -1.4142000000000001],
36
- [0, -2],
37
- [1.4142000000000001, -1.4142000000000001]
38
- ]
39
- t.notThrows(() => geom2.validate(result1))
40
- t.is(obs.length, 8)
41
- t.true(comparePoints(obs, exp))
42
-
43
- // intersect of two non-overlapping objects
44
- const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
45
-
46
- const result2 = intersect(geometry1, geometry2)
47
- obs = geom2.toPoints(result2)
48
- t.notThrows(() => geom2.validate(result2))
49
- t.is(obs.length, 0)
50
-
51
- // intersect of two partially overlapping objects
52
- const geometry3 = rectangle({ size: [18, 18] })
53
-
54
- const result3 = intersect(geometry2, geometry3)
55
- obs = geom2.toPoints(result3)
56
- exp = [
57
- [9, 9], [8, 9], [8, 8], [9, 8]
58
- ]
59
- t.notThrows(() => geom2.validate(result3))
60
- t.is(obs.length, 4)
61
- t.true(comparePoints(obs, exp))
62
-
63
- // intersect of two completely overlapping objects
64
- const result4 = intersect(geometry1, geometry3)
65
- obs = geom2.toPoints(result4)
66
- exp = [
67
- [2, 0],
68
- [1.4142000000000001, 1.4142000000000001],
69
- [0, 2],
70
- [-1.4142000000000001, 1.4142000000000001],
71
- [-2, 0],
72
- [-1.4142000000000001, -1.4142000000000001],
73
- [0, -2],
74
- [1.4142000000000001, -1.4142000000000001]
75
- ]
76
- t.notThrows(() => geom2.validate(result4))
77
- t.is(obs.length, 8)
78
- t.true(comparePoints(obs, exp))
79
- })
80
-
81
13
  test('intersect: intersect of one or more geom3 objects produces expected geometry', (t) => {
82
14
  const geometry1 = sphere({ radius: 2, segments: 8 })
83
15
 
@@ -0,0 +1,72 @@
1
+ const test = require('ava')
2
+
3
+ const { comparePoints } = require('../../../test/helpers')
4
+
5
+ const { geom2 } = require('../../geometries')
6
+
7
+ const { circle, rectangle } = require('../../primitives')
8
+
9
+ const { subtract } = require('./index')
10
+
11
+ const { center } = require('../transforms/center')
12
+
13
+ test('subtract: subtract of one or more geom2 objects produces expected geometry', (t) => {
14
+ const geometry1 = circle({ radius: 2, segments: 8 })
15
+
16
+ // subtract of one object
17
+ const result1 = subtract(geometry1)
18
+ let obs = geom2.toPoints(result1)
19
+ let exp = [
20
+ [2, 0],
21
+ [1.4142000000000001, 1.4142000000000001],
22
+ [0, 2],
23
+ [-1.4142000000000001, 1.4142000000000001],
24
+ [-2, 0],
25
+ [-1.4142000000000001, -1.4142000000000001],
26
+ [0, -2],
27
+ [1.4142000000000001, -1.4142000000000001]
28
+ ]
29
+ t.notThrows(() => geom2.validate(result1))
30
+ t.is(obs.length, 8)
31
+ t.true(comparePoints(obs, exp))
32
+
33
+ // subtract of two non-overlapping objects
34
+ const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
35
+
36
+ const result2 = subtract(geometry1, geometry2)
37
+ obs = geom2.toPoints(result2)
38
+ exp = [
39
+ [2, 0],
40
+ [1.4142000000000001, 1.4142000000000001],
41
+ [0, 2],
42
+ [-1.4142000000000001, 1.4142000000000001],
43
+ [-2, 0],
44
+ [-1.4142000000000001, -1.4142000000000001],
45
+ [0, -2],
46
+ [1.4142000000000001, -1.4142000000000001]
47
+ ]
48
+ t.notThrows(() => geom2.validate(result2))
49
+ t.is(obs.length, 8)
50
+ t.true(comparePoints(obs, exp))
51
+
52
+ // subtract of two partially overlapping objects
53
+ const geometry3 = rectangle({ size: [18, 18] })
54
+
55
+ const result3 = subtract(geometry2, geometry3)
56
+ obs = geom2.toPoints(result3)
57
+ exp = [
58
+ [12, 12], [9, 9], [8, 9], [8, 12], [9, 8], [12, 8]
59
+ ]
60
+ t.notThrows(() => geom2.validate(result3))
61
+ t.is(obs.length, 6)
62
+ t.true(comparePoints(obs, exp))
63
+
64
+ // subtract of two completely overlapping objects
65
+ const result4 = subtract(geometry1, geometry3)
66
+ obs = geom2.toPoints(result4)
67
+ exp = [
68
+ ]
69
+ t.notThrows(() => geom2.validate(result4))
70
+ t.is(obs.length, 0)
71
+ t.deepEqual(obs, exp)
72
+ })
@@ -1,6 +1,7 @@
1
1
  const flatten = require('../../utils/flatten')
2
2
 
3
- const retessellate = require('./retessellate')
3
+ const retessellate = require('../modifiers/retessellate')
4
+
4
5
  const subtractSub = require('./subtractGeom3Sub')
5
6
 
6
7
  /*
@@ -1,86 +1,15 @@
1
1
  const test = require('ava')
2
2
 
3
- const { comparePolygonsAsPoints, comparePoints } = require('../../../test/helpers')
3
+ const { comparePolygonsAsPoints } = require('../../../test/helpers')
4
4
 
5
- const { geom2, geom3 } = require('../../geometries')
5
+ const { geom3 } = require('../../geometries')
6
6
 
7
- const { circle, rectangle, sphere, cuboid } = require('../../primitives')
7
+ const { sphere, cuboid } = require('../../primitives')
8
8
 
9
9
  const { subtract } = require('./index')
10
10
 
11
11
  const { center } = require('../transforms/center')
12
12
 
13
- // test('subtract: subtract of a path produces expected changes to points', (t) => {
14
- // let geometry = path.fromPoints({}, [[0, 1, 0], [1, 0, 0]])
15
- //
16
- // geometry = subtract({normal: [1, 0, 0]}, geometry)
17
- // let obs = path.toPoints(geometry)
18
- // let exp = []
19
- //
20
- // t.deepEqual(obs, exp)
21
- // })
22
-
23
- test('subtract: subtract of one or more geom2 objects produces expected geometry', (t) => {
24
- const geometry1 = circle({ radius: 2, segments: 8 })
25
-
26
- // subtract of one object
27
- const result1 = subtract(geometry1)
28
- let obs = geom2.toPoints(result1)
29
- let exp = [
30
- [2, 0],
31
- [1.4142000000000001, 1.4142000000000001],
32
- [0, 2],
33
- [-1.4142000000000001, 1.4142000000000001],
34
- [-2, 0],
35
- [-1.4142000000000001, -1.4142000000000001],
36
- [0, -2],
37
- [1.4142000000000001, -1.4142000000000001]
38
- ]
39
- t.notThrows(() => geom2.validate(result1))
40
- t.is(obs.length, 8)
41
- t.true(comparePoints(obs, exp))
42
-
43
- // subtract of two non-overlapping objects
44
- const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
45
-
46
- const result2 = subtract(geometry1, geometry2)
47
- obs = geom2.toPoints(result2)
48
- exp = [
49
- [2, 0],
50
- [1.4142000000000001, 1.4142000000000001],
51
- [0, 2],
52
- [-1.4142000000000001, 1.4142000000000001],
53
- [-2, 0],
54
- [-1.4142000000000001, -1.4142000000000001],
55
- [0, -2],
56
- [1.4142000000000001, -1.4142000000000001]
57
- ]
58
- t.notThrows(() => geom2.validate(result2))
59
- t.is(obs.length, 8)
60
- t.true(comparePoints(obs, exp))
61
-
62
- // subtract of two partially overlapping objects
63
- const geometry3 = rectangle({ size: [18, 18] })
64
-
65
- const result3 = subtract(geometry2, geometry3)
66
- obs = geom2.toPoints(result3)
67
- exp = [
68
- [12, 12], [9, 9], [8, 9], [8, 12], [9, 8], [12, 8]
69
- ]
70
- t.notThrows(() => geom2.validate(result3))
71
- t.is(obs.length, 6)
72
- t.true(comparePoints(obs, exp))
73
-
74
- // subtract of two completely overlapping objects
75
- const result4 = subtract(geometry1, geometry3)
76
- obs = geom2.toPoints(result4)
77
- exp = [
78
- ]
79
- t.notThrows(() => geom2.validate(result4))
80
- t.is(obs.length, 0)
81
- t.deepEqual(obs, exp)
82
- })
83
-
84
13
  test('subtract: subtract of one or more geom3 objects produces expected geometry', (t) => {
85
14
  const geometry1 = sphere({ radius: 2, segments: 8 })
86
15
 
@@ -14,7 +14,7 @@ const to3DWall = (z0, z1, side) => {
14
14
  vec3.fromVec2(vec3.create(), side[1], z1),
15
15
  vec3.fromVec2(vec3.create(), side[0], z1)
16
16
  ]
17
- return poly3.fromPoints(points)
17
+ return poly3.create(points)
18
18
  }
19
19
 
20
20
  /*