UNPKG

@jscad/modeling

Version:

Constructive Solid Geometry (CSG) Library for JSCAD

134 lines (119 loc) 9.16 kB
const test = require('ava') const { comparePolygonsAsPoints } = require('../../../test/helpers') const { geom3 } = require('../../geometries') const { sphere, cuboid } = require('../../primitives') const { union } = require('./index') const { center } = require('../transforms/center') test('union of one or more geom3 objects produces expected geometry', (t) => { const geometry1 = sphere({ radius: 2, segments: 8 }) // union of one object const result1 = union(geometry1) let obs = geom3.toPoints(result1) let exp = [ [[2, 0, 0], [1.4142135623730951, -1.414213562373095, 0], [1.0000000000000002, -1, -1.414213562373095], [1.4142135623730951, 0, -1.414213562373095]], [[1.4142135623730951, 0, 1.414213562373095], [1.0000000000000002, -1, 1.414213562373095], [1.4142135623730951, -1.414213562373095, 0], [2, 0, 0]], [[1.4142135623730951, 0, -1.414213562373095], [1.0000000000000002, -1, -1.414213562373095], [1.2246467991473532e-16, 0, -2]], [[1.2246467991473532e-16, 0, 2], [1.0000000000000002, -1, 1.414213562373095], [1.4142135623730951, 0, 1.414213562373095]], [[1.4142135623730951, -1.414213562373095, 0], [1.2246467991473532e-16, -2, 0], [8.659560562354934e-17, -1.4142135623730951, -1.414213562373095], [1.0000000000000002, -1, -1.414213562373095]], [[1.0000000000000002, -1, 1.414213562373095], [8.659560562354934e-17, -1.4142135623730951, 1.414213562373095], [1.2246467991473532e-16, -2, 0], [1.4142135623730951, -1.414213562373095, 0]], [[1.0000000000000002, -1, -1.414213562373095], [8.659560562354934e-17, -1.4142135623730951, -1.414213562373095], [8.659560562354934e-17, -8.659560562354932e-17, -2]], [[8.659560562354934e-17, -8.659560562354932e-17, 2], [8.659560562354934e-17, -1.4142135623730951, 1.414213562373095], [1.0000000000000002, -1, 1.414213562373095]], [[1.2246467991473532e-16, -2, 0], [-1.414213562373095, -1.4142135623730951, 0], [-1, -1.0000000000000002, -1.414213562373095], [8.659560562354934e-17, -1.4142135623730951, -1.414213562373095]], [[8.659560562354934e-17, -1.4142135623730951, 1.414213562373095], [-1, -1.0000000000000002, 1.414213562373095], [-1.414213562373095, -1.4142135623730951, 0], [1.2246467991473532e-16, -2, 0]], [[8.659560562354934e-17, -1.4142135623730951, -1.414213562373095], [-1, -1.0000000000000002, -1.414213562373095], [7.498798913309288e-33, -1.2246467991473532e-16, -2]], [[7.498798913309288e-33, -1.2246467991473532e-16, 2], [-1, -1.0000000000000002, 1.414213562373095], [8.659560562354934e-17, -1.4142135623730951, 1.414213562373095]], [[-1.414213562373095, -1.4142135623730951, 0], [-2, -2.4492935982947064e-16, 0], [-1.4142135623730951, -1.7319121124709868e-16, -1.414213562373095], [-1, -1.0000000000000002, -1.414213562373095]], [[-1, -1.0000000000000002, 1.414213562373095], [-1.4142135623730951, -1.7319121124709868e-16, 1.414213562373095], [-2, -2.4492935982947064e-16, 0], [-1.414213562373095, -1.4142135623730951, 0]], [[-1, -1.0000000000000002, -1.414213562373095], [-1.4142135623730951, -1.7319121124709868e-16, -1.414213562373095], [-8.659560562354932e-17, -8.659560562354934e-17, -2]], [[-8.659560562354932e-17, -8.659560562354934e-17, 2], [-1.4142135623730951, -1.7319121124709868e-16, 1.414213562373095], [-1, -1.0000000000000002, 1.414213562373095]], [[-2, -2.4492935982947064e-16, 0], [-1.4142135623730954, 1.414213562373095, 0], [-1.0000000000000002, 1, -1.414213562373095], [-1.4142135623730951, -1.7319121124709868e-16, -1.414213562373095]], [[-1.4142135623730951, -1.7319121124709868e-16, 1.414213562373095], [-1.0000000000000002, 1, 1.414213562373095], [-1.4142135623730954, 1.414213562373095, 0], [-2, -2.4492935982947064e-16, 0]], [[-1.4142135623730951, -1.7319121124709868e-16, -1.414213562373095], [-1.0000000000000002, 1, -1.414213562373095], [-1.2246467991473532e-16, -1.4997597826618576e-32, -2]], [[-1.2246467991473532e-16, -1.4997597826618576e-32, 2], [-1.0000000000000002, 1, 1.414213562373095], [-1.4142135623730951, -1.7319121124709868e-16, 1.414213562373095]], [[-1.4142135623730954, 1.414213562373095, 0], [-3.6739403974420594e-16, 2, 0], [-2.59786816870648e-16, 1.4142135623730951, -1.414213562373095], [-1.0000000000000002, 1, -1.414213562373095]], [[-1.0000000000000002, 1, 1.414213562373095], [-2.59786816870648e-16, 1.4142135623730951, 1.414213562373095], [-3.6739403974420594e-16, 2, 0], [-1.4142135623730954, 1.414213562373095, 0]], [[-1.0000000000000002, 1, -1.414213562373095], [-2.59786816870648e-16, 1.4142135623730951, -1.414213562373095], [-8.659560562354935e-17, 8.659560562354932e-17, -2]], [[-8.659560562354935e-17, 8.659560562354932e-17, 2], [-2.59786816870648e-16, 1.4142135623730951, 1.414213562373095], [-1.0000000000000002, 1, 1.414213562373095]], [[-3.6739403974420594e-16, 2, 0], [1.4142135623730947, 1.4142135623730954, 0], [0.9999999999999998, 1.0000000000000002, -1.414213562373095], [-2.59786816870648e-16, 1.4142135623730951, -1.414213562373095]], [[-2.59786816870648e-16, 1.4142135623730951, 1.414213562373095], [0.9999999999999998, 1.0000000000000002, 1.414213562373095], [1.4142135623730947, 1.4142135623730954, 0], [-3.6739403974420594e-16, 2, 0]], [[-2.59786816870648e-16, 1.4142135623730951, -1.414213562373095], [0.9999999999999998, 1.0000000000000002, -1.414213562373095], [-2.2496396739927864e-32, 1.2246467991473532e-16, -2]], [[-2.2496396739927864e-32, 1.2246467991473532e-16, 2], [0.9999999999999998, 1.0000000000000002, 1.414213562373095], [-2.59786816870648e-16, 1.4142135623730951, 1.414213562373095]], [[1.4142135623730947, 1.4142135623730954, 0], [2, 4.898587196589413e-16, 0], [1.4142135623730951, 3.4638242249419736e-16, -1.414213562373095], [0.9999999999999998, 1.0000000000000002, -1.414213562373095]], [[0.9999999999999998, 1.0000000000000002, 1.414213562373095], [1.4142135623730951, 3.4638242249419736e-16, 1.414213562373095], [2, 4.898587196589413e-16, 0], [1.4142135623730947, 1.4142135623730954, 0]], [[0.9999999999999998, 1.0000000000000002, -1.414213562373095], [1.4142135623730951, 3.4638242249419736e-16, -1.414213562373095], [8.65956056235493e-17, 8.659560562354935e-17, -2]], [[8.65956056235493e-17, 8.659560562354935e-17, 2], [1.4142135623730951, 3.4638242249419736e-16, 1.414213562373095], [0.9999999999999998, 1.0000000000000002, 1.414213562373095]] ] t.notThrows.skip(() => geom3.validate(result1)) t.true(comparePolygonsAsPoints(obs, exp)) // union of two non-overlapping objects const geometry2 = center({ relativeTo: [10, 10, 10] }, cuboid({ size: [4, 4, 4] })) const result2 = union(geometry1, geometry2) obs = geom3.toPoints(result2) t.notThrows.skip(() => geom3.validate(result2)) t.is(obs.length, 38) // union of two partially overlapping objects const geometry3 = cuboid({ size: [18, 18, 18] }) const result3 = union(geometry2, geometry3) obs = geom3.toPoints(result3) exp = [ [[12, 8, 8], [12, 12, 8], [12, 12, 12], [12, 8, 12]], [[8, 12, 8], [8, 12, 12], [12, 12, 12], [12, 12, 8]], [[8, 8, 12], [12, 8, 12], [12, 12, 12], [8, 12, 12]], [[8, 12, 12], [8, 12, 9], [8, 8, 9], [8, 8, 12]], [[8, 12, 9], [8, 12, 8], [8, 9, 8], [8, 9, 9]], [[8, 8, 12], [8, 8, 9], [12, 8, 9], [12, 8, 12]], [[9, 8, 9], [9, 8, 8], [12, 8, 8], [12, 8, 9]], [[12, 12, 8], [12, 9, 8], [8, 9, 8], [8, 12, 8]], [[12, 9, 8], [12, 8, 8], [9, 8, 8], [9, 9, 8]], [[-9, -9, -9], [-9, -9, 9], [-9, 9, 9], [-9, 9, -9]], [[-9, -9, -9], [9, -9, -9], [9, -9, 9], [-9, -9, 9]], [[-9, -9, -9], [-9, 9, -9], [9, 9, -9], [9, -9, -9]], [[9, -9, 9], [9, -9, 8], [9, 8, 8], [9, 8, 9]], [[9, -9, 8], [9, -9, -9], [9, 9, -9], [9, 9, 8]], [[8, 9, 9], [8, 9, 8], [-9, 9, 8], [-9, 9, 9]], [[9, 9, 8], [9, 9, -9], [-9, 9, -9], [-9, 9, 8]], [[-9, 9, 9], [-9, 8, 9], [8, 8, 9], [8, 9, 9]], [[-9, 8, 9], [-9, -9, 9], [9, -9, 9], [9, 8, 9]] ] t.notThrows.skip(() => geom3.validate(result3)) t.is(obs.length, 18) t.true(comparePolygonsAsPoints(obs, exp)) // union of two completely overlapping objects const result4 = union(geometry1, geometry3) obs = geom3.toPoints(result4) exp = [ [[-9, -9, -9], [-9, -9, 9], [-9, 9, 9], [-9, 9, -9]], [[9, -9, -9], [9, 9, -9], [9, 9, 9], [9, -9, 9]], [[-9, -9, -9], [9, -9, -9], [9, -9, 9], [-9, -9, 9]], [[-9, 9, -9], [-9, 9, 9], [9, 9, 9], [9, 9, -9]], [[-9, -9, -9], [-9, 9, -9], [9, 9, -9], [9, -9, -9]], [[-9, -9, 9], [9, -9, 9], [9, 9, 9], [-9, 9, 9]] ] t.notThrows(() => geom3.validate(result4)) t.is(obs.length, 6) t.true(comparePolygonsAsPoints(obs, exp)) }) test('union of geom3 with rounding issues #137', (t) => { const geometry1 = center({ relativeTo: [0, 0, -1] }, cuboid({ size: [44, 26, 5] })) const geometry2 = center({ relativeTo: [0, 0, -4.400001] }, cuboid({ size: [44, 26, 1.8] })) // introduce precision error const obs = union(geometry1, geometry2) const pts = geom3.toPoints(obs) t.notThrows(() => geom3.validate(obs)) t.is(pts.length, 6) // number of polygons in union })