geometry: bordermesh: fix bug with one-way routes, move route calculation into triangulate()
Fixes #19
This commit is contained in:
parent
51fdc80542
commit
e21115cc65
@ -24,35 +24,11 @@ public class BorderMesh {
|
||||
Map<Region, Polygon> m_polygons;
|
||||
Map<Region, Set<Region>> m_neighbors;
|
||||
|
||||
// TODO: Probably need to cache the neighbors after doing all this
|
||||
// intersection work! Should be generated during triangulate()
|
||||
public Collection<Region> neighbors(Region region) {
|
||||
Collection<Region> ret = new ArrayList<Region>();
|
||||
if (m_neighbors.containsKey(region)) {
|
||||
Collection<Region> 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;
|
||||
return m_neighbors.get(region);
|
||||
}
|
||||
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 ret;
|
||||
return new ArrayList<Region>();
|
||||
}
|
||||
|
||||
public BorderMesh(Collection<Region> regions) {
|
||||
@ -191,10 +167,12 @@ public class BorderMesh {
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<Region, Set<Region>> allNeighborSet = new HashMap<Region, Set<Region>>();
|
||||
|
||||
// Now we go back through our region mesh to generate vornoi points
|
||||
for(Region region : m_regions) {
|
||||
ArrayList<Vector2D> points = new ArrayList<Vector2D>();
|
||||
HashSet<Region> neighbors = new HashSet<Region>();
|
||||
HashSet<Region> allNeighbors = new HashSet<Region>();
|
||||
log.info("Executing voronoi transform...");
|
||||
for(Triangle tri : triangleSoup) {
|
||||
if (tri.region == region) {
|
||||
@ -205,35 +183,57 @@ 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);
|
||||
}
|
||||
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 {
|
||||
// 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<Region> routedNeighbors = new HashSet<Region>();
|
||||
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;
|
||||
}
|
||||
}*/
|
||||
|
||||
private boolean vecEquals(Vector2D a, Vector2D b) {
|
||||
return a.x == b.x && a.y == b.y;
|
||||
|
Loading…
Reference in New Issue
Block a user