diff --git a/src/main/java/us/camin/regions/geometry/BorderMesh.java b/src/main/java/us/camin/regions/geometry/BorderMesh.java index 687030b..a61566e 100644 --- a/src/main/java/us/camin/regions/geometry/BorderMesh.java +++ b/src/main/java/us/camin/regions/geometry/BorderMesh.java @@ -24,35 +24,11 @@ public class BorderMesh { Map m_polygons; Map> m_neighbors; - // TODO: Probably need to cache the neighbors after doing all this - // intersection work! Should be generated during triangulate() public Collection neighbors(Region region) { - Collection ret = new ArrayList(); if (m_neighbors.containsKey(region)) { - Collection allNeighbors = m_neighbors.get(region); - for(Region neighbor : allNeighbors) { - int crossings = 0; - Vector2D start = new Vector2D(region.location().getBlockX(), region.location().getBlockZ()); - Vector2D neighborEnd = new Vector2D(neighbor.location().getBlockX(), neighbor.location().getBlockZ()); - for(Region distantNeighbor : m_regions) { - if (distantNeighbor.equals(neighbor)) { - continue; - } - Polygon poly = m_polygons.get(distantNeighbor); - for(Polygon.Segment edge : poly.segments()) { - // Check if the line from region->neighbor intersects with - // any polygon - if (doIntersect(start, neighborEnd, edge.start, edge.end)) { - crossings++; - } - } - } - if (crossings == 1 || crossings == 0) { - ret.add(neighbor); - } - } + return m_neighbors.get(region); } - return ret; + return new ArrayList(); } public BorderMesh(Collection regions) { @@ -191,10 +167,12 @@ public class BorderMesh { } } + HashMap> allNeighborSet = new HashMap>(); + // Now we go back through our region mesh to generate vornoi points for(Region region : m_regions) { ArrayList points = new ArrayList(); - HashSet neighbors = new HashSet(); + HashSet allNeighbors = new HashSet(); log.info("Executing voronoi transform..."); for(Triangle tri : triangleSoup) { if (tri.region == region) { @@ -205,36 +183,58 @@ public class BorderMesh { Location neighborLoc = neighbor.location(); Vector2D neighborCenter = new Vector2D(neighborLoc.getBlockX(), neighborLoc.getBlockZ()); if (vecEquals(tri.a, neighborCenter) || vecEquals(tri.b, neighborCenter) || vecEquals(tri.c, neighborCenter)) { - neighbors.add(neighbor); + allNeighbors.add(neighbor); } } points.add(tri.circumcenter()); } } + allNeighborSet.put(region, allNeighbors); + // Sort points into a renderable polygon based on direction to center Location loc = region.location(); Vector2D regionCenter = new Vector2D(loc.getBlockX(), loc.getBlockZ()); points.sort((Vector2D a, Vector2D b) -> Double.compare(direction(a, regionCenter), direction(b, regionCenter))); - log.info("Border for " + region.name() + " is defined by " + points.size() + " points"); + log.fine("Border for " + region.name() + " is defined by " + points.size() + " points"); Polygon polygon = new Polygon(points); m_polygons.put(region, polygon); - m_neighbors.put(region, neighbors); + + } + + // Now that we have the borders, we generate valid routes that cross + // zero or one border lines at most. + for(Region region : m_regions) { + Set routedNeighbors = new HashSet(); + for(Region neighbor : allNeighborSet.get(region)) { + int crossings = 0; + Vector2D start = new Vector2D(region.location().getBlockX(), region.location().getBlockZ()); + Vector2D neighborEnd = new Vector2D(neighbor.location().getBlockX(), neighbor.location().getBlockZ()); + for(Region distantNeighbor : m_regions) { + if (distantNeighbor.equals(neighbor) || distantNeighbor.equals(region)) { + continue; + } + Polygon poly = m_polygons.get(distantNeighbor); + for(Polygon.Segment edge : poly.segments()) { + // Check if the line from region->neighbor intersects with + // any polygon + if (doIntersect(start, neighborEnd, edge.start, edge.end)) { + log.fine("Intersect " + distantNeighbor.name()); + crossings++; + } + } + } + log.fine("Route: " + region.name() + " -> " + neighbor.name() + "\t" + crossings); + if (crossings == 1 || crossings == 0) { + routedNeighbors.add(neighbor); + } + } + + m_neighbors.put(region, routedNeighbors); } return true; } - /*public boolean validNeighbors(Region regionA, Region regionB) { - Polygon polyA = polygonForRegion(regionA); - Polygon polyB = polygonForRegion(regionA); - Location center = region.location(); - if (poly.contains(center.getBlockX(), center.getBlockZ())) { - return false; - } else { - return true; - } - }*/ - private boolean vecEquals(Vector2D a, Vector2D b) { return a.x == b.x && a.y == b.y; }