|
@@ -92,7 +92,7 @@ public class PathBuilder {
|
|
|
return points;
|
|
|
}
|
|
|
|
|
|
- private void findPath(List<Block> blocks) {
|
|
|
+ private boolean findPath(List<Block> blocks) {
|
|
|
Block rectArea = buildRectArea();
|
|
|
List<Block> currentBlocks = blocks.stream().filter(block -> block.getRect().intersects(rectArea.getRect())).collect(Collectors.toList());
|
|
|
|
|
@@ -125,16 +125,26 @@ public class PathBuilder {
|
|
|
if (Math.abs(move) <= edge) {
|
|
|
continue;
|
|
|
}
|
|
|
+
|
|
|
+ //预留边缘距离
|
|
|
+ if (stopPos > pos) {
|
|
|
+ stopPos -= edge;
|
|
|
+ } else {
|
|
|
+ stopPos += edge;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
List<int[]> nonBlockRoads = getNonBlockRoads(blockLines, rectArea, vDirection);
|
|
|
+ if(reverse) {
|
|
|
+ Collections.reverse(nonBlockRoads);
|
|
|
+ }
|
|
|
int[] nbr = findNonBlockRoad(nonBlockRoads, trackPos);
|
|
|
|
|
|
if (nbr != null) {
|
|
|
//检查终点是否在同一个无阻挡通道中
|
|
|
if (checkEnd(nbr, vDirection)) {
|
|
|
connectEnd(direction, nbr, vDirection);
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -149,13 +159,16 @@ public class PathBuilder {
|
|
|
boolean crossReverse = crossDirection == D_LEFT || crossDirection == D_UP;
|
|
|
List<BlockLine> crossBlockLines = buildBlockLines(currentBlocks, crossDirection);
|
|
|
List<int[]> crossNonBlockRoads = getNonBlockRoads(crossBlockLines, rectArea, !vDirection);
|
|
|
+ if(reverse) {
|
|
|
+ Collections.reverse(crossNonBlockRoads);
|
|
|
+ }
|
|
|
|
|
|
//位于垂直参考方向上的无阻挡通道中
|
|
|
int[] crossNbr = findNonBlockRoad(crossNonBlockRoads, pos);
|
|
|
if (crossNbr != null) {
|
|
|
if (checkEnd(crossNbr, !vDirection)) {
|
|
|
connectEnd(crossDirection, crossNbr, !vDirection);
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -165,47 +178,41 @@ public class PathBuilder {
|
|
|
boolean valid = !reverse ? crossRoad[0] > pos : crossRoad[1] < pos;
|
|
|
if (valid && checkEnd(crossRoad, !vDirection)) {
|
|
|
connectEnd(direction, crossRoad, !vDirection);
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (crossNbr != null) {
|
|
|
for (int[] road : nonBlockRoads) {
|
|
|
- boolean valid = !crossReverse ? road[0] > pos : road[1] < pos;
|
|
|
+ boolean valid = !crossReverse ? road[0] > trackPos : road[1] < trackPos;
|
|
|
if (valid && checkEnd(road, vDirection)) {
|
|
|
connectEnd(crossDirection, road, vDirection);
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //移动到垂直参考方向上的无阻挡通道位置
|
|
|
+ //移动到垂直参考方向上的第一个无阻挡通道位置
|
|
|
int targetPos = -1;
|
|
|
- if (!reverse) {
|
|
|
- for (int i = 0; i < crossNonBlockRoads.size(); i++) {
|
|
|
- int[] crossRoad = crossNonBlockRoads.get(i);
|
|
|
- if (crossRoad[0] > pos) {
|
|
|
- targetPos = crossRoad[0] + (crossRoad[1] - crossRoad[0]) / 2; //TODO 调整&避免重叠
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- for (int i = crossNonBlockRoads.size() - 1; i >= 0; i--) {
|
|
|
- int[] crossRoad = crossNonBlockRoads.get(i);
|
|
|
- if (crossRoad[1] < pos) {
|
|
|
- targetPos = crossRoad[0] + (crossRoad[1] - crossRoad[0]) / 2; //TODO 调整&避免重叠
|
|
|
- break;
|
|
|
+ for (int[] crossRoad : crossNonBlockRoads) {
|
|
|
+ boolean flag = !reverse ? crossRoad[0] > pos : crossRoad[1] < pos;
|
|
|
+ if (flag) {
|
|
|
+ targetPos = crossRoad[0] + (crossRoad[1] - crossRoad[0]) / 2; //TODO 调整&避免重叠
|
|
|
+
|
|
|
+ if(stopPos != -1) {
|
|
|
+ boolean valid = !reverse ? targetPos < stopPos : targetPos > stopPos;
|
|
|
+ if (!valid) {
|
|
|
+ targetPos = -1;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- //垂直参考方向方向上没有通道
|
|
|
+ //垂直参考方向方向上没有找到通道
|
|
|
if (targetPos == -1) {
|
|
|
- if (stopPos != -1) { // 移动到stopPos
|
|
|
- if (stopPos > pos) {
|
|
|
- targetPos = stopPos - edge;
|
|
|
- } else {
|
|
|
- targetPos = stopPos + edge;
|
|
|
- }
|
|
|
+ if (stopPos != -1) { // 移动到stopPos
|
|
|
+ targetPos = stopPos;
|
|
|
} else { //移动到垂直参考方向上blockLine变化的位置
|
|
|
for (BlockLine crossBl : crossBlockLines) {
|
|
|
boolean valid = !crossReverse ? crossBl.base > trackPos : crossBl.base < targetPos;
|
|
@@ -224,10 +231,14 @@ public class PathBuilder {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- setCurrentPoint(vDirection ? new XY(trackPos, targetPos) : new XY(targetPos, trackPos));
|
|
|
+ moveTo(targetPos, vDirection);
|
|
|
fromDirection = direction > 2 ? direction - 2 : direction + 2; //取反向
|
|
|
- findPath(blocks); //递归调用路径计算
|
|
|
+ //递归调用路径计算
|
|
|
+ if(findPath(blocks)){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
private Block buildRectArea() {
|
|
@@ -514,10 +525,20 @@ public class PathBuilder {
|
|
|
int[] lineScope = end2.getLineScope();
|
|
|
|
|
|
if (vDirection == vEndNbr) { //当前方向与终点通道方向相同
|
|
|
- if (vEndNbr == hLine) { //垂直相交
|
|
|
+ if (vEndNbr == hLine) { //endLine与通道垂直
|
|
|
moveTo(lineTrackPos, hLine); //线横向时做纵向移动
|
|
|
- } else {
|
|
|
- //TODO 平行连接
|
|
|
+ } else { //endLine与通道平行
|
|
|
+ //TODO 可能需要调整,避免和线水平连接
|
|
|
+ int target1 = hLine ? currentPoint.x : currentPoint.y;
|
|
|
+ int offset = random.nextInt((lineScope[1] - lineScope[0]) / 2);
|
|
|
+ if (Math.abs(lineScope[0] - target1) < Math.abs((lineScope[1] - target1))) {
|
|
|
+ target1 = lineScope[0] + offset;
|
|
|
+ } else {
|
|
|
+ target1 = lineScope[1] - offset;
|
|
|
+ }
|
|
|
+ moveTo(target1, vDirection);
|
|
|
+
|
|
|
+ moveTo(lineTrackPos, !vDirection);
|
|
|
}
|
|
|
} else { //当前方向与终点通道方向垂直,折线连接
|
|
|
if (vEndNbr == hLine) { //endLine与通道垂直
|