private int addNeighbors(List<Acre> left, List<Acre> right) { assert left.size() == right.size(); int count = 0; for (int i = 0, j = left.size(); i < j; i++) { Acre l = left.get(i); Acre r = right.get(i); if (l != null && r != null) { l.addNeighbor(r, indexOfMyNeighbor(l, r)); r.addNeighbor(l, indexOfMyNeighbor(r, l)); count++; } } return count; }
private void assignVertexIds() { pointLocator = new PointLocator(); for (Acre acre : sector.getInnerAcres()) { Point[] midpoints = AcreSeamSeq.buildMidpoints(acre); acre.seamStartVertexIds = buildSeamStarts(acre.packId, midpoints); acre.zoneStartVertexIds = buildZoneStarts(acre.packId, acre.points.length); acre.topographyDef = buildTopographyDef(acre.center, acre.points); } for (Acre acre : sector.getSharedAcres()) { Point[] midpoints = AcreSeamSeq.buildMidpoints(acre); acre.seamStartVertexIds = buildSeamStarts(acre.packId, midpoints); acre.zoneStartVertexIds = buildZoneStarts(acre.packId, acre.points.length); acre.topographyDef = buildTopographyDef(acre.center, acre.points); } }
public static void main(String[] args) { final Set<String> show = new HashSet<String>(Arrays.asList("point$ triangles acres neighbors sectors".split(" "))); // final Set<String> show = new HashSet<String>(Arrays.asList("global-sectors // sectors".split(" "))); final Map<Long, Acre> acresByID = new HashMap<Long, Acre>(); Consumer<Acre> acreConsumer = new Consumer<Acre>() { public void consume(Acre acre) { assert !acresByID.containsKey(acre.id); acresByID.put(acre.id, acre); } }; Point[] points = { new Point(1.0, -1000.0, Math.sqrt(3) * -0.5), new Point(-1.0, -1000.0, Math.sqrt(3) * -0.5), new Point(0.0, -1000.0, Math.sqrt(3) * 0.5) }; GeoPoint[] geoPoints = { GeoPoint.fromPoint(points[0]), GeoPoint.fromPoint(points[1]), GeoPoint.fromPoint(points[2]) }; for (int i = 0; i < 3; i++) { points[i] = geoPoints[i].toPoint(1000.0); } final OutputGraph out = new OutputGraph("Acres", new Dimension(2048, 2048), 0.0, 0.0, 1000.0); out.onClose( new Runnable() { public void run() { System.exit(0); } }); Sector.MAP_ACRES_BY_CENTER_POINT.set(true); final GlobalSector gs = new GlobalSector(0, Globe.INSTANCE, geoPoints); final AtomicReference<Sector[]> sectors = new AtomicReference<Sector[]>(); gs.setInit( gs.new Initializer(5, points[0], points[1], points[2], false, null) { @Override protected Sector[] getChildren(int length) { sectors.set(super.getChildren(length)); return sectors.get(); } @Override protected Sector buildChild( int index, GeoPoint a, GeoPoint b, GeoPoint c, Point i, Point j, Point k, boolean inverted) { TestSector sector = new TestSector(index, inverted, gs, new GeoPoint[] {a, b, c}); sector.setInit(sector.new TestInitializer(new Point[] {i, j, k}, show, out)); sectors.get()[index] = sector; return sector; } }); gs.getInit().run(); for (Sector s : sectors.get()) { s.getInit().run(); s.edgesBuilt = new AtomicInteger(); } if (show.contains("global-sectors")) { Point a = gs.points[0].toPoint(1000.0); Point b = gs.points[1].toPoint(1000.0); Point c = gs.points[2].toPoint(1000.0); double x = (a.x + b.x + c.x) / 3.0; double y = (a.z + b.z + c.z) / 3.0; if (show.contains("labels")) { out.addLabel(Color.orange, gs.getIDString(), x, y + 0.075); } x *= -0.02; y *= -0.02; out.addLine( Color.orange, a.x * 1.02 + x, a.z * 1.02 + y, b.x * 1.02 + x, b.z * 1.02 + y, c.x * 1.02 + x, c.z * 1.02 + y, a.x * 1.02 + x, a.z * 1.02 + y); } if (show.contains("sectors")) { for (Sector s : sectors.get()) { Point a = s.points[0].toPoint(1000.0); Point b = s.points[1].toPoint(1000.0); Point c = s.points[2].toPoint(1000.0); out.addLine(Color.magenta, a.x, a.z, b.x, b.z, c.x, c.z, a.x, a.z); if (show.contains("labels")) { double x = (a.x + b.x + c.x) / 3.0; double y = (a.z + b.z + c.z) / 3.0; out.addLabel(Color.magenta, s.getIDString(), x, y); } } } GeoFactory.combinePoints(Arrays.<GeoPointBasedElement>asList(sectors.get()), Globe.INSTANCE); Map<GeoPoint, Sector[]> sectorMap = new HashMap<GeoPoint, Sector[]>(); for (Sector s : sectors.get()) { GeoFactory.addSectorByPoint(sectorMap, s, s.points[0]); GeoFactory.addSectorByPoint(sectorMap, s, s.points[1]); GeoFactory.addSectorByPoint(sectorMap, s, s.points[2]); } Collection<AcreBuilder> builders = new ArrayList<AcreBuilder>(); for (final Sector s : sectors.get()) { builders.add( new AcreBuilder( GeoSpec.SECTOR_DIVISIONS.iGet(), false, s, sectorMap, null, acreConsumer) { @Override protected int[] findNearCornerAcres() { int[] nearCornerAcres = super.findNearCornerAcres(); if (show.contains("near-edge-acres")) { System.out.println("Corner A: " + nearCornerAcres[0]); System.out.println("Corner B: " + nearCornerAcres[1]); System.out.println("Corner C: " + nearCornerAcres[2]); } return nearCornerAcres; } @Override protected Map<Edge, int[]> findNearEdgeAcres() { Map<Edge, int[]> nearEdgeAcres = super.findNearEdgeAcres(); if (show.contains("near-edge-acres")) { System.out.println("Edge AB: " + Arrays.toString(nearEdgeAcres.get(Edge.AB))); System.out.println("Edge BC: " + Arrays.toString(nearEdgeAcres.get(Edge.BC))); System.out.println("Edge CA: " + Arrays.toString(nearEdgeAcres.get(Edge.CA))); } return nearEdgeAcres; } }); } for (AcreBuilder builder : builders) { builder.run(0); } for (AcreBuilder builder : builders) { builder.secondRun().run(); } for (Acre a : acresByID.values()) { int c = 0; Point p = a.center.toPoint(1000.0); for (Sector s : sectors.get()) { Acre acre = s.acres.get(p); if (acre != null) { assert acre == a; c++; } } assert a.flavor == Acre.Flavor.MULTI_SECTOR ? c >= 5 : (a.flavor == Acre.Flavor.DUAL_SECTOR ? c == 2 : c == 1); } if (show.contains("acres")) { Set<Long> visitedAcreIds = new HashSet<Long>(); for (Sector s : sectors.get()) { Acre[] acres = s.getInnerAcres(); for (Acre acre : acres) { debugAcre(acre, acre.getIDString(), visitedAcreIds, show, out); } acres = s.getSharedAcres(); for (Acre acre : acres) { if (acre != null) { debugAcre(acre, acre.getIDString(), visitedAcreIds, show, out); } } } assert visitedAcreIds.containsAll(acresByID.keySet()); } if (show.contains("neighbors")) { double v = 0.7, w = 1.0 - v; for (Acre a : acresByID.values()) { for (long neighborID : a.neighbors) { Acre n = acresByID.get(neighborID); if (n != null) { Point s = a.center.toPoint(1000.0); Point t = n.center.toPoint(1000.0); out.addArrow( Color.white, s.x * v + t.x * w, s.z * v + t.z * w, s.x * w + t.x * v, s.z * w + t.z * v); } } } } }
private int addNeighbors( Acre[] acresA, int rowA, int lengthA, Acre[] acresB, int rowB, int lengthB) { if (lengthA <= 0 || lengthB <= 0) { return 0; // no-op } if (lengthB > lengthA) { int t = rowA; rowA = rowB; rowB = t; t = lengthA; lengthA = lengthB; lengthB = t; } if (lengthA == lengthB) { for (int i = 0; i < lengthA; i++) { Acre acreA = acresA[rowA + i]; Acre acreB = acresB[rowB + i]; acreA.addNeighbor(acreB, indexOfMyNeighbor(acreA, acreB)); acreB.addNeighbor(acreA, indexOfMyNeighbor(acreB, acreA)); } return lengthA * 2; } else { assert lengthA <= lengthB + 2; if (lengthA == lengthB + 1) { for (int i = 0; i < lengthB; i++) { Acre acreA = acresA[rowA + i]; Acre acreB = acresB[rowB + i]; Acre acreC = acresA[rowA + i + 1]; acreA.addNeighbor(acreB, indexOfMyNeighbor(acreA, acreB)); acreB.addNeighbor(acreA, indexOfMyNeighbor(acreB, acreA)); acreB.addNeighbor(acreC, indexOfMyNeighbor(acreB, acreC)); acreC.addNeighbor(acreB, indexOfMyNeighbor(acreC, acreB)); } return lengthB * 4; } else { for (int i = 0; i < lengthB; i++) { Acre acreA = acresA[rowA + i + 1]; Acre acreB = acresB[rowB + i]; acreA.addNeighbor(acreB, indexOfMyNeighbor(acreA, acreB)); acreB.addNeighbor(acreA, indexOfMyNeighbor(acreB, acreA)); } return lengthB * 4; } } }
private static void debugAcre( Acre a, String label, Set<Long> visitedAcreIds, Set<String> show, OutputGraph out) { if (visitedAcreIds != null) { visitedAcreIds.add(a.id); } double x = 0, y = 0; int l = a.points.length; double[] coords = new double[l * 2 + 2]; for (int j = 0; j <= l; j++) { Point p = a.points[j % l].toPoint(1000.0); coords[j * 2] = p.x; coords[j * 2 + 1] = p.z; if (j < l) { x += p.x; y += p.z; } } x /= l; y /= l; for (int j = 0; j <= l; j++) { coords[j * 2] = coords[j * 2] * 0.85 + x * 0.15; coords[j * 2 + 1] = coords[j * 2 + 1] * 0.85 + y * 0.15; } if (label == null) { out.addLine(Color.white, coords); } else { Color polyColor, textColor = Color.black; AbstractCartographicElement parent = a.getParent(); boolean inverted = parent instanceof Sector && ((Sector) parent).isInverted(); int neighbors = 0; for (long id : a.neighbors) { if (id != 0) { neighbors++; } } switch (a.flavor) { case INNER1: polyColor = inverted ? Color.green : Color.red; break; case INNER2: polyColor = inverted ? Color.red : Color.green; break; case INNER3: // polyColor = Color.blue; // break; case DUAL_SECTOR: polyColor = new Color(51, 51, 255); break; case MULTI_SECTOR: polyColor = Color.gray.brighter(); textColor = Color.black; break; default: polyColor = Color.black; textColor = Color.red; break; } if (neighbors < 6) { polyColor = polyColor.darker().darker(); if (textColor == Color.black) { textColor = Color.white; } out.addPoly(polyColor, coords); double[] closed = new double[coords.length + 2]; System.arraycopy(coords, 0, closed, 0, coords.length); System.arraycopy(coords, 0, closed, coords.length, 2); out.addLine(polyColor, closed); } else { out.addPoly(polyColor, coords); } if (show.contains("labels")) { if (label.contains("~")) { Matcher matcher = Pattern.compile("^(.*):\\[(.*)~(.*)]$").matcher(label); matcher.find(); out.addLabel( textColor, matcher.group(1) + "\n" + matcher.group(2) + "\n" + matcher.group(3), x, y); } else { Matcher matcher = Pattern.compile("^(.*?):(.*)$").matcher(label); matcher.find(); out.addLabel(textColor, matcher.group(1) + "\n" + matcher.group(2), x, y); } } } }