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
The hulls module provides convex hull operations for geometries, enabling the creation of outer bounds, smooth transitions between shapes, and protective casings. It supports both 2D and 3D geometries with efficient algorithms for point-based and geometry-based hulls.
Create convex hulls from multiple geometries to find their outer boundary.
/**
* Create convex hull of given geometries
* @param {...Object} geometries - Variable number of geometry objects (geom2, geom3, or path2)
* @returns {Object} New geometry representing the convex hull
*/
function hull(...geometries: RecursiveArray<Geom2>): Geom2;
function hull(...geometries: RecursiveArray<Geom3>): Geom3;
function hull(...geometries: RecursiveArray<Path2>): Path2;
/**
* Create chain of hulled geometries with smooth transitions
* @param {...Object} geometries - Variable number of geometry objects (minimum 2)
* @returns {Object} Union of all consecutive hull pairs
*/
function hullChain(...geometries: RecursiveArray<Geom2>): Geom2;
function hullChain(...geometries: RecursiveArray<Geom3>): Geom3;
function hullChain(...geometries: RecursiveArray<Path2>): Path2;Usage Examples:
const { hull, hullChain } = require('@jscad/modeling').hulls;
const { rectangle, circle, triangle } = require('@jscad/modeling').primitives;
// Basic convex hull of multiple shapes
const envelope = hull(
rectangle({ center: [-5, -5], size: [4, 4] }),
circle({ center: [5, 5], radius: 3 }),
triangle()
);
// Smooth transition between shapes
const smoothTransition = hullChain(
rectangle({ center: [-10, 0] }),
circle({ center: [0, 0] }),
rectangle({ center: [10, 0] })
);
// Multiple geometry hull for protective casing
const casing = hull(component1, component2, component3);Create convex hulls directly from arrays of points using efficient algorithms.
/**
* Create 2D convex hull from array of points using Graham scan algorithm
* @param {Array} uniquePoints - Array of unique 2D points [[x,y], [x,y], ...]
* @returns {Array} Array of points forming convex hull boundary (counter-clockwise)
*/
function hullPoints2(uniquePoints: Array<[number, number]>): Array<[number, number]>;
/**
* Create 3D convex hull from array of points using QuickHull algorithm
* @param {Array} uniquePoints - Array of unique 3D points [[x,y,z], [x,y,z], ...]
* @returns {Array} Array of polygons (triangular faces) forming convex hull surface
*/
function hullPoints3(uniquePoints: Array<[number, number, number]>): Array<Poly3>;Usage Examples:
const { hullPoints2, hullPoints3 } = require('@jscad/modeling').hulls;
// 2D convex hull from scattered points
const points2D = [
[0, 0], [3, 1], [1, 3], [5, 2],
[2, 4], [4, 0], [1, 1] // interior point
];
const hull2D = hullPoints2(points2D); // Returns boundary points only
// 3D convex hull from point cloud
const points3D = [
[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1],
[1, 1, 0], [1, 0, 1], [0, 1, 1], [1, 1, 1],
[0.5, 0.5, 0.5] // interior point
];
const hull3D = hullPoints3(points3D); // Returns triangular faces
// Create geometry from hull points
const { geom2, geom3 } = require('@jscad/modeling').geometries;
const hullGeometry2D = geom2.fromPoints(hull2D);
const hullGeometry3D = geom3.create(hull3D);const { hull } = require('@jscad/modeling').hulls;
const { expand } = require('@jscad/modeling').expansions;
// Create protective casing around components
const components = [motor, battery, circuitBoard, connector];
const looseFit = hull(...components);
const tightFit = hull(...components.map(c => expand({ delta: 0.5 }, c)));
// Enclosure with mounting tabs
const enclosure = hull(
mainBody,
...mountingTabs.map(tab => translate(tab.position, tab.geometry))
);const { hullChain } = require('@jscad/modeling').hulls;
const { union } = require('@jscad/modeling').booleans;
// Morphing animation frames
const morphFrames = [];
const startShape = circle({ radius: 5 });
const endShape = rectangle({ size: [10, 8] });
// Create intermediate hull shapes for animation
for (let i = 0; i <= 10; i++) {
const t = i / 10;
const frame = hullChain(
scale([1 - t + 0.1, 1 - t + 0.1], startShape),
scale([t + 0.1, t + 0.1], endShape)
);
morphFrames.push(frame);
}
// Continuous transition structure
const bridge = hullChain(pillar1, arch, pillar2);const { hullPoints3 } = require('@jscad/modeling').hulls;
// Process 3D scan data
function processPointCloud(scanPoints) {
// Remove duplicate points
const uniquePoints = [...new Set(scanPoints.map(p => p.join(',')))].map(s => s.split(',').map(Number));
// Create convex hull
const hullFaces = hullPoints3(uniquePoints);
// Convert to solid geometry
const { geom3 } = require('@jscad/modeling').geometries;
return geom3.create(hullFaces);
}
// Simplify complex geometry to convex approximation
function simplifyToHull(complexGeometry) {
const { measureBoundingBox } = require('@jscad/modeling').measurements;
const bounds = measureBoundingBox(complexGeometry);
// Extract boundary points and create hull
const points = extractSurfacePoints(complexGeometry, 100); // Custom function
return hullPoints3(points);
}// Recursive array type for nested geometry arrays
type RecursiveArray<T> = Array<T | RecursiveArray<T>>;
// 2D point type
type Vec2 = [number, number];
// 3D point type
type Vec3 = [number, number, number];
// 3D polygon face
type Poly3 = {
vertices: Array<Vec3>;
};
// Supported geometry types
type Geom2 = {
sides: Array<Array<Vec2>>;
color?: [number, number, number, number];
};
type Geom3 = {
polygons: Array<Poly3>;
color?: [number, number, number, number];
};
type Path2 = {
points: Array<Vec2>;
isClosed: boolean;
};fakeAtan2 function for better performance than Math.atan2