Thread: [Bprocessor-commit] model/src/net/sourceforge/bprocessor/model Space.java, 1.40, 1.41
Status: Pre-Alpha
Brought to you by:
henryml
From: Nordholt <nor...@us...> - 2006-07-24 11:14:01
|
Update of /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv6484/src/net/sourceforge/bprocessor/model Modified Files: Space.java Log Message: method for determining whether spaces are closed or not add Index: Space.java =================================================================== RCS file: /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model/Space.java,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** Space.java 17 Jul 2006 08:37:00 -0000 1.40 --- Space.java 24 Jul 2006 11:13:57 -0000 1.41 *************** *** 1387,1389 **** --- 1387,1590 ---- } + /** + * Finds out if this space is closed or not. + * @return true or false. + */ + public boolean isClosed() { + Iterator surfaces = envelope.iterator(); + Surface startSurface = null; + if (surfaces.hasNext()) { + startSurface = (Surface)surfaces.next(); + Set coloured = new HashSet(); + if (colour(startSurface, coloured)) { + return coloured.containsAll(envelope); + } + } + return false; + } + + /** + * Colours a surface and then calls it self recursively to colour its neighbours. + * returns true if the colouring is succesfull, false otherwise + * @param surface the surface to colour + * @param coloured the set of coloured surfaces. + * @return the outcome of the colouring + */ + private boolean colour(Surface surface, Set coloured) { + coloured.add(surface); + boolean closed = true; + Iterator it = surface.getEdges().iterator(); + while (closed && it.hasNext()) { + Edge e = (Edge)it.next(); + Surface neighbour = neighbourOnEdge(surface, e); + if (neighbour != null) { + if (!coloured.contains(neighbour)) { + closed = colour(neighbour, coloured); + } + } else { + closed = false; + } + } + return closed; + } + + /** + * Determines if a surface can be coloured. + * @param s a surface + * @param angle the angle of the surface with the previous surface + * @param i - + * @param j - + * @return wherter or not it can be coloured. + */ + private boolean colourable(Surface s, double angle, Vertex i, Vertex j) { + boolean colourable = false; + if (s != null) { + Vertex spaceVector = s.normal(); + if (s.getFrontDomain() == this) { + spaceVector.scale(1 / spaceVector.length()); + } else if (s.getBackDomain() == this) { + spaceVector.scale(-1 / spaceVector.length()); + } else { + return false; + } + if (angle > Math.PI && spaceVector.dot(i) > 0) { + colourable = true; + } + if (angle < Math.PI && spaceVector.dot(i) < 0) { + colourable = true; + } + if (Math.abs(angle - Math.PI) < 0.00001 && spaceVector.dot(j) > 0) { + colourable = true; + } + if (Math.abs(angle) < 0.00001 && spaceVector.dot(j) < 0) { + colourable = true; + } + } + return colourable; + + } + + /** + * Finds the next surface on an edge + * @param startSurface the surface to find neighbours for. + * @param sharedEdge the shared edge + * @return the neighbour surface. + */ + private Surface neighbourOnEdge(Surface startSurface, Edge sharedEdge) { + //Building a coordinate system: + Vertex n = sharedEdge.getDirection(); + n.scale(1 / n.length()); + + Vertex j = startSurface.normal(); + if (startSurface.getFrontDomain() == this) { + j.scale(1 / j.length()); + } else { + j.scale(-1 / j.length()); + } + + LinkedList edges = new LinkedList(startSurface.getEdges()); + Vertex sharedVertex = sharedEdge.getFrom(); + Vertex adjacentVertex = findNextVertex(sharedEdge, sharedVertex, edges); + + + Plane p = new Plane(n.getX(), n.getY(), n.getZ(), + -(n.getX() * sharedVertex.getX() + + n.getY() * sharedVertex.getY() + + n.getZ() * sharedVertex.getZ())); + Vertex i = (p.project(sharedVertex)).minus(p.project(adjacentVertex)); + i.scale(1 / i.length()); + CoordinateSystem cs = new CoordinateSystem(i, j , n, sharedVertex); + + //Finding the surface with the minimal angle to the startSurface: + Iterator it = sharedEdge.getSurfaces().iterator(); + Surface neighbour = null; + double minAngle = (Math.PI * 2 + 1); + double angle = minAngle; + while (it.hasNext()) { + Surface s = (Surface)it.next(); + if (s != startSurface) { + LinkedList l = new LinkedList(s.getEdges()); + Vertex notShared = findNextVertex(sharedEdge, sharedVertex, l); + angle = findAngle(sharedVertex, notShared, cs); + Vertex normal = s.normal(); + if (angle < minAngle && colourable(s, angle, i, j)) { + minAngle = angle; + neighbour = s; + } + } + } + return neighbour; + } + + /** + * finds the angle between the x-axis of the coordinate system and + * a neighbour-surface to the sharedEdge. + * @param shared - + * @param notShared - + * @param coordinateSystem - + * @return the angle. + */ + private double findAngle(Vertex shared, Vertex notShared, + CoordinateSystem coordinateSystem) { + Vertex projShared = coordinateSystem.projection(shared); + Vertex projNotShared = coordinateSystem.projection(notShared); + Vertex projEdgeDir = projNotShared.minus(projShared); + projEdgeDir.scale(1 / projEdgeDir.length()); + Vertex xAxis = coordinateSystem.getI().copy(); + double angle = Math.acos(xAxis.dot(projEdgeDir)); + if (coordinateSystem.translate(projNotShared).getY() >= 0) { + angle = Math.PI - angle; + } else { + angle = Math.PI + angle; + } + return angle; + } + + /** + * Given a list of edges, L, one edge in the list, e, and one of this edge's + * vertices, v, finds the next edge in L which also contains v. If the edge found, e', + * is parrallel to e the first edge e'' in the direction of rotation from e to e' + * that is not parrallel to e is found. The end point of e'' that is not on a line + * parrallel to e is then returned. If no such vertex exists null is returned. + * @param edge the edge + * @param shared the shared vertex + * @param edges the list of edges + * @return the first non parrallel edge + */ + private Vertex findNextVertex(Edge edge, Vertex shared, LinkedList edges) { + int nextIndex = (edges.indexOf(edge) + 1) % edges.size(); + int lastIndex = ((edges.indexOf(edge) - 1) + edges.size()) % edges.size(); + Edge nextEdge = (Edge)edges.get(nextIndex); + Edge lastEdge = (Edge)edges.get(lastIndex); + int index; + int direction; + Edge nonParrallel; + Vertex notShared; + if (nextEdge.contains(shared)) { + nonParrallel = nextEdge; + notShared = nonParrallel.otherVertex(shared); + index = nextIndex; + direction = 1; + } else { + nonParrallel = lastEdge; + notShared = nonParrallel.otherVertex(shared); + index = lastIndex; + direction = -1; + } + boolean found = false; + while (!found && nonParrallel != edge) { + if (nonParrallel.getDirection().cross(edge.getDirection()).length() > 0.00001) { + found = true; + } else { + index = ((index + direction) + edges.size()) % edges.size(); + nonParrallel = (Edge)edges.get(index); + notShared = nonParrallel.otherVertex(notShared); + } + } + if (nonParrallel == edge) { + return null; + } else { + return notShared; + } + } } |