📄 boundingpolytope.java
字号:
/* * $RCSfile: BoundingPolytope.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.8 $ * $Date: 2007/04/12 17:34:04 $ * $State: Exp $ */package javax.media.j3d;import javax.vecmath.*;import java.lang.Math;import com.sun.j3d.internal.HashCodeUtil;/** * A BoundingPolytope defines a polyhedral bounding region using the * intersection of four or more half spaces. The region defined by a * BoundingPolytope is always convex and must be closed. * <p> * Each plane in the BoundingPolytope specifies a half-space defined * by the equation: * <ul> * Ax + By + Cz + D <= 0 * </ul> * where A, B, C, D are the parameters that specify the plane. The * parameters are passed in the x, y, z, and w fields, respectively, * of a Vector4d object. The intersection of the set of half-spaces * corresponding to the planes in this BoundingPolytope defines the * bounding region. */public class BoundingPolytope extends Bounds { /** * An array of bounding planes. */ Vector4d[] planes; double[] mag; // magnitude of plane vector double[] pDotN; // point on plane dotted with normal Point3d[] verts; // vertices of polytope int nVerts; // number of verts in polytope Point3d centroid = new Point3d(); // centroid of polytope Point3d boxVerts[]; boolean allocBoxVerts = false; /** * Constructs a BoundingPolytope using the specified planes. * @param planes a set of planes defining the polytope. * @exception IllegalArgumentException if the length of the * specified array of planes is less than 4. */ public BoundingPolytope(Vector4d[] planes) { if (planes.length < 4) { throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope11")); } boundId = BOUNDING_POLYTOPE; int i; double invMag; this.planes = new Vector4d[planes.length]; mag = new double[planes.length]; pDotN = new double[planes.length]; for(i=0;i<planes.length;i++) { // normalize the plane normals mag[i] = Math.sqrt(planes[i].x*planes[i].x + planes[i].y*planes[i].y + planes[i].z*planes[i].z); invMag = 1.0/mag[i]; this.planes[i] = new Vector4d( planes[i].x*invMag, planes[i].y*invMag, planes[i].z*invMag, planes[i].w*invMag ); } computeAllVerts(); // XXXX: lazy evaluate } /** * Constructs a BoundingPolytope and initializes it to a set of 6 * planes that defines a cube such that -1 <= x,y,z <= 1. The * values of the planes are as follows: * <ul> * planes[0] : x <= 1 (1,0,0,-1)<br> * planes[1] : -x <= 1 (-1,0,0,-1)<br> * planes[2] : y <= 1 (0,1,0,-1)<br> * planes[3] : -y <= 1 (0,-1,0,-1)<br> * planes[4] : z <= 1 (0,0,1,-1)<br> * planes[5] : -z <= 1 (0,0,-1,-1)<br> * </ul> */ public BoundingPolytope() { boundId = BOUNDING_POLYTOPE; planes = new Vector4d[6]; mag = new double[planes.length]; pDotN = new double[planes.length]; planes[0] = new Vector4d( 1.0, 0.0, 0.0, -1.0 ); planes[1] = new Vector4d(-1.0, 0.0, 0.0, -1.0 ); planes[2] = new Vector4d( 0.0, 1.0, 0.0, -1.0 ); planes[3] = new Vector4d( 0.0,-1.0, 0.0, -1.0 ); planes[4] = new Vector4d( 0.0, 0.0, 1.0, -1.0 ); planes[5] = new Vector4d( 0.0, 0.0,-1.0, -1.0 ); mag[0] = 1.0; mag[1] = 1.0; mag[2] = 1.0; mag[3] = 1.0; mag[4] = 1.0; mag[5] = 1.0; computeAllVerts(); // XXXX: lazy evaluate } /** * Constructs a BoundingPolytope from the specified bounds object. * The new polytope will circumscribe the region specified by the * input bounds. * @param boundsObject the bounds object from which this polytope * is constructed. */ public BoundingPolytope(Bounds boundsObject ) { int i; boundId = BOUNDING_POLYTOPE; if( boundsObject == null ) { boundsIsEmpty = true; boundsIsInfinite = false; initEmptyPolytope(); computeAllVerts(); // XXXX: lazy evaluate return; } boundsIsEmpty = boundsObject.boundsIsEmpty; boundsIsInfinite = boundsObject.boundsIsInfinite; if( boundsObject.boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObject; planes = new Vector4d[6]; mag = new double[planes.length]; pDotN = new double[planes.length]; planes[0] = new Vector4d( 1.0, 0.0, 0.0, -(sphere.center.x+sphere.radius) ); planes[1] = new Vector4d(-1.0, 0.0, 0.0, sphere.center.x-sphere.radius ); planes[2] = new Vector4d( 0.0, 1.0, 0.0, -(sphere.center.y+sphere.radius) ); planes[3] = new Vector4d( 0.0,-1.0, 0.0, sphere.center.y-sphere.radius ); planes[4] = new Vector4d( 0.0, 0.0, 1.0, -(sphere.center.z+sphere.radius) ); planes[5] = new Vector4d( 0.0, 0.0,-1.0, sphere.center.z-sphere.radius ); mag[0] = 1.0; mag[1] = 1.0; mag[2] = 1.0; mag[3] = 1.0; mag[4] = 1.0; mag[5] = 1.0; computeAllVerts(); // XXXX: lazy evaluate } else if( boundsObject.boundId == BOUNDING_BOX ){ BoundingBox box = (BoundingBox)boundsObject; planes = new Vector4d[6]; pDotN = new double[planes.length]; mag = new double[planes.length]; planes[0] = new Vector4d( 1.0, 0.0, 0.0, -box.upper.x ); planes[1] = new Vector4d(-1.0, 0.0, 0.0, box.lower.x ); planes[2] = new Vector4d( 0.0, 1.0, 0.0, -box.upper.y ); planes[3] = new Vector4d( 0.0,-1.0, 0.0, box.lower.y ); planes[4] = new Vector4d( 0.0, 0.0, 1.0, -box.upper.z ); planes[5] = new Vector4d( 0.0, 0.0,-1.0, box.lower.z ); mag[0] = 1.0; mag[1] = 1.0; mag[2] = 1.0; mag[3] = 1.0; mag[4] = 1.0; mag[5] = 1.0; computeAllVerts(); // XXXX: lazy evaluate } else if( boundsObject.boundId == BOUNDING_POLYTOPE ) { BoundingPolytope polytope = (BoundingPolytope)boundsObject; planes = new Vector4d[polytope.planes.length]; mag = new double[planes.length]; pDotN = new double[planes.length]; nVerts = polytope.nVerts; verts = new Point3d[nVerts]; for(i=0;i<planes.length;i++) { planes[i] = new Vector4d(polytope.planes[i]); mag[i] = polytope.mag[i]; pDotN[i] = polytope.pDotN[i]; } for(i=0;i<verts.length;i++) { verts[i] = new Point3d(polytope.verts[i]); } centroid = polytope.centroid; } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope0")); } } /** * Constructs a BoundingPolytope from the specified array of bounds * objects. The new polytope will circumscribe the union of the * regions specified by the input bounds objects. * @param boundsObjects the array bounds objects from which this * polytope is constructed. */ public BoundingPolytope(Bounds[] boundsObjects) { int i=0; boundId = BOUNDING_POLYTOPE; if( boundsObjects == null || boundsObjects.length <= 0 ) { boundsIsEmpty = true; boundsIsInfinite = false; initEmptyPolytope(); computeAllVerts(); // XXXX: lazy evaluate return; } // find first non empty bounds object while( boundsObjects[i] == null && i < boundsObjects.length) { i++; } if( i >= boundsObjects.length ) { // all bounds objects were empty boundsIsEmpty = true; boundsIsInfinite = false; initEmptyPolytope(); computeAllVerts(); // XXXX: lazy evaluate return; } boundsIsEmpty = boundsObjects[i].boundsIsEmpty; boundsIsInfinite = boundsObjects[i].boundsIsInfinite; if( boundsObjects[i].boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObjects[i]; planes = new Vector4d[6]; mag = new double[planes.length]; pDotN = new double[planes.length]; planes[0] = new Vector4d( 1.0, 0.0, 0.0, -(sphere.center.x+sphere.radius) ); planes[1] = new Vector4d(-1.0, 0.0, 0.0, sphere.center.x-sphere.radius ); planes[2] = new Vector4d( 0.0, 1.0, 0.0, -(sphere.center.y+sphere.radius) ); planes[3] = new Vector4d( 0.0,-1.0, 0.0, sphere.center.y-sphere.radius ); planes[4] = new Vector4d( 0.0, 0.0, 1.0, -(sphere.center.z+sphere.radius) ); planes[5] = new Vector4d( 0.0, 0.0,-1.0, sphere.center.z-sphere.radius ); mag[0] = 1.0; mag[1] = 1.0; mag[2] = 1.0; mag[3] = 1.0; mag[4] = 1.0; mag[5] = 1.0; computeAllVerts(); // XXXX: lazy evaluate } else if( boundsObjects[i].boundId == BOUNDING_BOX ){ BoundingBox box = (BoundingBox)boundsObjects[i]; planes = new Vector4d[6]; mag = new double[planes.length]; pDotN = new double[planes.length]; planes[0] = new Vector4d( 1.0, 0.0, 0.0, -box.upper.x ); planes[1] = new Vector4d(-1.0, 0.0, 0.0, box.lower.x ); planes[2] = new Vector4d( 0.0, 1.0, 0.0, -box.upper.y ); planes[3] = new Vector4d( 0.0,-1.0, 0.0, box.lower.y ); planes[4] = new Vector4d( 0.0, 0.0, 1.0, -box.upper.z ); planes[5] = new Vector4d( 0.0, 0.0,-1.0, box.lower.z ); mag[0] = 1.0; mag[1] = 1.0; mag[2] = 1.0; mag[3] = 1.0; mag[4] = 1.0; mag[5] = 1.0; computeAllVerts(); // XXXX: lazy evaluate } else if( boundsObjects[i].boundId == BOUNDING_POLYTOPE ) { BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i]; planes = new Vector4d[polytope.planes.length]; mag = new double[planes.length]; pDotN = new double[planes.length]; nVerts = polytope.nVerts; verts = new Point3d[nVerts]; for(i=0;i<planes.length;i++) { planes[i] = new Vector4d(polytope.planes[i]); pDotN[i] = polytope.pDotN[i]; mag[i] = polytope.mag[i]; } for(i=0;i<verts.length;i++) { verts[i] = new Point3d(polytope.verts[i]); } centroid = polytope.centroid; } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope1")); } for(i+=1;i<boundsObjects.length;i++) { this.combine(boundsObjects[i]); } } /** * Sets the bounding planes for this polytope. * @param planes the new set of planes for this polytope * @exception IllegalArgumentException if the length of the * specified array of planes is less than 4. */ public void setPlanes(Vector4d[] planes) { if (planes.length < 4) { throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope11")); } int i; double invMag; this.planes = new Vector4d[planes.length]; pDotN = new double[planes.length]; mag = new double[planes.length]; boundsIsEmpty = false; if( planes.length <= 0 ) { boundsIsEmpty = true; boundsIsInfinite = false; computeAllVerts(); // XXXX: lazy evaluate return; } for(i=0;i<planes.length;i++) { // normalize the plane normals mag[i] = Math.sqrt(planes[i].x*planes[i].x + planes[i].y*planes[i].y + planes[i].z*planes[i].z); invMag = 1.0/mag[i]; this.planes[i] = new Vector4d( planes[i].x*invMag, planes[i].y*invMag, planes[i].z*invMag, planes[i].w*invMag ); } computeAllVerts(); // XXXX: lazy evaluate } /** * Returns the equations of the bounding planes for this bounding polytope. * The equations are copied into the specified array. * The array must be large enough to hold all of the vectors. * The individual array elements must be allocated by the caller. * @param planes an array Vector4d to receive the bounding planes */ public void getPlanes(Vector4d[] planes) { int i; for(i=0;i<planes.length;i++) { planes[i].x = this.planes[i].x*mag[i]; planes[i].y = this.planes[i].y*mag[i]; planes[i].z = this.planes[i].z*mag[i]; planes[i].w = this.planes[i].w*mag[i]; } } public int getNumPlanes() { return planes.length; } /** * Sets the planes for this BoundingPolytope by keeping its current * number and position of planes and computing new planes positions * to enclose the given bounds object. * @param boundsObject another bounds object */ public void set(Bounds boundsObject) { int i,k; double dis; // no polytope exists yet so initialize one using the boundsObject if( boundsObject == null ) { boundsIsEmpty = true; boundsIsInfinite = false; computeAllVerts(); // XXXX: lazy evaluate }else if( boundsObject.boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObject; if( boundsIsEmpty) { initEmptyPolytope(); // no ptope exist so must initialize to default computeAllVerts(); } for(i=0;i<planes.length;i++) { // D = -(N dot C + radius) planes[i].w = -(sphere.center.x*planes[i].x + sphere.center.y*planes[i].y + sphere.center.z*planes[i].z + sphere.radius); } boundsIsEmpty = boundsObject.boundsIsEmpty; boundsIsInfinite = boundsObject.boundsIsInfinite; computeAllVerts(); // XXXX: lazy evaluate } else if( boundsObject.boundId == BOUNDING_BOX){ BoundingBox box = (BoundingBox)boundsObject; double ux,uy,uz,lx,ly,lz,newD; if( boundsIsEmpty) { initEmptyPolytope(); // no ptope exist so must initialize to default computeAllVerts(); } for(i=0;i<planes.length;i++) { ux = box.upper.x*planes[i].x; uy = box.upper.y*planes[i].y; uz = box.upper.z*planes[i].z; lx = box.lower.x*planes[i].x; ly = box.lower.y*planes[i].y; lz = box.lower.z*planes[i].z; planes[i].w = -(ux + uy + uz ); // initalize plane to upper vert if( (newD = ux + uy + lz ) + planes[i].w > 0.0) planes[i].w = -newD; if( (newD = ux + ly + uz ) + planes[i].w > 0.0) planes[i].w = -newD; if( (newD = ux + ly + lz ) + planes[i].w > 0.0) planes[i].w = -newD; if( (newD = lx + uy + uz ) + planes[i].w > 0.0) planes[i].w = -newD; if( (newD = lx + uy + lz ) + planes[i].w > 0.0) planes[i].w = -newD; if( (newD = lx + ly + uz ) + planes[i].w > 0.0) planes[i].w = -newD; if( (newD = lx + ly + lz ) + planes[i].w > 0.0) planes[i].w = -newD; } boundsIsEmpty = boundsObject.boundsIsEmpty; boundsIsInfinite = boundsObject.boundsIsInfinite; computeAllVerts(); // XXXX: lazy evaluate } else if(boundsObject.boundId == BOUNDING_POLYTOPE) { BoundingPolytope polytope = (BoundingPolytope)boundsObject; if( planes.length != polytope.planes.length) { planes = new Vector4d[polytope.planes.length]; for(k=0;k<polytope.planes.length;k++) planes[k] = new Vector4d(); mag = new double[polytope.planes.length]; pDotN = new double[polytope.planes.length]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -