diff --git a/csg.js b/csg.js index 83f0edf..01fc9fa 100644 --- a/csg.js +++ b/csg.js @@ -320,6 +320,38 @@ CSG.prototype = { return result; } }, + + // returns an array of two CSG.Vector3Ds (minimum coordinates and maximum coordinates) + getBounds: function() { + if(!this.cachedBoundingBox) + { + var minpoint = new CSG.Vector3D(0,0,0); + var maxpoint = new CSG.Vector3D(0,0,0); + var polygons = this.polygons; + var numpolygons = polygons.length; + for(var i=0; i < numpolygons; i++) + { + var polygon = polygons[i]; + var bounds = polygon.boundingBox(); + if(i == 0) + { + minpoint = bounds[0].clone(); + maxpoint = bounds[1].clone(); + } + else + { + minpoint.x = Math.min(minpoint.x, bounds[0].x); + minpoint.y = Math.min(minpoint.y, bounds[0].y); + minpoint.z = Math.min(minpoint.z, bounds[0].z); + maxpoint.x = Math.max(maxpoint.x, bounds[1].x); + maxpoint.y = Math.max(maxpoint.y, bounds[1].y); + maxpoint.z = Math.max(maxpoint.z, bounds[1].z); + } + } + this.cachedBoundingBox = [minpoint, maxpoint]; + } + return this.cachedBoundingBox; + } }; // Parse an option from the options object @@ -874,11 +906,18 @@ CSG.Plane = function(normal, w) { // point is on the plane. CSG.Plane.EPSILON = 1e-5; -CSG.Plane.fromPoints = function(a, b, c) { +CSG.Plane.fromVector3Ds = function(a, b, c) { var n = b.minus(a).cross(c.minus(a)).unit(); return new CSG.Plane(n, n.dot(a)); }; +CSG.Plane.fromPoints = function(a, b, c) { + a = new CSG.Vector3D(a); + b = new CSG.Vector3D(b); + c = new CSG.Vector3D(c); + return CSG.Plane.fromVector3Ds(a, b, c); +}; + CSG.Plane.prototype = { flipped: function() { return new CSG.Plane(this.normal.negated(), -this.w); @@ -1119,7 +1158,7 @@ CSG.Polygon = function(vertices, shared, plane) { } else { - this.plane = CSG.Plane.fromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos); + this.plane = CSG.Plane.fromVector3Ds(vertices[0].pos, vertices[1].pos, vertices[2].pos); } if(_CSGDEBUG) diff --git a/index.html b/index.html index 69cec19..91f969a 100644 --- a/index.html +++ b/index.html @@ -283,7 +283,25 @@ var csg = cube1.subtract(cube2); var rounded = csg.expand(0.2, 8); -

2d shapes

+

Determining the bounds of an object

+The getBounds() function can be used to retrieve the bounding box of an object. +This can be useful if you want to align two objects to each other. getBounds() returns +an array with two elements specifying the minimum x,y,z coordinate and the maximum x,y,z coordinate: + +
+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]);
+
+return cube1.union(cube2);
+
+ +

2D shapes

Two dimensional shapes can be defined through the Polygon2D class. Currently this requires the polygon to be convex (i.e. all corners less than 180 degrees). Shapes can be transformed (rotation, translation, scaling). To actually use the shape it needs to be extruded into a 3D CSG object through the extrude() function. extrude()