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];
|
this.cachedBoundingBox = [minpoint, maxpoint];
|
||||||
}
|
}
|
||||||
return this.cachedBoundingBox;
|
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
|
// 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);
|
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 = {
|
CSG.Plane.prototype = {
|
||||||
flipped: function() {
|
flipped: function() {
|
||||||
return new CSG.Plane(this.normal.negated(), -this.w);
|
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);
|
var cube5 = cube.mirrored(plane);
|
||||||
</pre>
|
</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>
|
<h2>Expansion and contraction</h2>
|
||||||
Expansion can be seen
|
Expansion can be seen
|
||||||
as the 3D convolution of an object with a sphere. Contraction is the reverse: the area outside the solid
|
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