我最终想出了一个解决方案,它还不是 100% 有效,但大多数时候它确实有效。有一个奇怪的错误导致一两行错位,我仍在努力。代码几乎占用每一行,当它到达一个顶点时,它会向右移动,从而在起点或边界点着陆。一旦确定了多边形的种类,border 函数就会将所有缺失的边界放置在多边形中。之后我的计划是去掉重复的多边形,因为它们是多余的,并且会减慢方法的速度。
private void constructPolygons() {
listRoots = new ArrayList<>();
int poly = 0;
for (GraphEdge edge : edges) {
List<GraphEdge> prevEdges = new ArrayList<>();
prevEdges.add(edge);
int count = 0;
Point forward = edge.getEnd();
Point reverse = edge.getStart();
GraphEdge currentForward = edge;
GraphEdge currentReverse = edge;
List<GraphEdge> tempArray = new ArrayList<>();
tempArray.add(edge);
System.out.println("#############################################");
System.out.printf("### Line %d is the start #####################\n", poly);
System.out.println("#############################################");
for (int ii = 0; ii < edges.size(); ii++) {
GraphEdge compEdge = edges.get(ii);
System.out.println("line: " + ii);
System.out.println("forward: " + forward.xCord + " " + forward.yCord);
System.out.println("reverse: " + reverse.xCord + " " + reverse.yCord);
System.out.println("compEdge: " + compEdge.getStart().xCord + " " + compEdge.getStart().yCord + " " + compEdge.getEnd().xCord + " " + compEdge.getEnd().yCord);
System.out.println("tempArray size: " + tempArray.size());
// Check to see whether polygon is closed. If true, break and continue with other points.
if( ((Math.abs(forward.xCord - reverse.xCord) <= tolerance) && (Math.abs(forward.yCord - forward.yCord) <= tolerance)) ) {
System.out.println("POLYGON MUST CLOSE");
break;
}
// Check to see whether point is on one of the borders
if( (((Math.abs(forward.xCord - mapMaxX) <= tolerance) || (Math.abs(forward.yCord - mapMaxY) <= tolerance)) ||
((Math.abs(forward.xCord - mapMinX) <= tolerance) || (Math.abs(forward.yCord - mapMinY) <= tolerance))) && (tempArray.size() > 1) ) {
System.out.println("POLYGON MUST CLOSE");
break;
}
// Check to see if edge has already been used
if (!tempArray.contains(compEdge)) {
double compStartX = compEdge.getStart().xCord;
double compStartY = compEdge.getStart().yCord;
double compEndX = compEdge.getEnd().xCord;
double compEndY = compEdge.getEnd().yCord;
if( ((Math.abs(forward.xCord - mapMinX) <= tolerance || Math.abs(forward.xCord - mapMaxX) <= tolerance) || (Math.abs(forward.yCord - mapMinY) <= tolerance || Math.abs(forward.yCord - mapMaxY) <= tolerance)) && (tempArray.size() <= 1)){
System.out.println(tempArray.size() < 1);
System.out.println("Swap values around");
Point temp = forward;
forward = reverse;
reverse = temp;
}
// If end of currentForward == start of compEdge
// Start -- End --> Start -- End
if ((Math.abs(forward.xCord - compStartX) <= tolerance) && (Math.abs(forward.yCord - compStartY) <= tolerance)) {
System.out.println("end -> start");
double sign1 = isPointLeft( currentForward.x1, currentForward.y1, forward.xCord, forward.yCord, compEndX, compEndY );
double sign2 = isPointLeft( currentForward.x2, currentForward.y2, forward.xCord, forward.yCord, compEndX, compEndY );
System.out.println("sign: " + sign1);
System.out.println("sign: " + sign2);
// End point must be on the right side of the line
if (sign1 > 0 || sign2 > 0) {
ii = -1;
forward = compEdge.getEnd();
currentForward = compEdge;
tempArray.add(compEdge);
System.out.println("added: " + compEdge.getStart().xCord + " " + compEdge.getStart().yCord + " " + compEdge.getEnd().xCord + " " + compEdge.getEnd().yCord);
}
}
// If end of currentForward == end of compEdge
// Start -- End --> End -- Start
else if ((Math.abs(forward.xCord - compEndX) <= tolerance) && (Math.abs(forward.yCord - compEndY) <= tolerance)) {
System.out.println("end -> end");
double sign1 = isPointLeft( currentForward.x1, currentForward.y1, forward.xCord, forward.yCord, compStartX, compStartY );
double sign2 = isPointLeft( currentForward.x2, currentForward.y2, forward.xCord, forward.yCord, compStartX, compStartY );
System.out.println("sign: " + sign1);
System.out.println("sign: " + sign2);
// Start point must be on the right side of the line
if (sign1 > 0 || sign2 > 0) {
ii = -1;
forward = compEdge.getStart();
currentForward = compEdge;
tempArray.add(compEdge);
System.out.println("added: " + compEdge.getStart().xCord + " " + compEdge.getStart().yCord + " " + compEdge.getEnd().xCord + " " + compEdge.getEnd().yCord);
}
}
} else {
System.out.println("already in list");
}
count++;
prevEdges.add(compEdge);
System.out.println("------------------------------------------");
}
if (tempArray.size() > 1) {
listRoots.add(tempArray);
poly++;
}
}
for (List<GraphEdge> list : listRoots) {
boolean point1 = false, point2 = false;
Point bp1 = new Point(), bp2 = new Point();
// System.out.println("---------------------------------");
for (GraphEdge ge : list) {
// System.out.println("Points: " + ge.x1 + "," + ge.y1 + "," + ge.x2 + "," + ge.y2);
if (ge.x1 == mapMinX || ge.x1 == mapMaxX || ge.y1 == mapMinY || ge.y1 == mapMaxY) {
if (point1) {
point2 = true;
bp2.setPoint(ge.x1, ge.y1);
} else {
point1 = true;
bp1.setPoint(ge.x1, ge.y1);
}
} else if (ge.x2 == mapMinX || ge.x2 == mapMaxX || ge.y2 == mapMinY || ge.y2 == mapMaxY) {
if (point1) {
point2 = true;
bp2.setPoint(ge.x2, ge.y2);
} else {
point1 = true;
bp1.setPoint(ge.x2, ge.y2);
}
}
}
if (point1 && point2) {
// System.out.println("Add border");
System.out.println(bp1.xCord + "," + bp1.yCord + "," + bp2.xCord + "," + bp2.yCord);
insertBorderLine(bp1, bp2, list);
}
}
}