Constructive Solid Geometry (CSG) Library for 2D and 3D geometries with boolean operations, transformations, and mathematical utilities
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Boolean operations allow you to perform logical operations on shapes using Constructive Solid Geometry (CSG) algorithms. All shapes (primitives or the results of operations) can be passed to boolean functions to perform logical operations like removing a hole from a board. In all cases, the functions return new results and never change the original shapes.
Return a new geometry representing the total space in the given geometries. Creates a single shape that encompasses all input shapes.
/**
* Return a new geometry representing the total space in the given geometries
* @param {...Object} geometries - Geometries to union (supports nested arrays)
* @returns {Geom2|Geom3} A new geometry representing the union
*/
function union(...geometries: RecursiveArray<Geom2>): Geom2;
function union(...geometries: RecursiveArray<Geom3>): Geom3;Usage Examples:
const { cube, sphere, union } = require('@jscad/modeling');
// Union of two overlapping cubes
const cube1 = cube({ size: 10, center: [0, 0, 0] });
const cube2 = cube({ size: 10, center: [5, 5, 5] });
const combined = union(cube1, cube2);
// Union of multiple shapes
const sphere1 = sphere({ radius: 4, center: [-3, 0, 0] });
const sphere2 = sphere({ radius: 4, center: [3, 0, 0] });
const sphere3 = sphere({ radius: 4, center: [0, 0, 6] });
const threeSpheres = union(sphere1, sphere2, sphere3);Return a new geometry representing the intersection (overlapping space) of the given geometries.
/**
* Return the intersection of the given geometries
* @param {...Object} geometries - Geometries to intersect (supports nested arrays)
* @returns {Geom2|Geom3} A new geometry representing the intersection
*/
function intersect(...geometries: RecursiveArray<Geom2>): Geom2;
function intersect(...geometries: RecursiveArray<Geom3>): Geom3;Usage Examples:
const { cube, sphere, intersect } = require('@jscad/modeling');
// Intersection of cube and sphere creates rounded cube corners
const myCube = cube({ size: 10 });
const mySphere = sphere({ radius: 8 });
const roundedCube = intersect(myCube, mySphere);
// Intersection of three cylinders for complex internal cavity
const { cylinder, rotateY, rotateX } = require('@jscad/modeling');
const cyl1 = cylinder({ height: 20, radius: 3 });
const cyl2 = rotateY(Math.PI/2, cylinder({ height: 20, radius: 3 }));
const cyl3 = rotateX(Math.PI/2, cylinder({ height: 20, radius: 3 }));
const tripleIntersection = intersect(cyl1, cyl2, cyl3);Return a new geometry with the first geometry minus all subsequent geometries. Removes material from the first shape.
/**
* Return a new geometry with the first geometry minus all subsequent geometries
* @param {...Object} geometries - Geometries for subtraction (supports nested arrays)
* @returns {Geom2|Geom3} A new geometry representing the subtraction
*/
function subtract(...geometries: RecursiveArray<Geom2>): Geom2;
function subtract(...geometries: RecursiveArray<Geom3>): Geom3;Usage Examples:
const { cube, cylinder, sphere, subtract, translate } = require('@jscad/modeling');
// Create a cube with cylindrical hole
const baseCube = cube({ size: 20 });
const hole = cylinder({ height: 25, radius: 3 });
const cubeWithHole = subtract(baseCube, hole);
// Create complex shape by subtracting multiple objects
const baseShape = cube({ size: 15 });
const hole1 = translate([5, 5, 0], cylinder({ height: 20, radius: 2 }));
const hole2 = translate([-5, -5, 0], cylinder({ height: 20, radius: 2 }));
const sphericalCut = sphere({ radius: 8, center: [0, 0, 10] });
const complexShape = subtract(baseShape, hole1, hole2, sphericalCut);Split geometries into separate pieces along intersection boundaries. Returns an array of separate geometries.
/**
* Split the given 3D geometries into separate pieces (3D only)
* @param {...Object} geometries - 3D geometries to split (supports nested arrays)
* @returns {Array<Geom3>} Array of separate 3D geometries
*/
function scission(...geometries: RecursiveArray<Geom3>): Array<Geom3>;Usage Examples:
const { cube, sphere, scission, translate } = require('@jscad/modeling');
// Split overlapping shapes into separate pieces
const cube1 = cube({ size: 10, center: [-3, 0, 0] });
const cube2 = cube({ size: 10, center: [3, 0, 0] });
const pieces = scission(cube1, cube2);
// Returns array with separate geometric pieces
// Split complex overlapping geometry
const sphere1 = sphere({ radius: 6, center: [0, 0, 0] });
const sphere2 = sphere({ radius: 6, center: [4, 4, 0] });
const sphere3 = sphere({ radius: 6, center: [-4, 4, 0] });
const splitResult = scission(sphere1, sphere2, sphere3);Boolean operations can be chained together to create complex shapes:
const { cube, cylinder, sphere, union, subtract, intersect } = require('@jscad/modeling');
// Create a complex mechanical part
const base = cube({ size: [20, 15, 10] });
const mainHole = cylinder({ height: 12, radius: 4 });
const sideHole1 = translate([6, 0, 0], cylinder({ height: 8, radius: 2 }));
const sideHole2 = translate([-6, 0, 0], cylinder({ height: 8, radius: 2 }));
// Add rounded corners
const cornerRounding = sphere({ radius: 2, center: [9, 6, 4] });
const roundedBase = union(base, cornerRounding);
// Remove holes
const finalPart = subtract(roundedBase, mainHole, sideHole1, sideHole2);Boolean operations work equally well with 2D geometries:
const { circle, rectangle, polygon, union, subtract } = require('@jscad/modeling');
// Create a 2D part with holes
const baseRect = rectangle({ size: [20, 15] });
const hole1 = circle({ radius: 3, center: [5, 3] });
const hole2 = circle({ radius: 2, center: [-5, -3] });
const cutout = polygon({ points: [[8, 0], [12, 4], [8, 8], [4, 4]] });
const part2D = subtract(baseRect, hole1, hole2, cutout);All geometries passed to boolean operations must be of the same type (all geom2 or all geom3):
const { cube, circle, union } = require('@jscad/modeling');
const myCube = cube({ size: 5 }); // geom3
const myCircle = circle({ radius: 3 }); // geom2
// This will throw an error - mixed types not supported
// const invalid = union(myCube, myCircle); // ERROR!
// Valid - same types only
const cube1 = cube({ size: 5 });
const cube2 = cube({ size: 3 });
const validUnion = union(cube1, cube2); // OKBoolean functions will throw errors for:
The boolean operations are implemented using Binary Space Partitioning (BSP) trees:
// Recursive array type for nested geometry arrays
type RecursiveArray<T> = Array<T | RecursiveArray<T>>;
// Core geometry types (uppercase for TypeScript definitions)
type Geom2 = {
sides: Array<Array<[number, number]>>;
color?: [number, number, number, number];
};
type Geom3 = {
polygons: Array<Poly3>;
color?: [number, number, number, number];
};
type Poly3 = {
vertices: Array<[number, number, number]>;
};