Added csg.cutByPlane() and CSG.Plane.fromNormalAndPoint()
This commit is contained in:
parent
1eac51e260
commit
5d1bc71521
46
csg.js
46
csg.js
|
@ -371,7 +371,43 @@ CSG.prototype = {
|
|||
this.cachedBoundingBox = [minpoint, maxpoint];
|
||||
}
|
||||
return this.cachedBoundingBox;
|
||||
}
|
||||
},
|
||||
|
||||
// Cut the solid by a plane. Returns the solid on the back side of the plane
|
||||
cutByPlane: function(plane) {
|
||||
// Ideally we would like to do an intersection with a polygon of inifinite size
|
||||
// but this is not supported by our implementation. As a workaround, we will create
|
||||
// a cube, with one face on the plane, and a size larger enough so that the entire
|
||||
// solid fits in the cube.
|
||||
|
||||
// find the max distance of any vertex to the center of the plane:
|
||||
var planecenter = plane.normal.times(plane.w);
|
||||
var maxdistance = 0;
|
||||
this.polygons.map(function(polygon){
|
||||
polygon.vertices.map(function(vertex){
|
||||
var distance = vertex.pos.distanceToSquared(planecenter);
|
||||
if(distance > maxdistance) maxdistance = distance;
|
||||
});
|
||||
});
|
||||
maxdistance = Math.sqrt(maxdistance);
|
||||
maxdistance *= 1.01; // make sure it's really larger
|
||||
|
||||
// Now build a polygon on the plane, at any point farther than maxdistance from the plane center:
|
||||
var vertices = [];
|
||||
var orthobasis = new CSG.OrthoNormalBasis(plane);
|
||||
vertices.push(new CSG.Vertex(orthobasis.to3D(new CSG.Vector2D(maxdistance,maxdistance))));
|
||||
vertices.push(new CSG.Vertex(orthobasis.to3D(new CSG.Vector2D(-maxdistance,maxdistance))));
|
||||
vertices.push(new CSG.Vertex(orthobasis.to3D(new CSG.Vector2D(-maxdistance,-maxdistance))));
|
||||
vertices.push(new CSG.Vertex(orthobasis.to3D(new CSG.Vector2D(maxdistance,-maxdistance))));
|
||||
var polygon = new CSG.Polygon(vertices, null, plane.flipped());
|
||||
|
||||
// and extrude the polygon into a cube, backwards of the plane:
|
||||
var cube = polygon.extrude(plane.normal.times(-maxdistance));
|
||||
|
||||
// Now we can do the intersection:
|
||||
return this.intersect(cube);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
// Parse an option from the options object
|
||||
|
@ -938,6 +974,14 @@ CSG.Plane.fromPoints = function(a, b, c) {
|
|||
return CSG.Plane.fromVector3Ds(a, b, c);
|
||||
};
|
||||
|
||||
CSG.Plane.fromNormalAndPoint = function(normal, point) {
|
||||
normal = new CSG.Vector3D(normal);
|
||||
point = new CSG.Vector3D(point);
|
||||
normal = normal.unit();
|
||||
var w = point.dot(normal);
|
||||
return new CSG.Plane(normal, w);
|
||||
};
|
||||
|
||||
CSG.Plane.prototype = {
|
||||
flipped: function() {
|
||||
return new CSG.Plane(this.normal.negated(), -this.w);
|
||||
|
|
20
index.html
20
index.html
|
@ -276,6 +276,26 @@ var plane = CSG.Plane.fromPoints([5,0,0], [5, 1, 0], [3, 1, 7]);
|
|||
var cube5 = cube.mirrored(plane);
|
||||
</pre>
|
||||
|
||||
<h2>Cutting by a plane</h2>
|
||||
A solid can be cut by a plane; only the part on the back side is kept:
|
||||
|
||||
<pre>
|
||||
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());
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Expansion and contraction</h2>
|
||||
Expansion can be seen
|
||||
as the 3D convolution of an object with a sphere. Contraction is the reverse: the area outside the solid
|
||||
|
|
Loading…
Reference in a new issue