/** * Locate the triangle with point inside it or on its boundary. * * @param point the point to locate * @return the triangle that holds point; null if no such triangle */ public Triangle locate(Pnt point) { Triangle triangle = mostRecent; if (!this.contains(triangle)) triangle = null; // Try a directed walk (this works fine in 2D, but can // fail in 3D) Set<Triangle> visited = new HashSet<Triangle>(); while (triangle != null) { if (visited.contains(triangle)) { // This should // never // happen ; // System.out.println("Warning: Caught in a locate loop"); break; } visited.add(triangle); // Corner opposite point Pnt corner = point.isOutside(triangle.toArray(new Pnt[0])); if (corner == null) return triangle; triangle = this.neighborOpposite(corner, triangle); } // No luck; try brute force ; // System.out.println("Warning: Checking all triangles for " + point); for (Triangle tri : this) { if (point.isOutside(tri.toArray(new Pnt[0])) == null) return tri; } // No such triangle ; // System.out.println("Warning: No triangle holds " + point); return null; }
/** * Determine the cavity caused by site. * * @param site the site causing the cavity * @param triangle the triangle containing site * @return set of all triangles that have site in their circumcircle */ private Set<Triangle> getCavity(Pnt site, Triangle triangle) { Set<Triangle> encroached = new HashSet<Triangle>(); Queue<Triangle> toBeChecked = new LinkedList<Triangle>(); Set<Triangle> marked = new HashSet<Triangle>(); toBeChecked.add(triangle); marked.add(triangle); while (!toBeChecked.isEmpty()) { triangle = toBeChecked.remove(); if (site.vsCircumcircle(triangle.toArray(new Pnt[0])) == 1) continue; // Site outside triangle => // triangle not in // cavity encroached.add(triangle); // Check the neighbors for (Triangle neighbor : triGraph.neighbors(triangle)) { if (marked.contains(neighbor)) continue; marked.add(neighbor); toBeChecked.add(neighbor); } } return encroached; }