/** * Computes the area-weighted average normal vector for this node. * @param vn array to contain the {X,Y,Z} components of the normal vector. */ public void normalVector(float[] vn) { vn[0] = vn[1] = vn[2] = 0.0f; FaceIterator fi = getFaces(); while (fi.hasNext()) { Face face = fi.next(); accNormalVector(face,vn); } float x = vn[0]; float y = vn[1]; float z = vn[2]; float s = 1.0f/(float)sqrt(x*x+y*y+z*z); vn[0] *= s; vn[1] *= s; vn[2] *= s; }
Node nodeB = (Node)meshFacei.nodeB().data; Node nodeC = (Node)meshFacei.nodeC().data; if (nodeA.isInSurface() || nodeB.isInSurface() || nodeC.isInSurface()) { faceList.add(meshFacei);
Node nodeB = edge.nodeB(); Node nodeC = otherNode(face,nodeA,nodeB); assert nodeA.isOnBoundary(); assert nodeB.isOnBoundary(); assert nodeC.isOnBoundary(); Node nodeD = nodeC.edgeAfter().nodeB(); assert nodeD.isOnBoundary(); if (nodeD.edgeAfter()==nodeA.edgeBefore()) { Edge edgeDA = nodeD.edgeAfter(); nodeA.setEdgeBefore(null); nodeD.setEdgeBefore(null); Node nodeD = nodeC.edgeBefore().nodeA(); assert nodeD.isOnBoundary(); if (nodeD.edgeBefore()==nodeB.edgeAfter()) { Edge edgeBD = nodeD.edgeBefore(); nodeB.setEdgeBefore(null); nodeD.setEdgeBefore(null);
if (!nodeC.isInSurface()) { extend(edge,face); return true; else if (nodeC.isOnBoundary()) { Node node1 = nodeC.edgeBefore().nodeA(); Node node2 = nodeC.edgeAfter().nodeB();
Node nodeB = edge.nodeB(); Node nodeC = otherNode(face,nodeA,nodeB); assert nodeA.isOnBoundary(); assert nodeB.isOnBoundary(); assert nodeC.isOnBoundary(); Node node1 = nodeC.edgeBefore().nodeA(); assert node1!=nodeA; assert node1!=nodeB; if (node1.isOnBoundary()) { Edge edgeTwin = node1.edgeAfter(); assert nodeC==edgeTwin.nodeB(); removeEdge(edgeTwin); return edgeFaceTwin; Node node2 = nodeC.edgeAfter().nodeB(); assert node2!=nodeA; assert node2!=nodeB; if (node2.isOnBoundary()) { Edge edgeTwin = node2.edgeBefore(); assert nodeC==edgeTwin.nodeA(); removeEdge(edgeTwin);
Node nodeB = edge.nodeB(); Node nodeC = otherNode(face,nodeA,nodeB); Edge edge1 = nodeC.edgeBefore(); Edge edge2 = nodeC.edgeAfter(); Node node1 = edge1.nodeA(); Node node2 = edge2.nodeB();
public void testCube() { TriSurf.Node n000 = new TriSurf.Node(0.0f,0.0f,0.0f); TriSurf.Node n001 = new TriSurf.Node(0.0f,0.0f,1.0f); TriSurf.Node n010 = new TriSurf.Node(0.0f,1.0f,0.0f); TriSurf.Node n011 = new TriSurf.Node(0.0f,1.0f,1.0f); TriSurf.Node n100 = new TriSurf.Node(1.0f,0.0f,0.0f); TriSurf.Node n101 = new TriSurf.Node(1.0f,0.0f,1.0f); TriSurf.Node n110 = new TriSurf.Node(1.0f,1.0f,0.0f); TriSurf.Node n111 = new TriSurf.Node(1.0f,1.0f,1.0f); TriSurf ts = new TriSurf(); ts.addNode(n000); ts.addNode(n001); ts.addNode(n010); ts.addNode(n011); assertEquals(2,ts.countFaces()); ts.addNode(n100); assertEquals(6,ts.countFaces()); ts.addNode(n101); ts.addNode(n110); ts.addNode(n111); assertEquals(12,ts.countFaces()); TriSurf.Node[] nodes = {n000,n001,n010,n011,n100,n101,n110,n111}; ts.removeNodes(nodes); ts.addNodes(nodes); assertEquals(12,ts.countFaces()); } }
private static void accNormalVector(Face face, float[] v) { Node na = face.nodeA(); Node nb = face.nodeB(); Node nc = face.nodeC(); float xa = na.x(); float ya = na.y(); float za = na.z(); float xb = nb.x(); float yb = nb.y(); float zb = nb.z(); float xc = nc.x(); float yc = nc.y(); float zc = nc.z(); float x0 = xc-xa; float y0 = yc-ya; float z0 = zc-za; float x1 = xa-xb; float y1 = ya-yb; float z1 = za-zb; v[0] += y0*z1-y1*z0; v[1] += x1*z0-x0*z1; v[2] += x0*y1-x1*y0; } }
/** * Computes the circumcenter of this face. * @param cc array of circumcenter coordinates {xc,yc,zc}. * @return radius-squared of circumcircle. */ public double centerCircle(double[] cc) { Node na = nodeA(); Node nb = nodeB(); Node nc = nodeC(); double xa = na.x(); double ya = na.y(); double za = na.z(); double xb = nb.x(); double yb = nb.y(); double zb = nb.z(); double xc = nc.x(); double yc = nc.y(); double zc = nc.z(); Geometry.centerCircle3D(xa,ya,za,xb,yb,zb,xc,yc,zc,cc); double xcc = cc[0]; double ycc = cc[1]; double zcc = cc[2]; double dx = xcc-xc; double dy = ycc-yc; double dz = zcc-yc; return dx*dx+dy*dy+dz*dz; }
private void validate() { assert _meshNode!=null; assert _face==null || _face.references(this); if (_edgeBefore==null) { assert _edgeAfter==null; } else { assert this==_edgeBefore.nodeB(); assert this==_edgeAfter.nodeA(); assert this==_edgeBefore.nodeA().edgeAfter().nodeB(); assert this==_edgeAfter.nodeB().edgeBefore().nodeA(); } assert _edgeBefore==null && _edgeAfter==null || _edgeBefore!=null && this==_edgeBefore.nodeB() && _edgeAfter!=null && this==_edgeAfter.nodeA(); } private void init() {
/** * Returns the number of faces that reference this node. * @return the number of faces. */ public int countFaces() { int nface = 0; FaceIterator fi = getFaces(); while (fi.hasNext()) { fi.next(); ++nface; } return nface; }
/** * Returns the area-weighted average normal vector for this node. * @return array containing the {X,Y,Z} components of the normal vector. */ public float[] normalVector() { float[] vn = new float[3]; normalVector(vn); return vn; }
/** * Determines whether the specified nodes would form a valid face. * Assumes that nodes A and B are a boundary edge. Node C is the * other node that would form the face in question. */ private boolean validForFace(Node nodeA, Node nodeB, Node nodeC) { return !nodeC.isInSurface() || nodeC.isOnBoundary() && !hasInternalEdge(nodeB,nodeC) && !hasInternalEdge(nodeC,nodeA); }