Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 : primitives revisted #697

Merged
merged 4 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions packages/modeling/src/primitives/arc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const vec2 = require('../maths/vec2')

const path2 = require('../geometries/path2')

const { isGT, isGTE, isArray } = require('./commonChecks')

/**
* Construct an arc in two dimensional space.
* @param {Object} [options] - options for construction
Expand All @@ -27,13 +29,11 @@ const arc = (options) => {
}
let { center, radius, startAngle, endAngle, makeTangent, segments } = Object.assign({}, defaults, options)

if (!Array.isArray(center)) throw new Error('center must be an array')
if (center.length < 2) throw new Error('center must contain X and Y values')

if (!Number.isFinite(radius)) throw new Error('radius must be a number')

if (startAngle < 0 || endAngle < 0) throw new Error('the start and end angles must be positive')
if (segments < 4) throw new Error('segments must be four or more')
if (!isArray(2, center)) throw new Error('center must be an array of X and Y values')
z3dev marked this conversation as resolved.
Show resolved Hide resolved
if (!isGT(radius, 0)) throw new Error('radius must be greater than zero')
if (!isGTE(startAngle, 0)) throw new Error('startAngle must be positive')
if (!isGTE(endAngle, 0)) throw new Error('endAngle must be positive')
if (!isGTE(segments, 4)) throw new Error('segments must be four or more')

startAngle = startAngle % (Math.PI * 2)
endAngle = endAngle % (Math.PI * 2)
Expand Down
6 changes: 4 additions & 2 deletions packages/modeling/src/primitives/circle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const ellipse = require('./ellipse')

const { isGT } = require('./commonChecks')

/**
* Construct a circle in two dimensional space where are points are at the same distance from the center.
* Construct a circle in two dimensional space where all points are at the same distance from the center.
* @see [ellipse]{@link module:modeling/primitives.ellipse} for more options
* @param {Object} [options] - options for construction
* @param {Array} [options.center=[0,0]] - center of circle
Expand All @@ -20,7 +22,7 @@ const circle = (options) => {
}
let { center, radius, segments } = Object.assign({}, defaults, options)

if (!Number.isFinite(radius)) throw new Error('radius must be a number')
if (!isGT(radius, 0)) throw new Error('radius must be greater than zero')

radius = [radius, radius]

Expand Down
66 changes: 33 additions & 33 deletions packages/modeling/src/primitives/circle.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,41 @@ test('circle (defaults)', (t) => {

test('circle (options)', (t) => {
// test center
let geometry = circle({radius: 3.5, center: [6.5, 6.5]})
let geometry = circle({ radius: 3.5, center: [6.5, 6.5] })
let pts = geom2.toPoints(geometry)
let exp = [
[ 10, 6.5 ],
[ 9.932748481411306, 7.182816127056449 ],
[ 9.733578363789503, 7.8393920132778145 ],
[ 9.410143643058909, 8.444495815568608 ],
[ 8.974873734152917, 8.974873734152915 ],
[ 8.444495815568608, 9.410143643058909 ],
[ 7.8393920132778145, 9.733578363789503 ],
[ 7.182816127056449, 9.932748481411306 ],
[ 6.5, 10 ],
[ 5.817183872943551, 9.932748481411306 ],
[ 5.1606079867221855, 9.733578363789503 ],
[ 4.555504184431394, 9.410143643058909 ],
[ 4.025126265847084, 8.974873734152917 ],
[ 3.589856356941091, 8.444495815568608 ],
[ 3.2664216362104965, 7.8393920132778145 ],
[ 3.0672515185886935, 7.18281612705645 ],
[ 3, 6.5 ],
[ 3.0672515185886935, 5.81718387294355 ],
[ 3.266421636210496, 5.160607986722186 ],
[ 3.589856356941091, 4.555504184431394 ],
[ 4.025126265847083, 4.025126265847084 ],
[ 4.555504184431392, 3.5898563569410915 ],
[ 5.160607986722184, 3.266421636210497 ],
[ 5.817183872943549, 3.067251518588694 ],
[ 6.499999999999999, 3 ],
[ 7.182816127056449, 3.0672515185886935 ],
[ 7.8393920132778145, 3.266421636210497 ],
[ 8.444495815568606, 3.589856356941091 ],
[ 8.974873734152915, 4.025126265847083 ],
[ 9.410143643058909, 4.555504184431392 ],
[ 9.733578363789503, 5.160607986722184 ],
[ 9.932748481411306, 5.817183872943549 ]
[10, 6.5],
[9.932748481411306, 7.182816127056449],
[9.733578363789503, 7.8393920132778145],
[9.410143643058909, 8.444495815568608],
[8.974873734152917, 8.974873734152915],
[8.444495815568608, 9.410143643058909],
[7.8393920132778145, 9.733578363789503],
[7.182816127056449, 9.932748481411306],
[6.5, 10],
[5.817183872943551, 9.932748481411306],
[5.1606079867221855, 9.733578363789503],
[4.555504184431394, 9.410143643058909],
[4.025126265847084, 8.974873734152917],
[3.589856356941091, 8.444495815568608],
[3.2664216362104965, 7.8393920132778145],
[3.0672515185886935, 7.18281612705645],
[3, 6.5],
[3.0672515185886935, 5.81718387294355],
[3.266421636210496, 5.160607986722186],
[3.589856356941091, 4.555504184431394],
[4.025126265847083, 4.025126265847084],
[4.555504184431392, 3.5898563569410915],
[5.160607986722184, 3.266421636210497],
[5.817183872943549, 3.067251518588694],
[6.499999999999999, 3],
[7.182816127056449, 3.0672515185886935],
[7.8393920132778145, 3.266421636210497],
[8.444495815568606, 3.589856356941091],
[8.974873734152915, 4.025126265847083],
[9.410143643058909, 4.555504184431392],
[9.733578363789503, 5.160607986722184],
[9.932748481411306, 5.817183872943549]
]

t.deepEqual(pts.length, 32)
Expand Down
19 changes: 19 additions & 0 deletions packages/modeling/src/primitives/commonChecks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// verify that the array has the given dimension, and contains Number values
const isArray = (dimension, array) => {
z3dev marked this conversation as resolved.
Show resolved Hide resolved
if (Array.isArray(array) && array.length >= dimension) {
return array.every((n) => Number.isFinite(n))
}
return false
}

// verify that the value is a Number greater than the constant
const isGT = (value, constant) => (Number.isFinite(value) && value > constant)
SimonClark marked this conversation as resolved.
Show resolved Hide resolved

// verify that the value is a Number greater than or equal to the constant
const isGTE = (value, constant) => (Number.isFinite(value) && value >= constant)

module.exports = {
isArray,
isGT,
isGTE
}
4 changes: 3 additions & 1 deletion packages/modeling/src/primitives/cube.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const cuboid = require('./cuboid')

const { isGT } = require('./commonChecks')

/**
* Construct an axis-aligned solid cube in three dimensional space with six square faces.
* @see [cuboid]{@link module:modeling/primitives.cuboid} for more options
Expand All @@ -18,7 +20,7 @@ const cube = (options) => {
}
let { center, size } = Object.assign({}, defaults, options)

if (!Number.isFinite(size)) throw new Error('size must be a number')
if (!isGT(size, 0)) throw new Error('size must be greater than zero')

size = [size, size, size]

Expand Down
14 changes: 7 additions & 7 deletions packages/modeling/src/primitives/cube.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ test('cube (defaults)', (t) => {

test('cube (options)', (t) => {
// test center
let obs = cube({size: 7, center: [6.5, 6.5, 6.5]})
let obs = cube({ size: 7, center: [6.5, 6.5, 6.5] })
let pts = geom3.toPoints(obs)
let exp = [
[ [ 3, 3, 3 ], [ 3, 3, 10 ], [ 3, 10, 10 ], [ 3, 10, 3 ] ],
[ [ 10, 3, 3 ], [ 10, 10, 3 ], [ 10, 10, 10 ], [ 10, 3, 10 ] ],
[ [ 3, 3, 3 ], [ 10, 3, 3 ], [ 10, 3, 10 ], [ 3, 3, 10 ] ],
[ [ 3, 10, 3 ], [ 3, 10, 10 ], [ 10, 10, 10 ], [ 10, 10, 3 ] ],
[ [ 3, 3, 3 ], [ 3, 10, 3 ], [ 10, 10, 3 ], [ 10, 3, 3 ] ],
[ [ 3, 3, 10 ], [ 10, 3, 10 ], [ 10, 10, 10 ], [ 3, 10, 10 ] ]
[[3, 3, 3], [3, 3, 10], [3, 10, 10], [3, 10, 3]],
[[10, 3, 3], [10, 10, 3], [10, 10, 10], [10, 3, 10]],
[[3, 3, 3], [10, 3, 3], [10, 3, 10], [3, 3, 10]],
[[3, 10, 3], [3, 10, 10], [10, 10, 10], [10, 10, 3]],
[[3, 3, 3], [3, 10, 3], [10, 10, 3], [10, 3, 3]],
[[3, 3, 10], [10, 3, 10], [10, 10, 10], [3, 10, 10]]
]

t.is(pts.length, 6)
Expand Down
10 changes: 5 additions & 5 deletions packages/modeling/src/primitives/cuboid.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const geom3 = require('../geometries/geom3')
const poly3 = require('../geometries/poly3')

const { isArray } = require('./commonChecks')

/**
* Construct an axis-aligned solid cuboid in three dimensional space.
* @param {Object} [options] - options for construction
Expand All @@ -19,11 +21,9 @@ const cuboid = (options) => {
}
const { center, size } = Object.assign({}, defaults, options)

if (!Array.isArray(center)) throw new Error('center must be an array')
if (center.length < 3) throw new Error('center must contain X, Y and Z values')

if (!Array.isArray(size)) throw new Error('size must be an array')
if (size.length < 3) throw new Error('size must contain width, depth and height values')
if (!isArray(3, center)) throw new Error('center must be an array of X, Y and Z values')
if (!isArray(3, size)) throw new Error('size must be an array of width, depth and height values')
if (!size.every((n) => n > 0)) throw new Error('size values must be greater than zero')

const result = geom3.create(
// adjust a basic shape to size
Expand Down
14 changes: 7 additions & 7 deletions packages/modeling/src/primitives/cuboid.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ test('cuboid (defaults)', (t) => {

test('cuboid (options)', (t) => {
// test center
let obs = cuboid({size: [6, 6, 6], center: [3, 5, 7]})
let obs = cuboid({ size: [6, 6, 6], center: [3, 5, 7] })
let pts = geom3.toPoints(obs)
let exp = [
[ [ 0, 2, 4 ], [ 0, 2, 10 ], [ 0, 8, 10 ], [ 0, 8, 4 ] ],
[ [ 6, 2, 4 ], [ 6, 8, 4 ], [ 6, 8, 10 ], [ 6, 2, 10 ] ],
[ [ 0, 2, 4 ], [ 6, 2, 4 ], [ 6, 2, 10 ], [ 0, 2, 10 ] ],
[ [ 0, 8, 4 ], [ 0, 8, 10 ], [ 6, 8, 10 ], [ 6, 8, 4 ] ],
[ [ 0, 2, 4 ], [ 0, 8, 4 ], [ 6, 8, 4 ], [ 6, 2, 4 ] ],
[ [ 0, 2, 10 ], [ 6, 2, 10 ], [ 6, 8, 10 ], [ 0, 8, 10 ] ]
[[0, 2, 4], [0, 2, 10], [0, 8, 10], [0, 8, 4]],
[[6, 2, 4], [6, 8, 4], [6, 8, 10], [6, 2, 10]],
[[0, 2, 4], [6, 2, 4], [6, 2, 10], [0, 2, 10]],
[[0, 8, 4], [0, 8, 10], [6, 8, 10], [6, 8, 4]],
[[0, 2, 4], [0, 8, 4], [6, 8, 4], [6, 2, 4]],
[[0, 2, 10], [6, 2, 10], [6, 8, 10], [0, 8, 10]]
]

t.is(pts.length, 6)
Expand Down
4 changes: 3 additions & 1 deletion packages/modeling/src/primitives/cylinder.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const cylinderElliptic = require('./cylinderElliptic')

const { isGT } = require('./commonChecks')

/**
* Construct a solid cylinder in three dimensional space.
* @see [cylinderElliptic]{@link module:modeling/primitives.cylinderElliptic} for more options
Expand All @@ -26,7 +28,7 @@ const cylinder = (options) => {
}
const { center, height, radius, segments } = Object.assign({}, defaults, options)

if (!Number.isFinite(radius)) throw new Error('radius must be a number')
if (!isGT(radius, 0)) throw new Error('radius must be greater than zero')

const newoptions = {
center,
Expand Down
72 changes: 21 additions & 51 deletions packages/modeling/src/primitives/cylinder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,59 +43,29 @@ test('cylinder (options)', (t) => {
t.true(comparePolygonsAsPoints(pts, exp))

// test center
obs = cylinder({center: [-5, -5, -5], segments: 5})
obs = cylinder({ center: [-5, -5, -5], segments: 5 })
pts = geom3.toPoints(obs)
exp = [
[ [ -5, -5, -6 ],
[ -4.6909830056250525, -4.048943483704846, -6 ],
[ -4, -5, -6 ] ],
[ [ -4.6909830056250525, -4.048943483704846, -6 ],
[ -4.6909830056250525, -4.048943483704846, -4 ],
[ -4, -5, -4 ],
[ -4, -5, -6 ] ],
[ [ -5, -5, -4 ],
[ -4, -5, -4 ],
[ -4.6909830056250525, -4.048943483704846, -4 ] ],
[ [ -5, -5, -6 ],
[ -5.8090169943749475, -4.412214747707527, -6 ],
[ -4.6909830056250525, -4.048943483704846, -6 ] ],
[ [ -5.8090169943749475, -4.412214747707527, -6 ],
[ -5.8090169943749475, -4.412214747707527, -4 ],
[ -4.6909830056250525, -4.048943483704846, -4 ],
[ -4.6909830056250525, -4.048943483704846, -6 ] ],
[ [ -5, -5, -4 ],
[ -4.6909830056250525, -4.048943483704846, -4 ],
[ -5.8090169943749475, -4.412214747707527, -4 ] ],
[ [ -5, -5, -6 ],
[ -5.8090169943749475, -5.587785252292473, -6 ],
[ -5.8090169943749475, -4.412214747707527, -6 ] ],
[ [ -5.8090169943749475, -5.587785252292473, -6 ],
[ -5.8090169943749475, -5.587785252292473, -4 ],
[ -5.8090169943749475, -4.412214747707527, -4 ],
[ -5.8090169943749475, -4.412214747707527, -6 ] ],
[ [ -5, -5, -4 ],
[ -5.8090169943749475, -4.412214747707527, -4 ],
[ -5.8090169943749475, -5.587785252292473, -4 ] ],
[ [ -5, -5, -6 ],
[ -4.6909830056250525, -5.951056516295154, -6 ],
[ -5.8090169943749475, -5.587785252292473, -6 ] ],
[ [ -4.6909830056250525, -5.951056516295154, -6 ],
[ -4.6909830056250525, -5.951056516295154, -4 ],
[ -5.8090169943749475, -5.587785252292473, -4 ],
[ -5.8090169943749475, -5.587785252292473, -6 ] ],
[ [ -5, -5, -4 ],
[ -5.8090169943749475, -5.587785252292473, -4 ],
[ -4.6909830056250525, -5.951056516295154, -4 ] ],
[ [ -5, -5, -6 ],
[ -4, -5, -6 ],
[ -4.6909830056250525, -5.951056516295154, -6 ] ],
[ [ -4, -5, -6 ],
[ -4, -5, -4 ],
[ -4.6909830056250525, -5.951056516295154, -4 ],
[ -4.6909830056250525, -5.951056516295154, -6 ] ],
[ [ -5, -5, -4 ],
[ -4.6909830056250525, -5.951056516295154, -4 ],
[ -4, -5, -4 ] ]
[[-5, -5, -6], [-4.6909830056250525, -4.048943483704846, -6], [-4, -5, -6]],
[[-4.6909830056250525, -4.048943483704846, -6], [-4.6909830056250525, -4.048943483704846, -4],
[-4, -5, -4], [-4, -5, -6]],
[[-5, -5, -4], [-4, -5, -4], [-4.6909830056250525, -4.048943483704846, -4]],
[[-5, -5, -6], [-5.8090169943749475, -4.412214747707527, -6], [-4.6909830056250525, -4.048943483704846, -6]],
[[-5.8090169943749475, -4.412214747707527, -6], [-5.8090169943749475, -4.412214747707527, -4],
[-4.6909830056250525, -4.048943483704846, -4], [-4.6909830056250525, -4.048943483704846, -6]],
[[-5, -5, -4], [-4.6909830056250525, -4.048943483704846, -4], [-5.8090169943749475, -4.412214747707527, -4]],
[[-5, -5, -6], [-5.8090169943749475, -5.587785252292473, -6], [-5.8090169943749475, -4.412214747707527, -6]],
[[-5.8090169943749475, -5.587785252292473, -6], [-5.8090169943749475, -5.587785252292473, -4],
[-5.8090169943749475, -4.412214747707527, -4], [-5.8090169943749475, -4.412214747707527, -6]],
[[-5, -5, -4], [-5.8090169943749475, -4.412214747707527, -4], [-5.8090169943749475, -5.587785252292473, -4]],
[[-5, -5, -6], [-4.6909830056250525, -5.951056516295154, -6], [-5.8090169943749475, -5.587785252292473, -6]],
[[-4.6909830056250525, -5.951056516295154, -6], [-4.6909830056250525, -5.951056516295154, -4],
[-5.8090169943749475, -5.587785252292473, -4], [-5.8090169943749475, -5.587785252292473, -6]],
[[-5, -5, -4], [-5.8090169943749475, -5.587785252292473, -4], [-4.6909830056250525, -5.951056516295154, -4]],
[[-5, -5, -6], [-4, -5, -6], [-4.6909830056250525, -5.951056516295154, -6]],
[[-4, -5, -6], [-4, -5, -4],
[-4.6909830056250525, -5.951056516295154, -4], [-4.6909830056250525, -5.951056516295154, -6]],
[[-5, -5, -4], [-4.6909830056250525, -5.951056516295154, -4], [-4, -5, -4]]
]

t.is(pts.length, 15)
Expand Down
22 changes: 11 additions & 11 deletions packages/modeling/src/primitives/cylinderElliptic.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const vec3 = require('../maths/vec3')
const geom3 = require('../geometries/geom3')
const poly3 = require('../geometries/poly3')

const { isGT, isGTE, isArray } = require('./commonChecks')

/**
* Construct an elliptic cylinder in three dimensional space.
* @param {Object} [options] - options for construction
Expand Down Expand Up @@ -37,17 +39,15 @@ const cylinderElliptic = (options) => {
}
let { center, height, startRadius, startAngle, endRadius, endAngle, segments } = Object.assign({}, defaults, options)

if (!Array.isArray(center)) throw new Error('center must be an array')
if (center.length < 3) throw new Error('center must contain X, Y and Z values')

if (height < (EPS * 2)) throw new Error('height must be larger then zero')

if ((endRadius[0] <= 0) || (startRadius[0] <= 0) || (endRadius[1] <= 0) || (startRadius[1] <= 0)) {
throw new Error('endRadus and startRadius should be positive')
}
if (startAngle < 0 || endAngle < 0) throw new Error('startAngle and endAngle must be positive')

if (segments < 4) throw new Error('segments must be four or more')
if (!isArray(3, center)) throw new Error('center must be an array of X, Y and Z values')
if (!isGT(height, 0)) throw new Error('height must be greater then zero')
if (!isArray(2, startRadius)) throw new Error('startRadius must be an array of X and Y values')
if (!startRadius.every((n) => n > 0)) throw new Error('startRadius values must be greater than zero')
if (!isArray(2, endRadius)) throw new Error('endRadius must be an array of X and Y values')
if (!endRadius.every((n) => n > 0)) throw new Error('endRadius values must be greater than zero')
if (!isGTE(startAngle, 0)) throw new Error('startAngle must be positive')
if (!isGTE(endAngle, 0)) throw new Error('endAngle must be positive')
if (!isGTE(segments, 4)) throw new Error('segments must be four or more')

startAngle = startAngle % (Math.PI * 2)
endAngle = endAngle % (Math.PI * 2)
Expand Down
Loading