@jscad/modeling 2.11.1 → 2.12.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.
- package/CHANGELOG.md +34 -0
- package/dist/jscad-modeling.min.js +338 -335
- package/package.json +2 -2
- package/src/curves/bezier/arcLengthToT.js +6 -6
- package/src/curves/bezier/arcLengthToT.test.js +25 -25
- package/src/curves/bezier/length.js +3 -5
- package/src/curves/bezier/length.test.js +2 -2
- package/src/curves/bezier/lengths.js +10 -10
- package/src/curves/bezier/lengths.test.js +3 -3
- package/src/geometries/geom2/transform.js +9 -1
- package/src/geometries/geom2/transform.test.js +58 -1
- package/src/geometries/poly2/arePointsInside.js +0 -7
- package/src/geometries/poly3/measureBoundingSphere.js +1 -2
- package/src/maths/plane/fromNoisyPoints.d.ts +6 -0
- package/src/maths/plane/fromNoisyPoints.js +106 -0
- package/src/maths/plane/fromNoisyPoints.test.js +24 -0
- package/src/maths/plane/index.d.ts +1 -0
- package/src/maths/plane/index.js +1 -0
- package/src/operations/booleans/trees/PolygonTreeNode.js +1 -1
- package/src/operations/expansions/expand.test.js +1 -1
- package/src/operations/extrusions/extrudeHelical.js +6 -7
- package/src/operations/extrusions/extrudeHelical.test.js +35 -37
- package/src/operations/extrusions/extrudeRotate.js +1 -1
- package/src/operations/extrusions/index.d.ts +1 -0
- package/src/operations/hulls/hullPoints2.js +3 -2
- package/src/operations/modifiers/index.js +1 -1
- package/src/operations/modifiers/retessellate.js +66 -27
- package/src/operations/transforms/mirror.test.js +9 -3
- package/src/primitives/circle.js +2 -2
- package/src/primitives/circle.test.js +7 -0
- package/src/primitives/cube.js +2 -2
- package/src/primitives/cube.test.js +7 -0
- package/src/primitives/cuboid.js +4 -1
- package/src/primitives/cuboid.test.js +7 -0
- package/src/primitives/cylinder.js +7 -2
- package/src/primitives/cylinder.test.js +14 -0
- package/src/primitives/ellipse.js +4 -1
- package/src/primitives/ellipse.test.js +7 -0
- package/src/primitives/ellipsoid.js +4 -1
- package/src/primitives/ellipsoid.test.js +7 -0
- package/src/primitives/geodesicSphere.js +5 -2
- package/src/primitives/geodesicSphere.test.js +7 -0
- package/src/primitives/polygon.d.ts +1 -0
- package/src/primitives/polygon.js +15 -4
- package/src/primitives/polygon.test.js +10 -0
- package/src/primitives/rectangle.js +4 -1
- package/src/primitives/rectangle.test.js +7 -0
- package/src/primitives/roundedCuboid.js +10 -3
- package/src/primitives/roundedCuboid.test.js +14 -0
- package/src/primitives/roundedCylinder.js +12 -5
- package/src/primitives/roundedCylinder.test.js +21 -0
- package/src/primitives/roundedRectangle.js +10 -3
- package/src/primitives/roundedRectangle.test.js +14 -0
- package/src/primitives/sphere.js +2 -2
- package/src/primitives/sphere.test.js +7 -0
- package/src/primitives/square.js +2 -2
- package/src/primitives/square.test.js +7 -0
|
@@ -8,7 +8,8 @@ const poly3 = require('../geometries/poly3')
|
|
|
8
8
|
|
|
9
9
|
const { sin, cos } = require('../maths/utils/trigonometry')
|
|
10
10
|
|
|
11
|
-
const {
|
|
11
|
+
const { isGTE, isNumberArray } = require('./commonChecks')
|
|
12
|
+
const cuboid = require('./cuboid')
|
|
12
13
|
|
|
13
14
|
const createCorners = (center, size, radius, segments, slice, positive) => {
|
|
14
15
|
const pitch = (TAU / 4) * slice / segments
|
|
@@ -135,10 +136,16 @@ const roundedCuboid = (options) => {
|
|
|
135
136
|
|
|
136
137
|
if (!isNumberArray(center, 3)) throw new Error('center must be an array of X, Y and Z values')
|
|
137
138
|
if (!isNumberArray(size, 3)) throw new Error('size must be an array of X, Y and Z values')
|
|
138
|
-
if (!size.every((n) => n
|
|
139
|
-
if (!
|
|
139
|
+
if (!size.every((n) => n >= 0)) throw new Error('size values must be positive')
|
|
140
|
+
if (!isGTE(roundRadius, 0)) throw new Error('roundRadius must be positive')
|
|
140
141
|
if (!isGTE(segments, 4)) throw new Error('segments must be four or more')
|
|
141
142
|
|
|
143
|
+
// if any size is zero return empty geometry
|
|
144
|
+
if (size[0] === 0 || size[1] === 0 || size[2] === 0) return geom3.create()
|
|
145
|
+
|
|
146
|
+
// if roundRadius is zero, return cuboid
|
|
147
|
+
if (roundRadius === 0) return cuboid({ center, size })
|
|
148
|
+
|
|
142
149
|
size = size.map((v) => v / 2) // convert to radius
|
|
143
150
|
|
|
144
151
|
if (roundRadius > (size[0] - EPS) ||
|
|
@@ -14,6 +14,20 @@ test('roundedCuboid (defaults)', (t) => {
|
|
|
14
14
|
t.deepEqual(pts.length, 614)
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
+
test('roundedCuboid (zero size)', (t) => {
|
|
18
|
+
const obs = roundedCuboid({ size: [1, 1, 0] })
|
|
19
|
+
const pts = geom3.toPoints(obs)
|
|
20
|
+
t.notThrows(() => geom3.validate(obs))
|
|
21
|
+
t.is(pts.length, 0)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('roundedCuboid (zero radius)', (t) => {
|
|
25
|
+
const obs = roundedCuboid({ roundRadius: 0 })
|
|
26
|
+
const pts = geom3.toPoints(obs)
|
|
27
|
+
t.notThrows(() => geom3.validate(obs))
|
|
28
|
+
t.deepEqual(pts.length, 6)
|
|
29
|
+
})
|
|
30
|
+
|
|
17
31
|
test('roundedCuboid (options)', (t) => {
|
|
18
32
|
// test segments
|
|
19
33
|
let obs = roundedCuboid({ segments: 8 })
|
|
@@ -7,7 +7,8 @@ const poly3 = require('../geometries/poly3')
|
|
|
7
7
|
|
|
8
8
|
const { sin, cos } = require('../maths/utils/trigonometry')
|
|
9
9
|
|
|
10
|
-
const {
|
|
10
|
+
const { isGTE, isNumberArray } = require('./commonChecks')
|
|
11
|
+
const cylinder = require('./cylinder')
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Construct a Z axis-aligned solid cylinder in three dimensional space with rounded ends.
|
|
@@ -34,12 +35,18 @@ const roundedCylinder = (options) => {
|
|
|
34
35
|
const { center, height, radius, roundRadius, segments } = Object.assign({}, defaults, options)
|
|
35
36
|
|
|
36
37
|
if (!isNumberArray(center, 3)) throw new Error('center must be an array of X, Y and Z values')
|
|
37
|
-
if (!
|
|
38
|
-
if (!
|
|
39
|
-
if (!
|
|
40
|
-
if (roundRadius >
|
|
38
|
+
if (!isGTE(height, 0)) throw new Error('height must be positive')
|
|
39
|
+
if (!isGTE(radius, 0)) throw new Error('radius must be positive')
|
|
40
|
+
if (!isGTE(roundRadius, 0)) throw new Error('roundRadius must be positive')
|
|
41
|
+
if (roundRadius > radius) throw new Error('roundRadius must be smaller then the radius')
|
|
41
42
|
if (!isGTE(segments, 4)) throw new Error('segments must be four or more')
|
|
42
43
|
|
|
44
|
+
// if size is zero return empty geometry
|
|
45
|
+
if (height === 0 || radius === 0) return geom3.create()
|
|
46
|
+
|
|
47
|
+
// if roundRadius is zero, return cylinder
|
|
48
|
+
if (roundRadius === 0) return cylinder({ center, height, radius })
|
|
49
|
+
|
|
43
50
|
const start = [0, 0, -(height / 2)]
|
|
44
51
|
const end = [0, 0, height / 2]
|
|
45
52
|
const direction = vec3.subtract(vec3.create(), end, start)
|
|
@@ -14,6 +14,27 @@ test('roundedCylinder (defaults)', (t) => {
|
|
|
14
14
|
t.is(pts.length, 544)
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
+
test('roundedCylinder (zero height)', (t) => {
|
|
18
|
+
const obs = roundedCylinder({ height: 0 })
|
|
19
|
+
const pts = geom3.toPoints(obs)
|
|
20
|
+
t.notThrows(() => geom3.validate(obs))
|
|
21
|
+
t.is(pts.length, 0)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('roundedCylinder (zero radius)', (t) => {
|
|
25
|
+
const obs = roundedCylinder({ radius: 0, roundRadius: 0 })
|
|
26
|
+
const pts = geom3.toPoints(obs)
|
|
27
|
+
t.notThrows(() => geom3.validate(obs))
|
|
28
|
+
t.is(pts.length, 0)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('roundedCylinder (zero roundRadius)', (t) => {
|
|
32
|
+
const obs = roundedCylinder({ roundRadius: 0 })
|
|
33
|
+
const pts = geom3.toPoints(obs)
|
|
34
|
+
t.notThrows(() => geom3.validate(obs))
|
|
35
|
+
t.is(pts.length, 96)
|
|
36
|
+
})
|
|
37
|
+
|
|
17
38
|
test('roundedCylinder (options)', (t) => {
|
|
18
39
|
// test segments
|
|
19
40
|
let obs = roundedCylinder({ segments: 5 })
|
|
@@ -4,7 +4,8 @@ const vec2 = require('../maths/vec2')
|
|
|
4
4
|
|
|
5
5
|
const geom2 = require('../geometries/geom2')
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { isGTE, isNumberArray } = require('./commonChecks')
|
|
8
|
+
const rectangle = require('./rectangle')
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Construct an axis-aligned rectangle in two dimensional space with rounded corners.
|
|
@@ -30,10 +31,16 @@ const roundedRectangle = (options) => {
|
|
|
30
31
|
|
|
31
32
|
if (!isNumberArray(center, 2)) throw new Error('center must be an array of X and Y values')
|
|
32
33
|
if (!isNumberArray(size, 2)) throw new Error('size must be an array of X and Y values')
|
|
33
|
-
if (!size.every((n) => n
|
|
34
|
-
if (!
|
|
34
|
+
if (!size.every((n) => n >= 0)) throw new Error('size values must be positive')
|
|
35
|
+
if (!isGTE(roundRadius, 0)) throw new Error('roundRadius must be positive')
|
|
35
36
|
if (!isGTE(segments, 4)) throw new Error('segments must be four or more')
|
|
36
37
|
|
|
38
|
+
// if any size is zero return empty geometry
|
|
39
|
+
if (size[0] === 0 || size[1] === 0) return geom2.create()
|
|
40
|
+
|
|
41
|
+
// if roundRadius is zero, return rectangle
|
|
42
|
+
if (roundRadius === 0) return rectangle({ center, size })
|
|
43
|
+
|
|
37
44
|
size = size.map((v) => v / 2) // convert to radius
|
|
38
45
|
|
|
39
46
|
if (roundRadius > (size[0] - EPS) ||
|
|
@@ -14,6 +14,20 @@ test('roundedRectangle (defaults)', (t) => {
|
|
|
14
14
|
t.deepEqual(obs.length, 36)
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
+
test('roundedRectangle (zero size)', (t) => {
|
|
18
|
+
const obs = roundedRectangle({ size: [1, 0] })
|
|
19
|
+
const pts = geom2.toPoints(obs)
|
|
20
|
+
t.notThrows(() => geom2.validate(obs))
|
|
21
|
+
t.is(pts.length, 0)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('roundedRectangle (zero radius)', (t) => {
|
|
25
|
+
const obs = roundedRectangle({ roundRadius: 0 })
|
|
26
|
+
const pts = geom2.toPoints(obs)
|
|
27
|
+
t.notThrows(() => geom2.validate(obs))
|
|
28
|
+
t.deepEqual(pts.length, 4)
|
|
29
|
+
})
|
|
30
|
+
|
|
17
31
|
test('roundedRectangle (options)', (t) => {
|
|
18
32
|
// test center
|
|
19
33
|
let geometry = roundedRectangle({ center: [4, 5], segments: 16 })
|
package/src/primitives/sphere.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const ellipsoid = require('./ellipsoid')
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { isGTE } = require('./commonChecks')
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Construct a sphere in three dimensional space where all points are at the same distance from the center.
|
|
@@ -25,7 +25,7 @@ const sphere = (options) => {
|
|
|
25
25
|
}
|
|
26
26
|
let { center, radius, segments, axes } = Object.assign({}, defaults, options)
|
|
27
27
|
|
|
28
|
-
if (!
|
|
28
|
+
if (!isGTE(radius, 0)) throw new Error('radius must be positive')
|
|
29
29
|
|
|
30
30
|
radius = [radius, radius, radius]
|
|
31
31
|
|
|
@@ -163,3 +163,10 @@ test('sphere (options)', (t) => {
|
|
|
163
163
|
t.is(pts.length, 32)
|
|
164
164
|
t.true(comparePolygonsAsPoints(pts, exp))
|
|
165
165
|
})
|
|
166
|
+
|
|
167
|
+
test('sphere (zero radius)', (t) => {
|
|
168
|
+
const obs = sphere({ radius: 0 })
|
|
169
|
+
const pts = geom3.toPoints(obs)
|
|
170
|
+
t.notThrows(() => geom3.validate(obs))
|
|
171
|
+
t.is(pts.length, 0)
|
|
172
|
+
})
|
package/src/primitives/square.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const rectangle = require('./rectangle')
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { isGTE } = require('./commonChecks')
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Construct an axis-aligned square in two dimensional space with four equal sides at right angles.
|
|
@@ -21,7 +21,7 @@ const square = (options) => {
|
|
|
21
21
|
}
|
|
22
22
|
let { center, size } = Object.assign({}, defaults, options)
|
|
23
23
|
|
|
24
|
-
if (!
|
|
24
|
+
if (!isGTE(size, 0)) throw new Error('size must be positive')
|
|
25
25
|
|
|
26
26
|
size = [size, size]
|
|
27
27
|
|
|
@@ -42,3 +42,10 @@ test('square (options)', (t) => {
|
|
|
42
42
|
t.is(pts.length, 4)
|
|
43
43
|
t.true(comparePoints(pts, exp))
|
|
44
44
|
})
|
|
45
|
+
|
|
46
|
+
test('square (zero size)', (t) => {
|
|
47
|
+
const geometry = square({ size: 0 })
|
|
48
|
+
const obs = geom2.toPoints(geometry)
|
|
49
|
+
t.notThrows(() => geom2.validate(geometry))
|
|
50
|
+
t.is(obs.length, 0)
|
|
51
|
+
})
|