@jscad/modeling 2.9.0 → 2.9.3
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.
- package/CHANGELOG.md +42 -0
- package/README.md +4 -4
- package/dist/jscad-modeling.min.js +437 -428
- package/package.json +3 -2
- package/src/colors/colorize.test.js +1 -1
- package/src/geometries/geom2/index.d.ts +1 -0
- package/src/geometries/geom2/index.js +2 -1
- package/src/geometries/geom2/toOutlines.js +66 -52
- package/src/geometries/geom2/validate.d.ts +3 -0
- package/src/geometries/geom2/validate.js +36 -0
- package/src/geometries/geom3/create.js +1 -1
- package/src/geometries/geom3/create.test.js +1 -1
- package/src/geometries/geom3/fromPoints.js +1 -1
- package/src/geometries/geom3/index.d.ts +1 -0
- package/src/geometries/geom3/index.js +2 -1
- package/src/geometries/geom3/isA.js +1 -1
- package/src/geometries/geom3/validate.d.ts +3 -0
- package/src/geometries/geom3/validate.js +62 -0
- package/src/geometries/path2/index.d.ts +1 -1
- package/src/geometries/path2/index.js +2 -2
- package/src/geometries/path2/validate.d.ts +3 -0
- package/src/geometries/path2/validate.js +41 -0
- package/src/geometries/poly2/arePointsInside.js +0 -35
- package/src/geometries/poly3/create.js +1 -1
- package/src/geometries/poly3/index.d.ts +1 -0
- package/src/geometries/poly3/index.js +2 -1
- package/src/geometries/poly3/measureArea.test.js +16 -16
- package/src/geometries/poly3/measureBoundingSphere.test.js +8 -8
- package/src/geometries/poly3/validate.d.ts +4 -0
- package/src/geometries/poly3/validate.js +64 -0
- package/src/maths/constants.d.ts +1 -0
- package/src/maths/constants.js +11 -0
- package/src/maths/utils/aboutEqualNormals.js +1 -5
- package/src/measurements/measureCenterOfMass.test.js +2 -2
- package/src/operations/booleans/intersect.test.js +8 -0
- package/src/operations/booleans/intersectGeom3.js +2 -1
- package/src/operations/booleans/scission.test.js +4 -4
- package/src/operations/booleans/subtract.test.js +8 -0
- package/src/operations/booleans/subtractGeom3.js +2 -1
- package/src/operations/booleans/to3DWalls.js +1 -1
- package/src/operations/booleans/trees/Node.js +10 -16
- package/src/operations/booleans/trees/PolygonTreeNode.js +13 -14
- package/src/operations/booleans/trees/Tree.js +1 -2
- package/src/operations/booleans/trees/splitPolygonByPlane.js +2 -3
- package/src/operations/booleans/union.test.js +27 -0
- package/src/operations/booleans/unionGeom3.js +2 -1
- package/src/operations/expansions/expand.test.js +30 -21
- package/src/operations/expansions/expandGeom3.test.js +14 -14
- package/src/operations/expansions/expandShell.js +5 -4
- package/src/operations/expansions/extrudePolygon.js +7 -7
- package/src/operations/expansions/offset.test.js +25 -0
- package/src/operations/extrusions/earcut/assignHoles.js +7 -3
- package/src/operations/extrusions/earcut/assignHoles.test.js +50 -4
- package/src/operations/extrusions/earcut/linkedList.js +1 -1
- package/src/operations/extrusions/extrudeFromSlices.test.js +16 -10
- package/src/operations/extrusions/extrudeLinear.test.js +15 -9
- package/src/operations/extrusions/extrudeRectangular.test.js +15 -8
- package/src/operations/extrusions/extrudeRotate.js +5 -1
- package/src/operations/extrusions/extrudeRotate.test.js +12 -0
- package/src/operations/extrusions/extrudeWalls.js +2 -2
- package/src/operations/extrusions/project.js +11 -14
- package/src/operations/extrusions/project.test.js +55 -55
- package/src/operations/hulls/hull.test.js +24 -1
- package/src/operations/hulls/hullChain.test.js +6 -4
- package/src/operations/hulls/hullGeom2.js +6 -18
- package/src/operations/hulls/hullGeom3.js +5 -18
- package/src/operations/hulls/hullPath2.js +4 -14
- package/src/operations/hulls/hullPath2.test.js +1 -1
- package/src/operations/hulls/hullPoints2.js +43 -92
- package/src/operations/hulls/toUniquePoints.js +34 -0
- package/src/operations/modifiers/generalize.js +2 -13
- package/src/operations/modifiers/generalize.test.js +5 -31
- package/src/operations/modifiers/insertTjunctions.js +1 -1
- package/src/operations/modifiers/insertTjunctions.test.js +21 -21
- package/src/operations/modifiers/mergePolygons.js +11 -14
- package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.js +1 -1
- package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.test.js +5 -5
- package/src/operations/{booleans → modifiers}/retessellate.js +2 -9
- package/src/operations/{booleans → modifiers}/retessellate.test.js +0 -0
- package/src/operations/modifiers/snapPolygons.test.js +12 -12
- package/src/operations/modifiers/triangulatePolygons.js +3 -3
- package/src/operations/transforms/align.test.js +12 -0
- package/src/operations/transforms/center.js +1 -1
- package/src/operations/transforms/center.test.js +12 -0
- package/src/operations/transforms/mirror.test.js +16 -0
- package/src/operations/transforms/rotate.test.js +10 -0
- package/src/operations/transforms/scale.test.js +15 -0
- package/src/operations/transforms/transform.test.js +5 -0
- package/src/operations/transforms/translate.test.js +16 -0
- package/src/primitives/arc.test.js +11 -0
- package/src/primitives/circle.test.js +15 -9
- package/src/primitives/cube.test.js +3 -0
- package/src/primitives/cuboid.js +1 -1
- package/src/primitives/cuboid.test.js +9 -24
- package/src/primitives/cylinder.test.js +7 -4
- package/src/primitives/cylinderElliptic.js +14 -7
- package/src/primitives/cylinderElliptic.test.js +72 -50
- package/src/primitives/ellipse.js +3 -1
- package/src/primitives/ellipse.test.js +14 -8
- package/src/primitives/ellipsoid.js +8 -6
- package/src/primitives/ellipsoid.test.js +84 -80
- package/src/primitives/geodesicSphere.test.js +3 -0
- package/src/primitives/line.test.js +1 -0
- package/src/primitives/polygon.test.js +15 -10
- package/src/primitives/polyhedron.js +1 -1
- package/src/primitives/polyhedron.test.js +14 -42
- package/src/primitives/rectangle.test.js +3 -0
- package/src/primitives/roundedCuboid.js +6 -6
- package/src/primitives/roundedCuboid.test.js +5 -0
- package/src/primitives/roundedCylinder.js +7 -5
- package/src/primitives/roundedCylinder.test.js +40 -36
- package/src/primitives/roundedRectangle.test.js +5 -0
- package/src/primitives/sphere.test.js +52 -73
- package/src/primitives/square.test.js +3 -0
- package/src/primitives/star.test.js +6 -0
- package/src/primitives/torus.test.js +8 -1
- package/src/primitives/triangle.js +1 -2
- package/src/primitives/triangle.test.js +7 -0
- package/src/utils/areAllShapesTheSameType.js +2 -2
- package/src/utils/areAllShapesTheSameType.test.js +17 -0
- package/src/utils/index.d.ts +1 -0
- package/src/utils/index.js +3 -1
- package/src/utils/trigonometry.d.ts +2 -0
- package/src/utils/trigonometry.js +34 -0
- package/src/utils/trigonometry.test.js +25 -0
- package/test/helpers/nearlyEqual.js +4 -1
- package/src/geometries/path2/eachPoint.d.ts +0 -9
- package/src/geometries/path2/eachPoint.js +0 -17
- package/src/geometries/path2/eachPoint.test.js +0 -11
- package/src/operations/modifiers/edges.js +0 -195
- package/src/operations/modifiers/repairTjunctions.js +0 -44
|
@@ -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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
[[1
|
|
18
|
-
|
|
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,
|
|
37
|
-
[[4,
|
|
38
|
-
[1.236067977499789, -3.8042260651806146,
|
|
39
|
-
[[0, 0, 5], [1.236067977499789, -3.8042260651806146, 5], [4,
|
|
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
|
|
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
|
|
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] *
|
|
79
|
-
vec3.scale(v2, axisY, radius[1] *
|
|
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)
|
|
@@ -87,7 +90,7 @@ const cylinderElliptic = (options) => {
|
|
|
87
90
|
// adjust the points to center
|
|
88
91
|
const fromPoints = (...points) => {
|
|
89
92
|
const newpoints = points.map((point) => vec3.add(vec3.create(), point, center))
|
|
90
|
-
return poly3.
|
|
93
|
+
return poly3.create(newpoints)
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
const polygons = []
|
|
@@ -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
|
}
|
|
@@ -10,6 +10,7 @@ test('cylinderElliptic (defaults)', (t) => {
|
|
|
10
10
|
const obs = cylinderElliptic()
|
|
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
|
|
|
@@ -26,48 +27,49 @@ test('cylinderElliptic (options)', (t) => {
|
|
|
26
27
|
[[0.5000000000000001, 0.8660254037844386, -5], [0.5000000000000001, 0.8660254037844386, 5],
|
|
27
28
|
[0.8660254037844387, 0.49999999999999994, 5], [0.8660254037844387, 0.49999999999999994, -5]],
|
|
28
29
|
[[0, 0, 5], [0.8660254037844387, 0.49999999999999994, 5], [0.5000000000000001, 0.8660254037844386, 5]],
|
|
29
|
-
[[0, 0, -5], [
|
|
30
|
-
[[
|
|
30
|
+
[[0, 0, -5], [0, 1, -5], [0.5000000000000001, 0.8660254037844386, -5]],
|
|
31
|
+
[[0, 1, -5], [0, 1, 5],
|
|
31
32
|
[0.5000000000000001, 0.8660254037844386, 5], [0.5000000000000001, 0.8660254037844386, -5]],
|
|
32
|
-
[[0, 0, 5], [0.5000000000000001, 0.8660254037844386, 5], [
|
|
33
|
-
[[0, 0, -5], [-0.4999999999999998, 0.8660254037844387, -5], [
|
|
33
|
+
[[0, 0, 5], [0.5000000000000001, 0.8660254037844386, 5], [0, 1, 5]],
|
|
34
|
+
[[0, 0, -5], [-0.4999999999999998, 0.8660254037844387, -5], [0, 1, -5]],
|
|
34
35
|
[[-0.4999999999999998, 0.8660254037844387, -5], [-0.4999999999999998, 0.8660254037844387, 5],
|
|
35
|
-
[
|
|
36
|
-
[[0, 0, 5], [
|
|
36
|
+
[0, 1, 5], [0, 1, -5]],
|
|
37
|
+
[[0, 0, 5], [0, 1, 5], [-0.4999999999999998, 0.8660254037844387, 5]],
|
|
37
38
|
[[0, 0, -5], [-0.8660254037844387, 0.49999999999999994, -5], [-0.4999999999999998, 0.8660254037844387, -5]],
|
|
38
39
|
[[-0.8660254037844387, 0.49999999999999994, -5], [-0.8660254037844387, 0.49999999999999994, 5],
|
|
39
40
|
[-0.4999999999999998, 0.8660254037844387, 5], [-0.4999999999999998, 0.8660254037844387, -5]],
|
|
40
41
|
[[0, 0, 5], [-0.4999999999999998, 0.8660254037844387, 5], [-0.8660254037844387, 0.49999999999999994, 5]],
|
|
41
|
-
[[0, 0, -5], [-1,
|
|
42
|
-
[[-1,
|
|
42
|
+
[[0, 0, -5], [-1, 0, -5], [-0.8660254037844387, 0.49999999999999994, -5]],
|
|
43
|
+
[[-1, 0, -5], [-1, 0, 5],
|
|
43
44
|
[-0.8660254037844387, 0.49999999999999994, 5], [-0.8660254037844387, 0.49999999999999994, -5]],
|
|
44
|
-
[[0, 0, 5], [-0.8660254037844387, 0.49999999999999994, 5], [-1,
|
|
45
|
-
[[0, 0, -5], [-0.8660254037844386, -0.5000000000000001, -5], [-1,
|
|
45
|
+
[[0, 0, 5], [-0.8660254037844387, 0.49999999999999994, 5], [-1, 0, 5]],
|
|
46
|
+
[[0, 0, -5], [-0.8660254037844386, -0.5000000000000001, -5], [-1, 0, -5]],
|
|
46
47
|
[[-0.8660254037844386, -0.5000000000000001, -5], [-0.8660254037844386, -0.5000000000000001, 5],
|
|
47
|
-
[-1,
|
|
48
|
-
[[0, 0, 5], [-1,
|
|
48
|
+
[-1, 0, 5], [-1, 0, -5]],
|
|
49
|
+
[[0, 0, 5], [-1, 0, 5], [-0.8660254037844386, -0.5000000000000001, 5]],
|
|
49
50
|
[[0, 0, -5], [-0.5000000000000004, -0.8660254037844385, -5], [-0.8660254037844386, -0.5000000000000001, -5]],
|
|
50
51
|
[[-0.5000000000000004, -0.8660254037844385, -5], [-0.5000000000000004, -0.8660254037844385, 5],
|
|
51
52
|
[-0.8660254037844386, -0.5000000000000001, 5], [-0.8660254037844386, -0.5000000000000001, -5]],
|
|
52
53
|
[[0, 0, 5], [-0.8660254037844386, -0.5000000000000001, 5], [-0.5000000000000004, -0.8660254037844385, 5]],
|
|
53
|
-
[[0, 0, -5], [
|
|
54
|
-
[[
|
|
54
|
+
[[0, 0, -5], [0, -1, -5], [-0.5000000000000004, -0.8660254037844385, -5]],
|
|
55
|
+
[[0, -1, -5], [0, -1, 5],
|
|
55
56
|
[-0.5000000000000004, -0.8660254037844385, 5], [-0.5000000000000004, -0.8660254037844385, -5]],
|
|
56
|
-
[[0, 0, 5], [-0.5000000000000004, -0.8660254037844385, 5], [
|
|
57
|
-
[[0, 0, -5], [0.5000000000000001, -0.8660254037844386, -5], [
|
|
57
|
+
[[0, 0, 5], [-0.5000000000000004, -0.8660254037844385, 5], [0, -1, 5]],
|
|
58
|
+
[[0, 0, -5], [0.5000000000000001, -0.8660254037844386, -5], [0, -1, -5]],
|
|
58
59
|
[[0.5000000000000001, -0.8660254037844386, -5], [0.5000000000000001, -0.8660254037844386, 5],
|
|
59
|
-
[
|
|
60
|
-
[[0, 0, 5], [
|
|
60
|
+
[0, -1, 5], [0, -1, -5]],
|
|
61
|
+
[[0, 0, 5], [0, -1, 5], [0.5000000000000001, -0.8660254037844386, 5]],
|
|
61
62
|
[[0, 0, -5], [0.8660254037844384, -0.5000000000000004, -5], [0.5000000000000001, -0.8660254037844386, -5]],
|
|
62
63
|
[[0.8660254037844384, -0.5000000000000004, -5], [0.8660254037844384, -0.5000000000000004, 5],
|
|
63
64
|
[0.5000000000000001, -0.8660254037844386, 5], [0.5000000000000001, -0.8660254037844386, -5]],
|
|
64
65
|
[[0, 0, 5], [0.5000000000000001, -0.8660254037844386, 5], [0.8660254037844384, -0.5000000000000004, 5]],
|
|
65
|
-
[[0, 0, -5], [1,
|
|
66
|
-
[[1,
|
|
67
|
-
[0.8660254037844384, -0.5000000000000004,
|
|
68
|
-
[[0, 0, 5], [0.8660254037844384, -0.5000000000000004, 5], [1,
|
|
66
|
+
[[0, 0, -5], [1, 0, -5], [0.8660254037844384, -0.5000000000000004, -5]],
|
|
67
|
+
[[1, 0, -5], [1, 0, 5], [0.8660254037844384, -0.5000000000000004, 5],
|
|
68
|
+
[0.8660254037844384, -0.5000000000000004, -5]],
|
|
69
|
+
[[0, 0, 5], [0.8660254037844384, -0.5000000000000004, 5], [1, 0, 5]]
|
|
69
70
|
]
|
|
70
71
|
|
|
72
|
+
t.notThrows(() => geom3.validate(obs))
|
|
71
73
|
t.is(pts.length, 36)
|
|
72
74
|
t.true(comparePolygonsAsPoints(pts, exp))
|
|
73
75
|
|
|
@@ -83,48 +85,49 @@ test('cylinderElliptic (options)', (t) => {
|
|
|
83
85
|
[[0.8660254037844387, 0.9999999999999999, -1], [0.5000000000000001, 1.7320508075688772, -1], [1.7320508075688774, 0.49999999999999994, 1]],
|
|
84
86
|
[[0, 0, 1], [1.7320508075688774, 0.49999999999999994, 1], [1.0000000000000002, 0.8660254037844386, 1]],
|
|
85
87
|
[[1.7320508075688774, 0.49999999999999994, 1], [0.5000000000000001, 1.7320508075688772, -1], [1.0000000000000002, 0.8660254037844386, 1]],
|
|
86
|
-
[[0, 0, -1], [
|
|
87
|
-
[[0.5000000000000001, 1.7320508075688772, -1], [
|
|
88
|
-
[[0, 0, 1], [1.0000000000000002, 0.8660254037844386, 1], [
|
|
89
|
-
[[1.0000000000000002, 0.8660254037844386, 1], [
|
|
90
|
-
[[0, 0, -1], [-0.4999999999999998, 1.7320508075688774, -1], [
|
|
91
|
-
[[
|
|
92
|
-
[[0, 0, 1], [
|
|
93
|
-
[[
|
|
88
|
+
[[0, 0, -1], [0, 2, -1], [0.5000000000000001, 1.7320508075688772, -1]],
|
|
89
|
+
[[0.5000000000000001, 1.7320508075688772, -1], [0, 2, -1], [1.0000000000000002, 0.8660254037844386, 1]],
|
|
90
|
+
[[0, 0, 1], [1.0000000000000002, 0.8660254037844386, 1], [0, 1, 1]],
|
|
91
|
+
[[1.0000000000000002, 0.8660254037844386, 1], [0, 2, -1], [0, 1, 1]],
|
|
92
|
+
[[0, 0, -1], [-0.4999999999999998, 1.7320508075688774, -1], [0, 2, -1]],
|
|
93
|
+
[[0, 2, -1], [-0.4999999999999998, 1.7320508075688774, -1], [0, 1, 1]],
|
|
94
|
+
[[0, 0, 1], [0, 1, 1], [-0.9999999999999996, 0.8660254037844387, 1]],
|
|
95
|
+
[[0, 1, 1], [-0.4999999999999998, 1.7320508075688774, -1], [-0.9999999999999996, 0.8660254037844387, 1]],
|
|
94
96
|
[[0, 0, -1], [-0.8660254037844387, 0.9999999999999999, -1], [-0.4999999999999998, 1.7320508075688774, -1]],
|
|
95
97
|
[[-0.4999999999999998, 1.7320508075688774, -1], [-0.8660254037844387, 0.9999999999999999, -1], [-0.9999999999999996, 0.8660254037844387, 1]],
|
|
96
98
|
[[0, 0, 1], [-0.9999999999999996, 0.8660254037844387, 1], [-1.7320508075688774, 0.49999999999999994, 1]],
|
|
97
99
|
[[-0.9999999999999996, 0.8660254037844387, 1], [-0.8660254037844387, 0.9999999999999999, -1], [-1.7320508075688774, 0.49999999999999994, 1]],
|
|
98
|
-
[[0, 0, -1], [-1,
|
|
99
|
-
[[-0.8660254037844387, 0.9999999999999999, -1], [-1,
|
|
100
|
-
[[0, 0, 1], [-1.7320508075688774, 0.49999999999999994, 1], [-2,
|
|
101
|
-
[[-1.7320508075688774, 0.49999999999999994, 1], [-1,
|
|
102
|
-
[[0, 0, -1], [-0.8660254037844386, -1.0000000000000002, -1], [-1,
|
|
103
|
-
[[-1,
|
|
104
|
-
[[0, 0, 1], [-2,
|
|
105
|
-
[[-2,
|
|
100
|
+
[[0, 0, -1], [-1, 0, -1], [-0.8660254037844387, 0.9999999999999999, -1]],
|
|
101
|
+
[[-0.8660254037844387, 0.9999999999999999, -1], [-1, 0, -1], [-1.7320508075688774, 0.49999999999999994, 1]],
|
|
102
|
+
[[0, 0, 1], [-1.7320508075688774, 0.49999999999999994, 1], [-2, 0, 1]],
|
|
103
|
+
[[-1.7320508075688774, 0.49999999999999994, 1], [-1, 0, -1], [-2, 0, 1]],
|
|
104
|
+
[[0, 0, -1], [-0.8660254037844386, -1.0000000000000002, -1], [-1, 0, -1]],
|
|
105
|
+
[[-1, 0, -1], [-0.8660254037844386, -1.0000000000000002, -1], [-2, 0, 1]],
|
|
106
|
+
[[0, 0, 1], [-2, 0, 1], [-1.7320508075688772, -0.5000000000000001, 1]],
|
|
107
|
+
[[-2, 0, 1], [-0.8660254037844386, -1.0000000000000002, -1], [-1.7320508075688772, -0.5000000000000001, 1]],
|
|
106
108
|
[[0, 0, -1], [-0.5000000000000004, -1.732050807568877, -1], [-0.8660254037844386, -1.0000000000000002, -1]],
|
|
107
109
|
[[-0.8660254037844386, -1.0000000000000002, -1], [-0.5000000000000004, -1.732050807568877, -1], [-1.7320508075688772, -0.5000000000000001, 1]],
|
|
108
110
|
[[0, 0, 1], [-1.7320508075688772, -0.5000000000000001, 1], [-1.0000000000000009, -0.8660254037844385, 1]],
|
|
109
111
|
[[-1.7320508075688772, -0.5000000000000001, 1], [-0.5000000000000004, -1.732050807568877, -1], [-1.0000000000000009, -0.8660254037844385, 1]],
|
|
110
|
-
[[0, 0, -1], [
|
|
111
|
-
[[-0.5000000000000004, -1.732050807568877, -1], [
|
|
112
|
-
[[0, 0, 1], [-1.0000000000000009, -0.8660254037844385, 1], [
|
|
113
|
-
[[-1.0000000000000009, -0.8660254037844385, 1], [
|
|
114
|
-
[[0, 0, -1], [0.5000000000000001, -1.7320508075688772, -1], [
|
|
115
|
-
[[
|
|
116
|
-
[[0, 0, 1], [
|
|
117
|
-
[[
|
|
112
|
+
[[0, 0, -1], [0, -2, -1], [-0.5000000000000004, -1.732050807568877, -1]],
|
|
113
|
+
[[-0.5000000000000004, -1.732050807568877, -1], [0, -2, -1], [-1.0000000000000009, -0.8660254037844385, 1]],
|
|
114
|
+
[[0, 0, 1], [-1.0000000000000009, -0.8660254037844385, 1], [0, -1, 1]],
|
|
115
|
+
[[-1.0000000000000009, -0.8660254037844385, 1], [0, -2, -1], [0, -1, 1]],
|
|
116
|
+
[[0, 0, -1], [0.5000000000000001, -1.7320508075688772, -1], [0, -2, -1]],
|
|
117
|
+
[[0, -2, -1], [0.5000000000000001, -1.7320508075688772, -1], [0, -1, 1]],
|
|
118
|
+
[[0, 0, 1], [0, -1, 1], [1.0000000000000002, -0.8660254037844386, 1]],
|
|
119
|
+
[[0, -1, 1], [0.5000000000000001, -1.7320508075688772, -1], [1.0000000000000002, -0.8660254037844386, 1]],
|
|
118
120
|
[[0, 0, -1], [0.8660254037844384, -1.0000000000000009, -1], [0.5000000000000001, -1.7320508075688772, -1]],
|
|
119
121
|
[[0.5000000000000001, -1.7320508075688772, -1], [0.8660254037844384, -1.0000000000000009, -1], [1.0000000000000002, -0.8660254037844386, 1]],
|
|
120
122
|
[[0, 0, 1], [1.0000000000000002, -0.8660254037844386, 1], [1.7320508075688767, -0.5000000000000004, 1]],
|
|
121
123
|
[[1.0000000000000002, -0.8660254037844386, 1], [0.8660254037844384, -1.0000000000000009, -1], [1.7320508075688767, -0.5000000000000004, 1]],
|
|
122
|
-
[[0, 0, -1], [1,
|
|
123
|
-
[[0.8660254037844384, -1.0000000000000009, -1], [1,
|
|
124
|
-
[[0, 0, 1], [1.7320508075688767, -0.5000000000000004, 1], [2,
|
|
125
|
-
[[1.7320508075688767, -0.5000000000000004, 1], [1,
|
|
124
|
+
[[0, 0, -1], [1, 0, -1], [0.8660254037844384, -1.0000000000000009, -1]],
|
|
125
|
+
[[0.8660254037844384, -1.0000000000000009, -1], [1, 0, -1], [1.7320508075688767, -0.5000000000000004, 1]],
|
|
126
|
+
[[0, 0, 1], [1.7320508075688767, -0.5000000000000004, 1], [2, 0, 1]],
|
|
127
|
+
[[1.7320508075688767, -0.5000000000000004, 1], [1, 0, -1], [2, 0, 1]]
|
|
126
128
|
]
|
|
127
129
|
|
|
130
|
+
t.notThrows(() => geom3.validate(obs))
|
|
128
131
|
t.is(pts.length, 48)
|
|
129
132
|
t.true(comparePolygonsAsPoints(pts, exp))
|
|
130
133
|
|
|
@@ -132,6 +135,7 @@ test('cylinderElliptic (options)', (t) => {
|
|
|
132
135
|
obs = cylinderElliptic({ startRadius: [1, 2], endRadius: [2, 1], startAngle: Math.PI / 2, endAngle: Math.PI * 2 * 0.75, segments: 12 })
|
|
133
136
|
pts = geom3.toPoints(obs)
|
|
134
137
|
|
|
138
|
+
t.notThrows(() => geom3.validate(obs))
|
|
135
139
|
t.is(pts.length, 28)
|
|
136
140
|
// t.true(comparePolygonsAsPoints(pts, exp))
|
|
137
141
|
|
|
@@ -139,6 +143,7 @@ test('cylinderElliptic (options)', (t) => {
|
|
|
139
143
|
obs = cylinderElliptic({ segments: 8 })
|
|
140
144
|
pts = geom3.toPoints(obs)
|
|
141
145
|
|
|
146
|
+
t.notThrows(() => geom3.validate(obs))
|
|
142
147
|
t.is(pts.length, 24)
|
|
143
148
|
|
|
144
149
|
// test center
|
|
@@ -179,6 +184,23 @@ test('cylinderElliptic (options)', (t) => {
|
|
|
179
184
|
[[-5, -5, -3.5], [-4.292893218813453, -5.707106781186548, -3.5], [-4, -5, -3.5]]
|
|
180
185
|
]
|
|
181
186
|
|
|
187
|
+
t.notThrows(() => geom3.validate(obs))
|
|
182
188
|
t.is(pts.length, 24)
|
|
183
189
|
t.true(comparePolygonsAsPoints(pts, exp))
|
|
184
190
|
})
|
|
191
|
+
|
|
192
|
+
test('cylinderElliptic (cone)', (t) => {
|
|
193
|
+
const obs = cylinderElliptic({ endRadius: [0, 0] })
|
|
194
|
+
const pts = geom3.toPoints(obs)
|
|
195
|
+
|
|
196
|
+
t.notThrows(() => geom3.validate(obs))
|
|
197
|
+
t.is(pts.length, 64)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
test('cylinderElliptic (squished)', (t) => {
|
|
201
|
+
const obs = cylinderElliptic({ startRadius: [1, 0], endRadius: [0, 1], segments: 4 })
|
|
202
|
+
const pts = geom3.toPoints(obs)
|
|
203
|
+
|
|
204
|
+
t.notThrows(() => geom3.validate(obs))
|
|
205
|
+
t.is(pts.length, 8)
|
|
206
|
+
})
|
|
@@ -4,6 +4,8 @@ const vec2 = require('../maths/vec2')
|
|
|
4
4
|
|
|
5
5
|
const geom2 = require('../geometries/geom2')
|
|
6
6
|
|
|
7
|
+
const { sin, cos } = require('../utils/trigonometry')
|
|
8
|
+
|
|
7
9
|
const { isGTE, isNumberArray } = require('./commonChecks')
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -62,7 +64,7 @@ const ellipse = (options) => {
|
|
|
62
64
|
segments = (rotation < Math.PI * 2) ? segments + 1 : segments
|
|
63
65
|
for (let i = 0; i < segments; i++) {
|
|
64
66
|
const angle = (step * i) + startAngle
|
|
65
|
-
const point = vec2.fromValues(radius[0] *
|
|
67
|
+
const point = vec2.fromValues(radius[0] * cos(angle), radius[1] * sin(angle))
|
|
66
68
|
vec2.add(point, centerv, point)
|
|
67
69
|
points.push(point)
|
|
68
70
|
}
|
|
@@ -10,6 +10,7 @@ test('ellipse (defaults)', (t) => {
|
|
|
10
10
|
const geometry = ellipse()
|
|
11
11
|
const obs = geom2.toPoints(geometry)
|
|
12
12
|
|
|
13
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
13
14
|
t.deepEqual(obs.length, 32)
|
|
14
15
|
})
|
|
15
16
|
|
|
@@ -52,6 +53,7 @@ test('ellipse (options)', (t) => {
|
|
|
52
53
|
[3.9807852804032304, 4.804909677983871]
|
|
53
54
|
]
|
|
54
55
|
|
|
56
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
55
57
|
t.deepEqual(obs.length, 32)
|
|
56
58
|
t.true(comparePoints(obs, exp))
|
|
57
59
|
|
|
@@ -63,20 +65,21 @@ test('ellipse (options)', (t) => {
|
|
|
63
65
|
[2.77163859753386, 1.913417161825449],
|
|
64
66
|
[2.121320343559643, 3.5355339059327373],
|
|
65
67
|
[1.1480502970952695, 4.619397662556434],
|
|
66
|
-
[
|
|
68
|
+
[0, 5],
|
|
67
69
|
[-1.1480502970952693, 4.619397662556434],
|
|
68
70
|
[-2.1213203435596424, 3.5355339059327378],
|
|
69
71
|
[-2.77163859753386, 1.9134171618254494],
|
|
70
|
-
[-3,
|
|
72
|
+
[-3, 0],
|
|
71
73
|
[-2.7716385975338604, -1.9134171618254483],
|
|
72
74
|
[-2.121320343559643, -3.5355339059327373],
|
|
73
75
|
[-1.148050297095271, -4.619397662556432],
|
|
74
|
-
[
|
|
76
|
+
[0, -5],
|
|
75
77
|
[1.14805029709527, -4.619397662556433],
|
|
76
78
|
[2.121320343559642, -3.5355339059327386],
|
|
77
79
|
[2.7716385975338595, -1.913417161825452]
|
|
78
80
|
]
|
|
79
81
|
|
|
82
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
80
83
|
t.deepEqual(obs.length, 16)
|
|
81
84
|
t.true(comparePoints(obs, exp))
|
|
82
85
|
|
|
@@ -84,22 +87,23 @@ test('ellipse (options)', (t) => {
|
|
|
84
87
|
geometry = ellipse({ radius: [3, 5], startAngle: Math.PI / 2, segments: 16 })
|
|
85
88
|
obs = geom2.toPoints(geometry)
|
|
86
89
|
exp = [
|
|
87
|
-
[
|
|
90
|
+
[0, 5],
|
|
88
91
|
[-1.1480502970952693, 4.619397662556434],
|
|
89
92
|
[-2.1213203435596424, 3.5355339059327378],
|
|
90
93
|
[-2.77163859753386, 1.9134171618254494],
|
|
91
|
-
[-3,
|
|
94
|
+
[-3, 0],
|
|
92
95
|
[-2.7716385975338604, -1.9134171618254483],
|
|
93
96
|
[-2.121320343559643, -3.5355339059327373],
|
|
94
97
|
[-1.148050297095271, -4.619397662556432],
|
|
95
|
-
[
|
|
98
|
+
[0, -5],
|
|
96
99
|
[1.14805029709527, -4.619397662556433],
|
|
97
100
|
[2.121320343559642, -3.5355339059327386],
|
|
98
101
|
[2.7716385975338595, -1.913417161825452],
|
|
99
|
-
[3,
|
|
102
|
+
[3, 0],
|
|
100
103
|
[0, 0]
|
|
101
104
|
]
|
|
102
105
|
|
|
106
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
103
107
|
t.deepEqual(obs.length, 14)
|
|
104
108
|
t.true(comparePoints(obs, exp))
|
|
105
109
|
|
|
@@ -111,15 +115,17 @@ test('ellipse (options)', (t) => {
|
|
|
111
115
|
[2.77163859753386, 1.913417161825449],
|
|
112
116
|
[2.121320343559643, 3.5355339059327373],
|
|
113
117
|
[1.1480502970952695, 4.619397662556434],
|
|
114
|
-
[
|
|
118
|
+
[0, 5],
|
|
115
119
|
[0, 0]
|
|
116
120
|
]
|
|
117
121
|
|
|
122
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
118
123
|
t.deepEqual(obs.length, 6)
|
|
119
124
|
t.true(comparePoints(obs, exp))
|
|
120
125
|
|
|
121
126
|
// test segments
|
|
122
127
|
geometry = ellipse({ segments: 72 })
|
|
123
128
|
obs = geom2.toPoints(geometry)
|
|
129
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
124
130
|
t.deepEqual(obs.length, 72)
|
|
125
131
|
})
|
|
@@ -3,6 +3,8 @@ 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')
|
|
7
|
+
|
|
6
8
|
const { isGTE, isNumberArray } = require('./commonChecks')
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -42,14 +44,14 @@ const ellipsoid = (options) => {
|
|
|
42
44
|
const p1 = vec3.create()
|
|
43
45
|
const p2 = vec3.create()
|
|
44
46
|
for (let slice1 = 0; slice1 <= segments; slice1++) {
|
|
45
|
-
const angle =
|
|
46
|
-
const cylinderpoint = vec3.add(vec3.create(), vec3.scale(p1, xvector,
|
|
47
|
+
const angle = 2 * Math.PI * slice1 / segments
|
|
48
|
+
const cylinderpoint = vec3.add(vec3.create(), vec3.scale(p1, xvector, cos(angle)), vec3.scale(p2, yvector, sin(angle)))
|
|
47
49
|
if (slice1 > 0) {
|
|
48
50
|
let prevcospitch, prevsinpitch
|
|
49
51
|
for (let slice2 = 0; slice2 <= qsegments; slice2++) {
|
|
50
52
|
const pitch = 0.5 * Math.PI * slice2 / qsegments
|
|
51
|
-
const cospitch =
|
|
52
|
-
const sinpitch =
|
|
53
|
+
const cospitch = cos(pitch)
|
|
54
|
+
const sinpitch = sin(pitch)
|
|
53
55
|
if (slice2 > 0) {
|
|
54
56
|
let points = []
|
|
55
57
|
let point
|
|
@@ -64,7 +66,7 @@ const ellipsoid = (options) => {
|
|
|
64
66
|
point = vec3.subtract(vec3.create(), vec3.scale(p1, prevcylinderpoint, cospitch), vec3.scale(p2, zvector, sinpitch))
|
|
65
67
|
points.push(vec3.add(point, point, center))
|
|
66
68
|
|
|
67
|
-
polygons.push(poly3.
|
|
69
|
+
polygons.push(poly3.create(points))
|
|
68
70
|
|
|
69
71
|
points = []
|
|
70
72
|
point = vec3.add(vec3.create(), vec3.scale(p1, prevcylinderpoint, prevcospitch), vec3.scale(p2, zvector, prevsinpitch))
|
|
@@ -79,7 +81,7 @@ const ellipsoid = (options) => {
|
|
|
79
81
|
points.push(vec3.add(vec3.create(), center, point))
|
|
80
82
|
points.reverse()
|
|
81
83
|
|
|
82
|
-
polygons.push(poly3.
|
|
84
|
+
polygons.push(poly3.create(points))
|
|
83
85
|
}
|
|
84
86
|
prevcospitch = cospitch
|
|
85
87
|
prevsinpitch = sinpitch
|