📄 _polyhedralboundedsolidface.java
字号:
null values to attributes `lastIntersectedHalfedge` and `lastIntersectedVertex`. When the point is on the border of the polygon, it can be over a vertex or over an edge. If it is on a vertex, the intersecting vertex is referenced on attribute `lastIntersectedVertex` and `lastIntersectedHalfedge` is leaved null. Otherwise, when point intersects an edge, the intersected edge is referenced at `lastIntersectedHalfedge`, and `lastIntersectedVertex` is leaved null. Altough should be seldom of a problem, note the decribed mechanism for quering extra border intersection is not re-entrant (thread safe) for current face. */ public int testPointInside(Vector3D p, double tolerance) { int nc; // Number of crossings int sh; // Sign holder for vertex crossings int nsh; // Next sign holder for vertex crossings lastIntersectedHalfedge = null; lastIntersectedVertex = null; //----------------------------------------------------------------- //- 1. For all vertices in face, project them in to dominant //- coordinate's plane ArrayListOfDoubles polygon2Du = new ArrayListOfDoubles(100); ArrayListOfDoubles polygon2Dv = new ArrayListOfDoubles(100); ArrayList<_PolyhedralBoundedSolidHalfEdge> polygon2Dh; ArrayList<_PolyhedralBoundedSolidVertex> polygon2Dvv; double u, v; Vector3D projectedPoint = new Vector3D(); int dominantCoordinate = 3; int i; Vector3D n; polygon2Dh = new ArrayList<_PolyhedralBoundedSolidHalfEdge>(); polygon2Dvv = new ArrayList<_PolyhedralBoundedSolidVertex>(); n = containingPlane.getNormal(); if ( Math.abs(n.x) >= Math.abs(n.y) && Math.abs(n.x) >= Math.abs(n.z) ) { dominantCoordinate = 1; } else if ( Math.abs(n.y) >= Math.abs(n.x) && Math.abs(n.y) >= Math.abs(n.z) ) { dominantCoordinate = 2; } else { dominantCoordinate = 3; } _PolyhedralBoundedSolidHalfEdge he; for ( i = 0; i < boundariesList.size(); i++ ) { _PolyhedralBoundedSolidLoop loop; _PolyhedralBoundedSolidHalfEdge heStart, heOld; loop = boundariesList.get(i); he = loop.boundaryStartHalfEdge; if ( he == null ) { // Loop without starting halfedge return Geometry.OUTSIDE; } heStart = he; do { if ( VSDK.vectorDistance(p, he.startingVertex.position) < 2*tolerance ) { lastIntersectedVertex = he.startingVertex; return Geometry.LIMIT; } dropCoordinate(he.startingVertex.position, projectedPoint, dominantCoordinate); polygon2Du.append(projectedPoint.x); polygon2Dv.append(projectedPoint.y); polygon2Dh.add(he); heOld = he; polygon2Dvv.add(he.startingVertex); he = he.next(); if ( he == null ) { // Loop is not closed! return Geometry.OUTSIDE; } dropCoordinate(he.startingVertex.position, projectedPoint, dominantCoordinate); polygon2Du.append(projectedPoint.x); polygon2Dv.append(projectedPoint.y); polygon2Dvv.add(he.startingVertex); if ( VSDK.vectorDistance(p, he.startingVertex.position) < 2*tolerance ) { lastIntersectedVertex = he.startingVertex; return Geometry.LIMIT; } if ( ComputationalGeometry.lineSegmentContainmentTest( heOld.startingVertex.position, he.startingVertex.position, p, tolerance ) == Geometry.LIMIT ) { lastIntersectedHalfedge = heOld; return Geometry.LIMIT; } } while( he != heStart ); } dropCoordinate(p, projectedPoint, dominantCoordinate); u = projectedPoint.x; v = projectedPoint.y; //----------------------------------------------------------------- //- 2. Translate the 2D polygon such that the intersection point is //- in the origin for ( i = 0; i < polygon2Du.size; i++ ) { polygon2Du.array[i] -= u; polygon2Dv.array[i] -= v; } nc = 0; //----------------------------------------------------------------- //- 3. Iterate edges double ua, va, ub, vb; _PolyhedralBoundedSolidVertex vva, vvb; for ( i = 0; i < polygon2Du.size - 1; i += 2 ) { // This iteration tests the line segment (ua, va) - (ub, vb) ua = polygon2Du.array[i]; va = polygon2Dv.array[i]; ub = polygon2Du.array[i+1]; vb = polygon2Dv.array[i+1]; he = polygon2Dh.get(i/2); vva = polygon2Dvv.get(i); vvb = polygon2Dvv.get(i+1); // Note that testing line is (y = 0), so "segment crossed" can be // detected as a sign change in the v dimension. // First, calculate the va and vb signs in sh and nsh respectively if ( va < 0 ) { sh = -1; } else { sh = 1; } if ( vb < 0 ) { nsh = -1; } else { nsh = 1; } // If a sign change in the v dimension occurs, then report cross... if ( sh != nsh ) { // But taking into account the special case crossing occurring // over a vertex if ( ua >= 0 && ub >= 0 ) { nc++; } else if ( ua >= 0 || ub >= 0 ) { if ( ua - va*(ub-ua)/(vb - va) > 0 ) { nc++; } } } } if ( (nc % 2) == 1 ) { return Geometry.INSIDE; } return Geometry.OUTSIDE; } /** Current implementation only takes into account the containing plane. @return 1 if this face is visible from camera c, -1 if is not visible and 0 if is tangent to it. @todo: generalize to plane. This is returning "1" in cases where should return "-1". */ public int isVisibleFrom(Camera c) { Vector3D iv = new Vector3D(1, 0, 0); Vector3D viewingVector; viewingVector = c.getRotation().multiply(iv); Vector3D n = containingPlane.getNormal(); Vector3D cp, t; n.normalize(); double dot; int i; Vector3D p; if ( c.getProjectionMode() == c.PROJECTION_MODE_ORTHOGONAL ) { viewingVector.normalize(); dot = n.dotProduct(viewingVector); if ( dot > VSDK.EPSILON ) { return -1; } else if ( dot > VSDK.EPSILON ) { return 1; } else return 0; } else { cp = c.getPosition(); _PolyhedralBoundedSolidLoop l; for ( i = 0; i < boundariesList.size(); i++ ) { //System.out.println(" - Testing boundary " + i + " of " + boundariesList.size()); l = boundariesList.get(i); _PolyhedralBoundedSolidHalfEdge he, heStart; he = l.boundaryStartHalfEdge; heStart = he; do { // Logic he = he.next(); if ( he == null ) { // Loop is not closed! break; } // Calculate containing plane equation for current edge p = he.startingVertex.position; //System.out.println(" . Testing point " + p); t = p.substract(cp); t = t.multiply(-1); t.normalize(); //System.out.println(" -> Viewing point " + t); if ( t.dotProduct(n) > 0.0 ) { return 1; //System.out.println(" * Face in"); } } while( he != heStart ); } //System.out.println(" * Face out"); return -1; } } public void revert() { int i; for ( i = 0; i < boundariesList.size(); i++ ) { boundariesList.get(i).revert(); } } public String toString() { String msg; msg = "Face id [" + id + "], " + boundariesList.size() + " loops."; return msg; }}//===========================================================================//= EOF =//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -