Choose another example:
function main() { var cube = CSG.cube(); return cube; }creates a cube with a radius of 1 and centered at the origin. The code should always contain a main() function. The main() function should return a CSG object (for a 3D solid) or a CAG object (for a 2D area). It's also possible to return multiple objects (a dropdown box will be shown to select the part to be displayed), see rendering multiple objects.
radius: 1
will give radius: [1,1,1]
.
// a cube: var cube = CSG.cube({ center: [0, 0, 0], radius: [1, 1, 1] }); // or alternatively by specifying two diagonally opposite corners: var cube = CSG.cube({ corner1: [-10, 5, 10], corner2: [10, -5, 1] }); // a sphere: var sphere = CSG.sphere({ center: [0, 0, 0], radius: 2, // must be scalar resolution: 32 // optional }); // a cylinder: var cylinder = CSG.cylinder({ start: [0, -1, 0], end: [0, 1, 0], radius: 1, resolution: 16 // optional }); // a cone: var cone = CSG.cylinder({ start: [0, -1, 0], end: [0, 1, 0], radiusStart: 1, radiusEnd: 2, resolution: 16 // optional }); // a cone or cylinder sector: var coneSector = CSG.cylinder({ start: [0, 0, -1], end: [0, 0, 1], radiusStart: 2, radiusEnd: 1, sectorAngle: 90, resolution: 16 // optional }); // like a cylinder, but with spherical endpoints: var roundedCylinder = CSG.roundedCylinder({ start: [0, -1, 0], end: [0, 1, 0], radius: 1, resolution: 16 // optional }); // a rounded cube: var cube = CSG.roundedCube({ corner1: [-10, 5, 10], corner2: [10, -5, 1] roundradius: 3, resolution: 8, // optional }); // roundedCube works with a vector radius too: var cube = CSG.roundedCube({ radius: [10, 5, 8], roundradius: [3, 5, 0.01], resolution: 24 }); // a polyhedron (point ordering for faces: when looking at the face from the outside inwards, the points must be clockwise): var polyhedron = CSG.polyhedron({ points:[ [10,10,0],[10,-10,0],[-10,-10,0],[-10,10,0], // the four points at base [0,0,10] ], // the apex point faces:[ [0,1,4],[1,2,4],[2,3,4],[3,0,4], // each triangle side [1,0,3],[2,1,3] ] // two triangles for square base });
var csg1 = cube.union(sphere); var csg2 = cube.intersect(sphere); var csg3 = cube.subtract(sphere); // combine multiple solids in one go (faster): var csg1 = cube.union([solid1, solid2, solid3]); var csg2 = cube.intersect([solid1, solid2, solid3]); var csg3 = cube.subtract([solid1, solid2, solid3]);
var cube = CSG.cube(); // translation: var cube2 = cube.translate([1, 2, 3]); // scaling: var largecube = cube.scale(2.0); var stretchedcube = cube.scale([1.5, 1, 0.5]); // rotation: var rotated1 = cube.rotateX(-45); // rotate around the X axis var rotated2 = cube.rotateY(90); // rotate around the Y axis var rotated3 = cube.rotateZ(20); // rotate around the Z axis // combine multiple transforms into a single matrix transform: var m = new CSG.Matrix4x4(); m = m.multiply(CSG.Matrix4x4.rotationX(40)); m = m.multiply(CSG.Matrix4x4.rotationZ(40)); m = m.multiply(CSG.Matrix4x4.translation([-.5, 0, 0])); m = m.multiply(CSG.Matrix4x4.scaling([1.1, 1.2, 1.3])); // and apply the transform: var cube3 = cube.transform(m);
var cube = CSG.cube().translate([1,0,0]); var cube2 = cube.mirroredX(); // mirrored in the x=0 plane var cube3 = cube.mirroredY(); // mirrored in the y=0 plane var cube4 = cube.mirroredZ(); // mirrored in the z=0 plane // create a plane by specifying 3 points: var plane = CSG.Plane.fromPoints([5,0,0], [5, 1, 0], [3, 1, 7]); // and mirror in that plane: var cube5 = cube.mirrored(plane);
var cube = CSG.cube().translate([1, 2, 3]); var cubeC = cube.center(); // only center on selected axes var cubeCx = cube.center('x'); var cubeCxz = cube.center('x', 'z');
var cube = CSG.cube({radius: 10}); // create a plane by specifying 3 points: var plane1 = CSG.Plane.fromPoints([5,0,0], [7, 1, 0], [3, 1, 7]); // or by specifying a normal and a point on the plane: var plane2 = CSG.Plane.fromNormalAndPoint([3, 1, 2], [5, 0, 0]); // and cut by the plane: var part1 = cube.cutByPlane(plane2); // or if we need the other half of the cube: var part2 = cube.cutByPlane(plane2.flipped());
var cube1 = CSG.cube({radius: 1.0}); var cube2 = CSG.cube({radius: 1.0}).translate([-0.3, -0.3, -0.3]); var csg = cube1.subtract(cube2); var rounded = csg.expand(0.2, 8);
var stretched_csg = csg.stretchAtPlane(normal, point, length); In the gear example, function main, try replacing return gear; with return gear.stretchAtPlane([0, 0.05, 1], [0, 0, 0], 30);
var cube = CSG.cube({radius: 1.0}); cube.properties.aCorner = new CSG.Vector3D([1, 1, 1]); cube = cube.translate([5, 0, 0]); cube = cube.scale(2); // cube.properties.aCorner will now point to [12, 2, 2], // which is still the same corner point // Properties can be stored in arrays; all properties in the array // will be transformed if the solid is transformed: cube.properties.otherCorners = [ new CSG.Vector3D([-1, 1, 1]), new CSG.Vector3D([-1, -1, 1]) ]; // and we can create sub-property objects; these must be of the // CSG.Properties class. All sub properties will be transformed with // the solid: cube.properties.myProperties = new CSG.Properties(); cube.properties.myProperties.someProperty = new CSG.Vector3D([-1, -1, -1]);For an example checkout the Servo motor example.
var cube1 = CSG.cube({radius: 10}); var cube2 = CSG.cube({radius: 4}); // define a connector on the center of one face of cube1 // The connector's axis points outwards and its normal points // towards the positive z axis: cube1.properties.myConnector = new CSG.Connector([10, 0, 0], [1, 0, 0], [0, 0, 1]); // define a similar connector for cube 2: cube2.properties.myConnector = new CSG.Connector([0, -4, 0], [0, -1, 0], [0, 0, 1]); // do some random transformations on cube 1: cube1 = cube1.rotateX(30); cube1 = cube1.translate([3.1, 2, 0]); // Now attach cube2 to cube 1: cube2 = cube2.connectTo( cube2.properties.myConnector, cube1.properties.myConnector, true, // mirror 0 // normalrotation ); // Or alternatively: var matrix = cube2.properties.myConnector.getTransformationTo( cube1.properties.myConnector, true, // mirror 0 // normalrotation ); cube2 = cube2.transform(matrix); var result = cube2.union(cube1);For a more complete example see the Servo motor example.
var cube1 = CSG.cube({radius: 10}); var cube2 = CSG.cube({radius: 5}); // get the right bound of cube1 and the left bound of cube2: var deltax = cube1.getBounds()[1].x - cube2.getBounds()[0].x; // align cube2 so it touches cube1: cube2 = cube2.translate([deltax, 0, 0]); var cube3 = CSG.cube({radius: [100,120,10]}); // do some random transformations: cube3 = cube3.rotateZ(31).rotateX(50).translate([30,50,20]); // now place onto the z=0 plane: cube3 = cube3.lieFlat(); // or instead we could have used: var transformation = cube3.getTransformationToFlatLying(); cube3 = cube3.transform(transformation); // or: var obj = cube3.getTransformationAndInverseTransformationToFlatLying(); var forwardtransformation=obj[0]; var backtransformation=obj[1]; cube3 = cube3.transform(forwardtransformation); return cube3;
// Create a shape; argument is an array of 2D coordinates var shape1 = CAG.fromPoints([[0,0], [5,0], [3,5], [0,5]]); // 2D primitives: var shape2 = CAG.circle({center: [-2, -2], radius: 4, resolution: 20}); var shape3 = CAG.rectangle({center: [5, -2], radius: [2, 3]}); var shape4 = CAG.rectangle({corner1: [-10, 20], corner2: [15, -30]}); var shape5 = CAG.roundedRectangle({center: [5, 7], radius: [4, 4], roundradius: 1, resolution: 24}); var shape6 = CAG.roundedRectangle({corner1: [-2, 3], corner2: [4, -4], roundradius: 1, resolution: 24}); // Expand one of the shapes: first parameter is expand radius, second is the resolution: shape1 = shape1.expand(1, 20); var shape = shape1.union([shape2, shape3, shape4]); // Do some transformations: shape.center(); shape=shape.translate([-2, -2]); shape=shape.rotateZ(20); shape=shape.scale([0.7, 0.9]); // And extrude. This creates a CSG solid: var extruded = shape.extrude({ offset: [0.5, 0, 10], // direction for extrusion twistangle: 30, // top surface is rotated 30 degrees twiststeps: 10 // create 10 slices }); // extrude such that the 2D x coordinate maps to the 3D negated z coordinate, // and the 2D y coordinate maps to the 3D x coordinate: var extruded2 = shape.extrudeInPlane("-Z","X", 10); // extrude by rotation around y-axis at the origin. // Note: for this to work, shape shouldn't have point in negative x space var shapeX = shape.translate([20, 0]); var rotExtruded = shapeX.rotateExtrude({ angle: 210, // degrees of rotation; 360 deg if left out resolution: 200 // resolution, optional }); var cube2d = CSG.cube({radius: 10}).rotateZ(45); var z0basis = CSG.OrthoNormalBasis.Z0Plane(); var cag = cube2d.sectionCut(z0basis); // or: var cag = cube2d.projectToOrthoNormalBasis(z0basis);Using a CNC router it's impossible to cut out a true sharp inside corner. The inside corner will be rounded due to the radius of the cutter. The CAG.overCutInsideCorners(radius) function compensates for this by creating an extra cutout at each inner corner so that the actual cut out shape will be at least as large as needed:
var r1=CAG.rectangle({center:[0,0], radius: 4}); var r2=CAG.rectangle({center:[2,0], radius: 2}); var r3=r1.subtract(r2); var cutterradius=1; var r4=r3.overCutInsideCorners(cutterradius); return r4;For an example of 2D shapes see the Parametric S hook example.
var path = new CSG.Path2D([[10,10], [-10,10]], /* closed = */ false); var anotherpath = new CSG.Path2D([[-10,-10]]); path = path.concat(anotherpath); path = path.appendPoint([10,-10]); path = path.close(); // close the path // of course we could simply have done: // var path = new CSG.Path2D([[10,10], [-10,10], [-10,-10], [10,-10]], /* closed = */ true); // We can make arcs and circles. Two methods are provided: // arc() creates an circular segment with a specified center and radius: var curvedpath = CSG.Path2D.arc({ center: [0,0,0], radius: 10, startangle: 0, endangle: 180, resolution: 16, }); // or appendArc() can be used to create a circular or elliptical segment between two endpoints. // appendArc() closely follows the SVG arc specification: // http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands // The starting point for the arc is the current endpoint of the path // path2d = path2d.appendArc(endpoint, options); // endpoint is the destination coordinate // options: // .resolution // smoothness of the arc (number of segments per 360 degree of rotation) // to create a circular arc: // .radius // to create an elliptical arc: // .xradius // .yradius // .xaxisrotation // the rotation (in degrees) of the x axis of the ellipse with respect // // to the x axis of our coordinate system // this still leaves 4 possible arcs between the two given points. The following two flags select which one we draw: // .clockwise // = true | false (default is false). Two of the 4 solutions draw clockwise with respect to // // the center point, the other 2 counterclockwise // .large // = true | false (default is false). Two of the 4 solutions are an arc longer than 180 // // degrees, the other two are <= 180 degrees var curvedpath2 = new CSG.Path2D([[0,0], [10,0]]); // create an elliptical arc from [10,0] to [15,0]: curvedpath2 = curvedpath2.appendArc([15,0], { xradius: 4, yradius: -6, xaxisrotation: 30, resolution: 48, clockwise: false, large: true, }); // Extrude the path by following it with a rectangle (upright, perpendicular to the path direction) // Returns a CSG solid // width: width of the extrusion, in the z=0 plane // height: height of the extrusion in the z direction // resolution: number of segments per 360 degrees for the curve in a corner // roundEnds: if true, the ends of the polygon will be rounded, otherwise they will be flat var csg = path.rectangularExtrude(3, 4, 16, true); return csg;
path2d.appendBezier(controlpoints[, options]) - create a single Bézier segment controlpoints: an array of control points. Each control point is a 2d coordinate (can be an [x,y] array or a CSG.Vector2D). The Bézier curve starts at the last point in the existing path2d (hence path2d must not be empty), and ends at the last given control point. Other control points are intermediate control points. The first control point may be null. In that case a smooth transition is ensured: the null control point is replaced by the second last control point of the previous Bézier curve mirrored into the starting point of this curve. In other words the incoming gradient matches the outgoing gradient at the current starting point. options: an optional object. Currently only one option is supported: resolution: controls the smoothness of the curve: at least this number of segments will be used per 360 degree rotation. If omitted, CSG.defaultResolution2D will be used.An example:
var path=new CSG.Path2D([[0,0]]); // beware of the double array: we must pass an array of 2d coordinates // bezier curve from [0,0] to [10,10] // with 3 intermediate control points so it is a 3rd order bezier // Since we do not give a resolution option, CSG.defaultResolution2D is used to determine the number of vertices path = path.appendBezier([[2,8], [5,0], [8,6], [10,10]]); // cubic bezier curve from [10,10] to [10,0] // first control point is null: this forces a smooth transition from the previous bezier curve // In this case the null control point will be replaced by [10,10]+([10,10]-[8,6]) = [12,14] // i.e. the last control point will be mirrored // Here we give the optional options object, setting a resolution of 24 steps per 360 degree of revolution // So the angle between each subsequent side is guaranteed to be less than 15 degrees path = path.appendBezier([null, [10,0]], {resolution: 24}); // close the path and convert to a solid 2D shape: path = path.close(); var cag = path.innerToCAG(); return cag;
// objective: place a cag (cagFunc or static cag) along a list of connectors. // cover the resulting skeleton with polygons to create the resulting CSG // The basics work like this: // create dynamic cag as function(connector) var cagFunc = function(point, axis, normal) { return CAG.circle({radius: Math.abs((point.x-8)/10+point.length()) + 0.01}); }; // connector list var cs = new CSG.ConnectorList(); for (var i = 0; i < 10; i++) { cs.appendConnector( new CSG.Connector([i, -i, 0], [1, -i/5, i/6], [0, 1, 0]) ); } // create resulting CSG return cs.followWith(cagFunc); // To ease creating curved ConnectorLists etc., we can make one from a Path2D. var curvedpath = CSG.Path2D.arc({ center: [0,0,0], radius: 10, startangle: 0, endangle: 180, resolution: 50 }); // When creating a ConnectorList from this, it knows the points and will turn them // into 3d points by adding a 0 z height. // Then there are 2 ways to add corresponding axisvectors that define the CAG direction: // This signature calculates pseudo-tangents for the axisvectors. Only the first and the // last axisvector have to be manually given, as tangents for these cannot be found var cs2 = CSG.ConnectorList.fromPath2D(curvedpath, [0, 1, 0], [0, -1, 0]); var csg = cs2.followWith(CAG.rectangle()); return csg; // Or if there are special requirements on the directions, these can be provided using // a function var cs3 = CSG.ConnectorList.fromPath2D(curvedpath, function(pt, i) { return pt.angleDegrees() + 90; }); return cs3.followWith(CAG.circle());
{ name: 'width', type: 'float', // or 'text', 'int', 'longtext', 'bool' initial: 1.23, // optional, sets the initial value // 'default': 1.23 // this is still supported for backward compatibility but deprecated ('default' is a Javascript keyword) caption: 'Width of the thingy:', // optional, displayed left of the input field // if omitted, the 'name' is displayed (i.e. 'width') }A 'choice' parameter is created using the following object:
{ name: 'shape', type: 'choice', values: ["TRI", "SQU", "CIR"], // these are the values that will be supplied to your script captions: ["Triangle", "Square", "Circle"], // optional, these values are shown in the listbox // if omitted, the items in the 'values' array are used caption: 'Shape:', // optional, displayed left of the input field initial: "SQU", // optional, default selected value // if omitted, the first item is selected by default }To use the values add an argument to your main() function. This argument will be supplied an object with the user edited parameter values:
function main(params) { // custom error checking: if(params.width <= 0) throw new Error("Width should be positive!"); if(params.shape == "TRI") { // do something } }A complete example. Copy/paste it into the Playground at the top of this page to see how it works:
function getParameterDefinitions() { return [ { name: 'width', type: 'float', initial: 10, caption: "Width of the cube:", }, { name: 'height', type: 'float', initial: 14, caption: "Height of the cube:", }, { name: 'depth', type: 'float', initial: 7, caption: "Depth of the cube:", }, { name: 'rounded', type: 'choice', caption: 'Round the corners?', values: [0, 1], captions: ["No thanks", "Yes please"], initial: 1, }, ]; } function main(params) { var result; if(params.rounded == 1) { result = CSG.roundedCube({radius: [params.width, params.height, params.depth], roundradius: 2, resolution: 32}); } else { result = CSG.cube({radius: [params.width, params.height, params.depth]}); } return result; }Or see the Involute Gears example for another example of interactive parameters.
function main() { var mycube = CSG.cube({radius: 10}); var mycircle = CAG.circle({radius: 10}); // we could just do: // return [mycube, mycircle]; // give each element a description and filename: return [ { name: "cube", // optional, will be used as a prefix for the downloaded stl file caption: "A small cube", // will be shown in the dropdown box data: mycube, }, { name: "circle", // optional, will be used as a prefix for the downloaded dxf file caption: "Circle", data: mycircle, }, ]; }If more than 1 object is returned, a dropdown box is displayed for selecting the part to be displayed and/or downloaded. The jscad is not re-rendered so switching between parts happens fast.
function main() { return CSG.cube({radius: 10}); }
// construct a plane: var plane = CSG.Plane.fromNormalAndPoint([1,1,0], [0,0,1]); var orthobasis = new CSG.OrthoNormalBasis(plane); // or if we would like a specific right hand vector: // var orthobasis = new CSG.OrthoNormalBasis(plane, [0,0,1]); var point3d = new CSG.Vector3D(1,5,7); var point2d = orthobasis.to2D(point3d); var projected = orthobasis.to3D(point2d);
function main() { var cube = CSG.cube({radius: 1}); // var volume = cube.getFeatures("volume"); // var area = cube.getFeatures("area"); var features = cube.getFeatures(["volume","area"]); var volume = features[0]; var area = features[1]; OpenJsCad.log("volume: "+volume+"; area: "+area); // volume: 8; area: 24 return cube; }
var cube1 = CSG.cube({radius: 10}); cube1 = cube1.setColor([0.5, 0, 0]); var cube2 = CSG.cube({radius: 10}); cube2 = cube2.setColor([0, 0.5, 0]); cube2 = cube2.translate([5,1,4]); var result = cube1.subtract(cube2); // the resulting solid will have faces with 2 different colors
// --------- Vector3D --------------------- var vec1 = new CSG.Vector3D(1,2,3); // 3 arguments var vec2 = new CSG.Vector3D( [1,2,3] ); // 1 array argument var vec3 = new CSG.Vector3D(vec2); // cloning a vector // get the values as: vec1.x, vec.y, vec1.z // vector math. All operations return a new vector, the original is unmodified! // vectors cannot be modified. Instead you should create a new vector. vec.negated() vec.abs() vec.plus(othervector) vec.minus(othervector) vec.times(3.0) vec.dividedBy(-5) vec.dot(othervector) vec.lerp(othervector, t) // linear interpolation (0 <= t <= 1) vec.length() vec.lengthSquared() // == vec.length()^2 vec.unit() vec.cross(othervector) // cross product: returns a vector perpendicular to both vec.distanceTo(othervector) vec.distanceToSquared(othervector) // == vec.distanceTo(othervector)^2 vec.equals(othervector) vec.multiply4x4(matrix4x4) // right multiply by a 4x4 matrix vec.min(othervector) // returns a new vector with the minimum x,y and z values vec.max(othervector) // returns a new vector with the maximum x,y and z values // --------- Vector2D --------------------- var vec1 = new CSG.Vector2D(1,2); // 2 arguments var vec2 = new CSG.Vector2D( [1,2] ); // 1 array argument var vec3 = new CSG.Vector2D(vec2); // cloning a vector // vector math. All operations return a new vector, the original is unmodified! vec.negated() vec.abs() vec.plus(othervector) vec.minus(othervector) vec.times(3.0) vec.dividedBy(-5) vec.dot(othervector) vec.lerp(othervector, t) // linear interpolation (0 <= t <= 1) vec.length() vec.lengthSquared() // == vec.length()^2 vec.unit() vec.normal() // returns a 90 degree clockwise rotated vector vec.distanceTo(othervector) vec.distanceToSquared(othervector) // == vec.distanceTo(othervector)^2 vec.cross(othervector) // 2D cross product: returns a scalar vec.equals(othervector) vec.min(othervector) // returns a new vector with the minimum x and y values vec.max(othervector) // returns a new vector with the maximum x and y values vec.multiply4x4(matrix4x4) // right multiply by a 4x4 matrix vec.toVector3D(z) // convert to a vector3D by adding a z coordinate vec.angleDegrees() // returns the angle of the vector: [1,0] = 0 degrees, [0, 1] = 90 degrees, etc vec.angleRadians() // ditto in radians var vec = CSG.Vector2D.fromAngleDegrees(degrees); // returns a vector at the specified angle var vec = CSG.Vector2D.fromAngleRadians(radians); // returns a vector at the specified angle // --------- Matrix4x4 --------------------- var m1 = new CSG.Matrix4x4(); // unity matrix var m2 = new CSG.Matrix4x4( [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] ); // elements are passed in row order var result = m1.plus(m2); var result = m1.minus(m2); var result = m1.multiply(m2); // matrix vector multiplication (vectors are padded with zeroes to get a 4x1 vector): var vec3d = m1.rightMultiply1x3Vector(vec3d); // matrix * vector var vec3d = m1.leftMultiply1x3Vector(vec3d); // vector * matrix var vec2d = m1.rightMultiply1x2Vector(vec2d); // matrix * vector var vec2d = m1.leftMultiply1x2Vector(vec2d); // vector * matrix // common transformation matrices: var m = CSG.Matrix4x4.rotationX(degrees); // matrix for rotation about X axis var m = CSG.Matrix4x4.rotationY(degrees); // matrix for rotation about Y axis var m = CSG.Matrix4x4.rotationZ(degrees); // matrix for rotation about Z axis var m = CSG.Matrix4x4.rotation(rotationCenter, rotationAxis, degrees); // rotation about arbitrary point and axis var m = CSG.Matrix4x4.translation(vec3d); // translation var m = CSG.Matrix4x4.scaling(vec3d); // scale var m = CSG.Matrix4x4.mirroring(plane); // mirroring in a plane; the argument must be a CSG.Plane // matrix transformations can be concatenated: var transform = CSG.Matrix4x4.rotationX(20).multiply(CSG.Matrix4x4.rotationY(30)); // Use a CSG solid's transform() method to apply the transformation to a CSG solid // ------------ Plane -------------------------- // a 3D plane is represented by a normal vector (should have unit length) and a distance from the origin w // the plane passes through normal.times(w) var plane1 = new CSG.Plane(normal, w); // Or we can construct a plane from 3 points: var plane2 = CSG.Plane.fromPoints(p1, p2, p3); // Or from a normal vector and 1 point: var plane3 = CSG.Plane.fromNormalAndPoint(normal, point); // Flip a plane (front side becomes back side): var plane4 = plane3.flipped(); // Apply transformations (rotation, scaling, translation): var transformed = plane3.transformed(matrix4x4); // argument is a CSG.Matrix4x4 // Intersection of plane and 3d line: var point = plane3.intersectWithLine(line); // argument is CSG.Line3D, returns a CSG.Vector3D // Intersection of 2 planes: var line = plane3.intersectWithPlane(plane); // argument is another CSG.Plane, returns a CSG.Line3D // Distance to point: var w = signedDistanceToPoint(point); // argument is CSG.Vector3D, returns a float (positive // if in front of plane, negative if in back) // ------------ Line3D -------------------------- // A line in 3d space is represented by a point and a direction vector. // Direction should be a unit vector. Point can be any point on the line: var line = new CSG.Line3D(point, direction); // argumenst are CSG.Vector3D // or by giving two points: var line = CSG.Line3D.fromPoints(p1, p2); // argumenst are CSG.Vector3D var point = intersectWithPlane(plane); // == plane.intersectWithLine(this) var line2 = line.reverse(); // same line but reverse direction var line2 = line.transform(matrix4x4); // for rotation, scaling, etc var p = line.closestPointOnLine(point); // project point onto the line var d = line.distanceToPoint(point); // ------------ Line2D -------------------------- // A line in 2d space is represented by a normal vector and a distance w to the // origin along the normal vector // A line in 2d space is represented by a point and a direction vector. // Direction should be a unit vector. Point can be any point on the line: var line = new CSG.Line2D(CSG.Line2D(normal,w)); // or by giving two points: var line = CSG.Line2D.fromPoints(p1, p2); // argumenst are CSG.Vector2D var line2 = line.reverse(); // same line but reverse direction var line2 = line.transform(matrix4x4); // for rotation, scaling, etc var point = line.origin(); // returns the point closest to the origin var dir = line.direction(); // direction vector (CSG.Vector2D) var x = line.xAtY(y); // returns the x coordinate of the line at given y coordinate var d = absDistanceToPoint(point); // returns the absolute distance between a point and the line var p = line.closestPoint(point); // projection of point onto the line var point = line.intersectWithLine(line2); // intersection of two lines, returns CSG.Vector2D