|
@@ -1,15 +1,10 @@
|
|
|
package com.persagy.adm.diagram.core.line;
|
|
|
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
|
-import com.persagy.adm.diagram.core.model.Line;
|
|
|
+import com.persagy.adm.diagram.core.model.ConnectPoint;
|
|
|
import com.persagy.adm.diagram.core.model.base.XY;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.Iterator;
|
|
|
-import java.util.LinkedList;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Random;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -29,14 +24,10 @@ public class PathBuilder {
|
|
|
|
|
|
private static int edge = 10;
|
|
|
|
|
|
- private Line line;
|
|
|
-
|
|
|
private LineEnd end1;
|
|
|
|
|
|
private LineEnd end2;
|
|
|
|
|
|
- private boolean exchange;
|
|
|
-
|
|
|
private List<XY> points = new ArrayList<>();
|
|
|
|
|
|
private XY currentPoint;
|
|
@@ -45,14 +36,12 @@ public class PathBuilder {
|
|
|
|
|
|
private Random random = new Random();
|
|
|
|
|
|
- public PathBuilder(Line line, LineEnd end1, LineEnd end2, boolean exchange) {
|
|
|
- this.line = line;
|
|
|
+ public PathBuilder(LineEnd end1, LineEnd end2, ConnectPoint from) {
|
|
|
this.end1 = end1;
|
|
|
this.end2 = end2;
|
|
|
- this.exchange = exchange;
|
|
|
|
|
|
setCurrentPoint(end1.getPoint());
|
|
|
- String fromAnchor = (!exchange ? line.getFrom() : line.getTo()).getAnchorCode();
|
|
|
+ String fromAnchor = from.getAnchorCode();
|
|
|
switch (fromAnchor.charAt(0)) {
|
|
|
case 'T':
|
|
|
fromDirection = D_DOWN;
|
|
@@ -77,18 +66,6 @@ public class PathBuilder {
|
|
|
|
|
|
public List<XY> calcPath(List<Block> blocks) {
|
|
|
findPath(blocks);
|
|
|
-
|
|
|
- if (exchange) {
|
|
|
- Collections.reverse(points);
|
|
|
- }
|
|
|
-
|
|
|
- if (line.getFrom().getLocation() != null) {
|
|
|
- points.add(0, line.getFrom().getLocation());
|
|
|
- }
|
|
|
- if (line.getTo().getLocation() != null) {
|
|
|
- points.add(line.getTo().getLocation());
|
|
|
- }
|
|
|
-
|
|
|
return points;
|
|
|
}
|
|
|
|
|
@@ -215,14 +192,17 @@ public class PathBuilder {
|
|
|
targetPos = stopPos;
|
|
|
} else { //移动到垂直参考方向上blockLine变化的位置
|
|
|
for (BlockLine crossBl : crossBlockLines) {
|
|
|
- boolean valid = !crossReverse ? crossBl.base > trackPos : crossBl.base < targetPos;
|
|
|
- if (valid && crossBl.begin <= pos && crossBl.end >= pos) {
|
|
|
- if (!reverse) {
|
|
|
- targetPos = crossBl.end;
|
|
|
- } else {
|
|
|
- targetPos = crossBl.begin;
|
|
|
+ boolean valid = !crossReverse ? crossBl.base > trackPos : crossBl.base < trackPos;
|
|
|
+ if (valid) {
|
|
|
+ int safeOffset = 5;
|
|
|
+ if(!reverse && crossBl.end > pos){
|
|
|
+ targetPos = crossBl.end + safeOffset;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if(reverse && crossBl.begin < pos) {
|
|
|
+ targetPos = crossBl.begin - safeOffset;
|
|
|
+ break;
|
|
|
}
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
//计算失败,尝试下一方向
|
|
@@ -244,12 +224,44 @@ public class PathBuilder {
|
|
|
private Block buildRectArea() {
|
|
|
int[] xs;
|
|
|
int[] ys;
|
|
|
- if (end2.getPoint() != null) {
|
|
|
- xs = new int[]{currentPoint.x, end2.getPoint().x};
|
|
|
- ys = new int[]{currentPoint.y, end2.getPoint().y};
|
|
|
+
|
|
|
+ boolean begin = points.size() == 1;
|
|
|
+ if(begin) {
|
|
|
+ xs = new int[4];
|
|
|
+ ys = new int[4];
|
|
|
+ if (LineEnd.isHorizontal(end1.getAnchorSide())) {
|
|
|
+ xs[0] = end1.getAnchorSide()[0].x;
|
|
|
+ xs[1] = end1.getAnchorSide()[1].x;
|
|
|
+ ys[0] = ys[1] = currentPoint.y;
|
|
|
+ } else {
|
|
|
+ xs[0] = xs[1] = currentPoint.x;
|
|
|
+ ys[0] = end1.getAnchorSide()[0].y;
|
|
|
+ ys[1] = end1.getAnchorSide()[1].y;
|
|
|
+ }
|
|
|
+ if (end2.getPoint() != null) {
|
|
|
+ if (LineEnd.isHorizontal(end2.getAnchorSide())) {
|
|
|
+ xs[2] = end2.getAnchorSide()[0].x;
|
|
|
+ xs[3] = end2.getAnchorSide()[1].x;
|
|
|
+ ys[2] = ys[3] = end2.getPoint().y;
|
|
|
+ } else {
|
|
|
+ xs[2] = xs[3] = end2.getPoint().x;
|
|
|
+ ys[2] = end2.getAnchorSide()[0].y;
|
|
|
+ ys[3] = end2.getAnchorSide()[1].y;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ xs[2] = end2.getLine()[0].x;
|
|
|
+ xs[3] = end2.getLine()[1].x;
|
|
|
+ ys[2] = end2.getLine()[0].y;
|
|
|
+ ys[3] = end2.getLine()[1].y;
|
|
|
+ }
|
|
|
} else {
|
|
|
- xs = new int[]{currentPoint.x, end2.getLine()[0].x, end2.getLine()[1].x};
|
|
|
- ys = new int[]{currentPoint.y, end2.getLine()[0].y, end2.getLine()[1].y};
|
|
|
+ if (end2.getPoint() != null) {
|
|
|
+ xs = new int[]{currentPoint.x, end2.getPoint().x};
|
|
|
+ ys = new int[]{currentPoint.y, end2.getPoint().y};
|
|
|
+ } else {
|
|
|
+ xs = new int[]{currentPoint.x, end2.getLine()[0].x, end2.getLine()[1].x};
|
|
|
+ ys = new int[]{currentPoint.y, end2.getLine()[0].y, end2.getLine()[1].y};
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
XY location = new XY(ArrayUtil.min(xs), ArrayUtil.min(ys));
|
|
@@ -265,22 +277,25 @@ public class PathBuilder {
|
|
|
private int[] findDirection() {
|
|
|
int[] rtn = new int[4];
|
|
|
|
|
|
+ boolean vPriority;
|
|
|
if (end2.getPoint() != null) {
|
|
|
XY endPoint = end2.getPoint();
|
|
|
+ vPriority = Math.abs(endPoint.y - currentPoint.y) > Math.abs(endPoint.x - currentPoint.x);
|
|
|
if (endPoint.x == currentPoint.x) {
|
|
|
- setDirection(rtn, null, endPoint.y > currentPoint.y);
|
|
|
+ setDirection(rtn, null, endPoint.y > currentPoint.y, vPriority);
|
|
|
} else if (endPoint.y == currentPoint.y) {
|
|
|
- setDirection(rtn, endPoint.x > currentPoint.x, null);
|
|
|
+ setDirection(rtn, endPoint.x > currentPoint.x, null, vPriority);
|
|
|
} else {
|
|
|
- setDirection(rtn, endPoint.x > currentPoint.x, endPoint.y > currentPoint.y);
|
|
|
+ setDirection(rtn, endPoint.x > currentPoint.x, endPoint.y > currentPoint.y, vPriority);
|
|
|
}
|
|
|
} else {
|
|
|
int trackPos = end2.getLineTrackPos();
|
|
|
int[] scope = end2.getLineScope();
|
|
|
if (end2.isLineHorizontal()) {
|
|
|
+ vPriority = Math.abs(end2.getLineTrackPos() - currentPoint.y) > Math.min(Math.abs(scope[0] - currentPoint.x), Math.abs(scope[1] - currentPoint.x));
|
|
|
boolean xMatch = scope[0] <= currentPoint.x && scope[1] >= currentPoint.x;
|
|
|
if (xMatch) {
|
|
|
- setDirection(rtn, null, trackPos > currentPoint.y);
|
|
|
+ setDirection(rtn, null, trackPos > currentPoint.y, vPriority);
|
|
|
} else if (trackPos == currentPoint.y) {
|
|
|
//需要垂直交汇
|
|
|
rtn[0] = D_DOWN;
|
|
@@ -291,9 +306,10 @@ public class PathBuilder {
|
|
|
rtn[3] = right ? D_LEFT : D_RIGHT;
|
|
|
}
|
|
|
} else {
|
|
|
- boolean yMatch = scope[0] <= currentPoint.y && scope[0] >= currentPoint.y;
|
|
|
+ vPriority = Math.min(Math.abs(scope[0] - currentPoint.y), Math.abs(scope[1] - currentPoint.y)) > Math.abs(end2.getLineTrackPos() - currentPoint.x);
|
|
|
+ boolean yMatch = scope[0] <= currentPoint.y && scope[1] >= currentPoint.y;
|
|
|
if (yMatch) {
|
|
|
- setDirection(rtn, trackPos > currentPoint.x, null);
|
|
|
+ setDirection(rtn, trackPos > currentPoint.x, null, vPriority);
|
|
|
} else if (trackPos == currentPoint.x) {
|
|
|
//需要垂直交汇
|
|
|
rtn[0] = D_RIGHT;
|
|
@@ -306,17 +322,17 @@ public class PathBuilder {
|
|
|
}
|
|
|
if (rtn[0] == 0) {
|
|
|
XY p0 = end2.getLine()[0];
|
|
|
- setDirection(rtn, p0.x > currentPoint.x, p0.y > currentPoint.y);
|
|
|
+ setDirection(rtn, p0.x > currentPoint.x, p0.y > currentPoint.y, vPriority);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return rtn;
|
|
|
}
|
|
|
|
|
|
- private void setDirection(int[] directions, Boolean right, Boolean down) {
|
|
|
+ private void setDirection(int[] directions, Boolean right, Boolean down, boolean vPriority) {
|
|
|
if (right != null && down != null) {
|
|
|
- directions[0] = right ? D_RIGHT : D_LEFT;
|
|
|
- directions[1] = down ? D_DOWN : D_UP;
|
|
|
+ directions[vPriority ? 1 : 0] = right ? D_RIGHT : D_LEFT;
|
|
|
+ directions[vPriority ? 0 : 1] = down ? D_DOWN : D_UP;
|
|
|
directions[2] = right ? D_LEFT : D_RIGHT;
|
|
|
directions[3] = down ? D_UP : D_DOWN;
|
|
|
} else if (right != null) {
|