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
Geometries are objects that represent the contents of primitives or the results of operations. Note: Geometries are considered immutable, so never change the contents directly. The library provides five main geometry types for different geometric representations.
2D geometry consisting of sides (line segments) that form closed shapes.
const geom2: {
/**
* Create a new 2D geometry from sides
* @param {Array} [sides] - Array of sides, each side is array of two points
* @returns {geom2} New 2D geometry
*/
create(sides?: Array<[[number, number], [number, number]]>): geom2;
/**
* Create deep copy of 2D geometry
* @param {geom2} geometry - Geometry to clone
* @returns {geom2} Cloned geometry
*/
clone(geometry: geom2): geom2;
/**
* Check if object is a geom2
* @param {Object} object - Object to test
* @returns {Boolean} True if object is geom2
*/
isA(object: any): boolean;
/**
* Get the sides of a 2D geometry
* @param {geom2} geometry - Input geometry
* @returns {Array} Array of sides
*/
toSides(geometry: geom2): Array<[[number, number], [number, number]]>;
/**
* Get outline points of 2D geometry
* @param {geom2} geometry - Input geometry
* @returns {Array} Array of [x,y] points
*/
toPoints(geometry: geom2): Array<[number, number]>;
/**
* Reverse the orientation of 2D geometry
* @param {geom2} geometry - Input geometry
* @returns {geom2} Reversed geometry
*/
reverse(geometry: geom2): geom2;
/**
* Transform 2D geometry using matrix
* @param {mat4} matrix - Transformation matrix
* @param {geom2} geometry - Input geometry
* @returns {geom2} Transformed geometry
*/
transform(matrix: mat4, geometry: geom2): geom2;
/**
* Validate 2D geometry for errors
* @param {geom2} geometry - Geometry to validate
* @returns {Boolean} True if valid
*/
validate(geometry: geom2): boolean;
};Usage Examples:
const { geom2 } = require('@jscad/modeling').geometries;
// Create geometry from sides
const sides = [
[[0, 0], [5, 0]],
[[5, 0], [5, 3]],
[[5, 3], [0, 3]],
[[0, 3], [0, 0]]
];
const rect = geom2.create(sides);
// Clone geometry
const rectCopy = geom2.clone(rect);
// Get outline points
const points = geom2.toPoints(rect);
// [[0, 0], [5, 0], [5, 3], [0, 3]]
// Check if valid geometry
const isValid = geom2.validate(rect);3D geometry consisting of polygons that form solid shapes.
const geom3: {
/**
* Create a new 3D geometry from polygons
* @param {Array} [polygons] - Array of poly3 objects
* @returns {geom3} New 3D geometry
*/
create(polygons?: poly3[]): geom3;
/**
* Create deep copy of 3D geometry
* @param {geom3} geometry - Geometry to clone
* @returns {geom3} Cloned geometry
*/
clone(geometry: geom3): geom3;
/**
* Check if object is a geom3
* @param {Object} object - Object to test
* @returns {Boolean} True if object is geom3
*/
isA(object: any): boolean;
/**
* Get the polygons of a 3D geometry
* @param {geom3} geometry - Input geometry
* @returns {Array} Array of poly3 objects
*/
toPolygons(geometry: geom3): poly3[];
/**
* Get all vertices of 3D geometry
* @param {geom3} geometry - Input geometry
* @returns {Array} Array of [x,y,z] vertices
*/
toVertices(geometry: geom3): Array<[number, number, number]>;
/**
* Reverse the orientation of 3D geometry
* @param {geom3} geometry - Input geometry
* @returns {geom3} Reversed geometry
*/
reverse(geometry: geom3): geom3;
/**
* Transform 3D geometry using matrix
* @param {mat4} matrix - Transformation matrix
* @param {geom3} geometry - Input geometry
* @returns {geom3} Transformed geometry
*/
transform(matrix: mat4, geometry: geom3): geom3;
/**
* Validate 3D geometry for errors
* @param {geom3} geometry - Geometry to validate
* @returns {Boolean} True if valid
*/
validate(geometry: geom3): boolean;
};Usage Examples:
const { geom3, poly3 } = require('@jscad/modeling').geometries;
// Create simple tetrahedron
const vertices1 = [[0, 0, 0], [1, 0, 0], [0.5, 1, 0]];
const vertices2 = [[0, 0, 0], [0.5, 1, 0], [0.5, 0.5, 1]];
const vertices3 = [[1, 0, 0], [0.5, 1, 0], [0.5, 0.5, 1]];
const vertices4 = [[0, 0, 0], [1, 0, 0], [0.5, 0.5, 1]];
const polygons = [
poly3.create(vertices1),
poly3.create(vertices2),
poly3.create(vertices3),
poly3.create(vertices4)
];
const tetrahedron = geom3.create(polygons);
// Get all vertices
const allVertices = geom3.toVertices(tetrahedron);
// Validate geometry
const isValid = geom3.validate(tetrahedron);2D geometry consisting of ordered points that form an open or closed path.
const path2: {
/**
* Create a new 2D path from points
* @param {Array} [points] - Array of [x,y] points
* @param {Boolean} [isClosed=false] - Whether path is closed
* @returns {path2} New 2D path
*/
create(points?: Array<[number, number]>, isClosed?: boolean): path2;
/**
* Create 2D path from points array
* @param {Array} points - Array of [x,y] points
* @returns {path2} New path
*/
fromPoints(points: Array<[number, number]>): path2;
/**
* Create deep copy of 2D path
* @param {path2} geometry - Path to clone
* @returns {path2} Cloned path
*/
clone(geometry: path2): path2;
/**
* Check if object is a path2
* @param {Object} object - Object to test
* @returns {Boolean} True if object is path2
*/
isA(object: any): boolean;
/**
* Get points of 2D path
* @param {path2} geometry - Input path
* @returns {Array} Array of [x,y] points
*/
toPoints(geometry: path2): Array<[number, number]>;
/**
* Close the 2D path by connecting last point to first
* @param {path2} geometry - Input path
* @returns {path2} Closed path
*/
close(geometry: path2): path2;
/**
* Reverse the direction of 2D path
* @param {path2} geometry - Input path
* @returns {path2} Reversed path
*/
reverse(geometry: path2): path2;
/**
* Transform 2D path using matrix
* @param {mat4} matrix - Transformation matrix
* @param {path2} geometry - Input path
* @returns {path2} Transformed path
*/
transform(matrix: mat4, geometry: path2): path2;
/**
* Append points to existing path
* @param {path2} geometry - Input path
* @param {...Array} points - Points to append
* @returns {path2} Extended path
*/
appendPoints(geometry: path2, ...points: Array<[number, number]>): path2;
};Usage Examples:
const { path2 } = require('@jscad/modeling').geometries;
// Create open path
const points = [[0, 0], [5, 0], [5, 5], [2, 8], [0, 5]];
const openPath = path2.fromPoints(points);
// Create closed path
const closedPath = path2.close(openPath);
// Append more points
const extended = path2.appendPoints(openPath, [10, 10], [15, 5]);
// Get path points
const pathPoints = path2.toPoints(extended);2D polygon consisting of ordered vertices that form a closed shape.
const poly2: {
/**
* Create a new 2D polygon from vertices
* @param {Array} [vertices] - Array of [x,y] vertices
* @returns {poly2} New 2D polygon
*/
create(vertices?: Array<[number, number]>): poly2;
/**
* Create deep copy of 2D polygon
* @param {poly2} geometry - Polygon to clone
* @returns {poly2} Cloned polygon
*/
clone(geometry: poly2): poly2;
/**
* Check if object is a poly2
* @param {Object} object - Object to test
* @returns {Boolean} True if object is poly2
*/
isA(object: any): boolean;
/**
* Get vertices of 2D polygon
* @param {poly2} geometry - Input polygon
* @returns {Array} Array of [x,y] vertices
*/
toVertices(geometry: poly2): Array<[number, number]>;
/**
* Reverse the orientation of 2D polygon
* @param {poly2} geometry - Input polygon
* @returns {poly2} Reversed polygon
*/
reverse(geometry: poly2): poly2;
/**
* Transform 2D polygon using matrix
* @param {mat4} matrix - Transformation matrix
* @param {poly2} geometry - Input polygon
* @returns {poly2} Transformed polygon
*/
transform(matrix: mat4, geometry: poly2): poly2;
};Usage Examples:
const { poly2 } = require('@jscad/modeling').geometries;
// Create triangle
const vertices = [[0, 0], [5, 0], [2.5, 4]];
const triangle = poly2.create(vertices);
// Get vertices
const triangleVertices = poly2.toVertices(triangle);
// Reverse orientation (clockwise to counter-clockwise)
const reversed = poly2.reverse(triangle);3D polygon consisting of ordered vertices that form a planar face in 3D space.
const poly3: {
/**
* Create a new 3D polygon from vertices
* @param {Array} [vertices] - Array of [x,y,z] vertices
* @returns {poly3} New 3D polygon
*/
create(vertices?: Array<[number, number, number]>): poly3;
/**
* Create deep copy of 3D polygon
* @param {poly3} geometry - Polygon to clone
* @returns {poly3} Cloned polygon
*/
clone(geometry: poly3): poly3;
/**
* Check if object is a poly3
* @param {Object} object - Object to test
* @returns {Boolean} True if object is poly3
*/
isA(object: any): boolean;
/**
* Get vertices of 3D polygon
* @param {poly3} geometry - Input polygon
* @returns {Array} Array of [x,y,z] vertices
*/
toVertices(geometry: poly3): Array<[number, number, number]>;
/**
* Get plane equation of 3D polygon
* @param {poly3} geometry - Input polygon
* @returns {Array} Plane as [a,b,c,d]
*/
plane(geometry: poly3): [number, number, number, number];
/**
* Reverse the orientation of 3D polygon
* @param {poly3} geometry - Input polygon
* @returns {poly3} Reversed polygon
*/
reverse(geometry: poly3): poly3;
/**
* Transform 3D polygon using matrix
* @param {mat4} matrix - Transformation matrix
* @param {poly3} geometry - Input polygon
* @returns {poly3} Transformed polygon
*/
transform(matrix: mat4, geometry: poly3): poly3;
};Usage Examples:
const { poly3 } = require('@jscad/modeling').geometries;
// Create 3D triangle
const vertices = [[0, 0, 0], [5, 0, 0], [2.5, 4, 2]];
const triangle3D = poly3.create(vertices);
// Get plane equation
const trianglePlane = poly3.plane(triangle3D);
// Get vertices
const vertices3D = poly3.toVertices(triangle3D);Convert between different geometry types:
const { geom2, path2, poly2 } = require('@jscad/modeling').geometries;
// Convert path to geom2 (if closed)
const points = [[0, 0], [5, 0], [5, 5], [0, 5], [0, 0]];
const closedPath = path2.fromPoints(points);
const convertedGeom = geom2.create(path2.toSides(closedPath));
// Extract polygon from geom2
const sides = geom2.toSides(convertedGeom);
const outline = sides.map(side => side[0]); // First point of each side
const polygon = poly2.create(outline);Validate and repair geometry issues:
const { geom2, geom3 } = require('@jscad/modeling').geometries;
const validateAndRepair = (geometry) => {
if (geom2.isA(geometry)) {
const isValid = geom2.validate(geometry);
if (!isValid) {
console.warn('Invalid 2D geometry detected');
// Attempt repair by removing duplicate points
const points = geom2.toPoints(geometry);
const uniquePoints = points.filter((point, index) => {
return index === 0 ||
point[0] !== points[index-1][0] ||
point[1] !== points[index-1][1];
});
return geom2.fromPoints(uniquePoints);
}
}
return geometry;
};Create complex geometries programmatically:
const { geom2, poly2 } = require('@jscad/modeling').geometries;
// Create star shape using polygon
const createStar = (points, outerRadius, innerRadius) => {
const vertices = [];
const angleStep = (Math.PI * 2) / points;
for (let i = 0; i < points; i++) {
// Outer point
const outerAngle = i * angleStep;
vertices.push([
Math.cos(outerAngle) * outerRadius,
Math.sin(outerAngle) * outerRadius
]);
// Inner point
const innerAngle = (i + 0.5) * angleStep;
vertices.push([
Math.cos(innerAngle) * innerRadius,
Math.sin(innerAngle) * innerRadius
]);
}
return poly2.create(vertices);
};
const star = createStar(5, 10, 5);Analyze geometry properties:
const { geom2, geom3, measureArea, measureVolume } = require('@jscad/modeling');
const analyzeGeometry = (geometry) => {
const analysis = {};
if (geom2.isA(geometry)) {
analysis.type = '2D';
analysis.points = geom2.toPoints(geometry);
analysis.sides = geom2.toSides(geometry).length;
analysis.area = measureArea(geometry);
} else if (geom3.isA(geometry)) {
analysis.type = '3D';
analysis.polygons = geom3.toPolygons(geometry).length;
analysis.vertices = geom3.toVertices(geometry).length;
analysis.volume = measureVolume(geometry);
analysis.surfaceArea = measureArea(geometry);
}
return analysis;
};