说明:
1、未实现障碍物自动避让功能;
2、未实现添加图元到连线之间,连线自动避开新增图元功能;
后续再完善...
package com.sunsheen.jfids.studio.uml.modulediagram.anchorAndRouter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.Assert; import org.eclipse.draw2d.BendpointConnectionRouter; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.geometry.Vector; /** * uml连接线路由算法 * 1、一旦用户对某条连线的路由方式进行了调整,就不再为其提供智能路由布线的功能。 * 2、用户是否对连线的路径进行了调整的信息是需要持久存储的。 * 3、用户在建模时,只有当发生了连线和模型的布局冲突时,才对存在布局冲突的连线进行路由调整,对其他连线不做更改。 * * @author WangSong */ public class AIUmlConnectionRouter extends BendpointConnectionRouter { private IFigure content;// 当前操作的图元 private final static int DEFAULT_SPACE = 10;// 默认点间距 private PointList points;// 连线上位置点集合 private int space; /* 离障碍物的间隙 */ private Vector endDirection;// 结束方向 private Point endPoint;// 结束位置 // 连线是否跟图元起点边平行 private boolean parallelStartSide; // 连线是否跟图元终点边平行 private boolean parallelEndSide; // 连线跟连接点平行的边(源图元) private String parallelSideSource; // 上下左右 // 连线跟连接点平行的边(目标图元) private String parallelSideTarget; // 上下左右 private int rectangleAffirm = 0;// 初始化当前图元选择 //冲突图元、拐点、关联关系 Map> rectangleLinesRelationMap = new HashMap >();//关联关系 private List conflictRectangleList = new ArrayList (); //有冲突的图元 private List conflictPointArrayList = new ArrayList ();//存放一对一对冲突的拐点 private boolean sourceAcrossCenterPoint;//连线是否跨过源图元或者目标图元中心点(原图原) private boolean targetAcrossCenterPoint;//连线是否跨过源图元或者目标图元中心点(目标图元) private Rectangle sourceRect;// 初始化矩形图元 private Rectangle targetRect;//初始化目標圖元 //源点位于源图元的边 private String sourceSide; //源点位于目标图元的边 private String targetSide; // 初始化上下左右方向(从原点看) private final Vector DOWN = new Vector(0, -1),//下 UP = new Vector(0, 1), //上 LEFT = new Vector(-1, 0),//左 RIGHT = new Vector(1, 0),//右 LEFT_UP = new Vector(-1,1),//左上 RIGHT_UP = new Vector(1,1),//右上 LEFT_DOWN = new Vector(-1,-1),//左下 RIGHT_DOWN = new Vector(1,-1);//右下 //直线方向数组 private Vector[] straightLineArr = {DOWN,UP,LEFT,RIGHT}; //折线集合 private Vector[] brokenLineArr = {LEFT_UP,RIGHT_UP,LEFT_DOWN,RIGHT_DOWN}; public AIUmlConnectionRouter(IFigure content) { this(content, DEFAULT_SPACE); } public AIUmlConnectionRouter(IFigure content, int space) { Assert.isNotNull(content); Assert.isLegal(space > 0, "空间间距不能为0!"); this.content = content; this.space = space; this.points = new PointList(); } // 是否能连接 private boolean validConn(Connection conn) { if ((conn.getSourceAnchor() == null) || (conn.getTargetAnchor() == null)) return false; return true; } //初始化连线间冲突图元集合 private void conflictRectangleJudge(Connection conn){ //获取到连线中的所有图元 List figures = conn.getChildren(); //这种方式获取不到连线中的所有图元,需要修改,后续完成.... /////////////////////////////////////////////////// //得到当前连线上所有图元 //所有图元周围添加拐点 /////////////////////////////////////////////////// PointList allPoint = conn.getPoints(); //得到冲突图元 for(IFigure f : figures){ Rectangle currentR = f.getBounds().getCopy();//当前图元 f.translateToAbsolute(currentR);// //取出当前连线所有的拐点 for(int i=0;i ){ //最后一个点时,不能再进行检测 if(i == allPoint.size() - 1) break; //两个拐点之间是垂直或者平行的线段,存在有冲突的图元 Point start = allPoint.getPoint(i); Point end = allPoint.getPoint(i+1); //会依次检查当前图元是否跟连线冲突 if(detectionRectangleClash(currentR,start,end)){ //可能存在拐点在冲突图元内(两段线段跟当前图元冲突)の情况 //拐点在冲突图元内的情况 if(!conflictRectangleList.contains(currentR)){ conflictRectangleList.add(currentR);//存为冲突图元 } //拐点在冲突图元外的情况 Point[] segment = {start,end}; conflictPointArrayList.add(segment);//存放冲突线段 //存入关联关系 rectangleLinesRelationMap.put(currentR, conflictPointArrayList); } } } } //检测当前图元是否跟线段冲突 private boolean detectionRectangleClash(Rectangle currentR,Point start,Point end){ boolean result = false; //垂直情况下,跟当前图元是否冲突 if(start.x == end.x){ if((currentR.x <= start.x) && (start.x <= currentR.x+currentR.width) ){ result = true; } } //水平连线,是否跟当前图元冲突 else if(start.y == end.y){ if((start.y >= currentR.y) && (start.y <= currentR.y+currentR.height)){ result = true; } } return result; } /* * 连线路由 */ @Override public void route(Connection conn) { points = conn.getPoints(); points.removeAllPoints();// 清空连线 Point startPoint = getStartPoint(conn).getCopy();// 起点 conn.translateToRelative(startPoint);// 设置连接线起点 points.addPoint(startPoint);// 添加到路由连线点集合 endPoint = getEndPoint(conn).getCopy();// 终点 conn.translateToRelative(endPoint);// 设置连接线终点 // 是否能连接 if (validConn(conn)) { Vector sdirection = getStartDirection(conn);// 得到起始方向 endDirection = getEndDirection(conn);// 终点方向 //连线方向异常情况 if(null == sdirection) return; else if(null == endDirection) endDirection = sdirection; //连线水平或者垂直且源图元跟目标图元没有布局冲突时:调用直线路由算法 if(Arrays.asList(straightLineArr).contains(sdirection) && !sourceAcrossCenterPoint && !targetAcrossCenterPoint) processPoints(startPoint, sdirection, null);//调用直线路由算法 //斜向方向、直线但源图元或者目标图元存在布局冲突:调用折线路由算法 else polyline(startPoint, sdirection) ;//折线路由算法 } // 添加终点到连接线集合 if(null != endPoint) points.addPoint(endPoint); /////////////////////冲突图元应该在所有拐点连线完成之后再判断、绘制//////////////////////// //当前折线上冲突图元检测 conflictRectangleJudge(conn); //TODO 修正冲突图元周围的连线轨迹 // 通过连接点设置线轨迹 conn.setPoints(points.getCopy()); endDirection = null;// 清空终点方向 endPoint = null;// 清空终点位置 //将判断连线障碍物冲突规则重置 rectangleAffirm = 0;// 重置图元计数器 parallelSideTarget = null; parallelSideSource = null; parallelEndSide = false; parallelStartSide = false; sourceAcrossCenterPoint = false; targetAcrossCenterPoint = false; sourceRect = null; targetRect = null; sourceSide = null; targetSide = null; rectangleLinesRelationMap.clear(); conflictRectangleList.clear(); conflictPointArrayList.clear(); } //折线连接 private void polyline(Point startPoint, Vector sdirection) { //1、直线(垂直、水平)情况,源图元或者目标图元一定存在至少一个图元冲突,其余位置可能存在图元冲突 //源图元冲突 if(sourceAcrossCenterPoint){ //连线中是否存在图元冲突 if(conflictRectangleList.isEmpty()){ //连线中只有源图元冲突 //上边界向下连接 if(sdirection == DOWN){ Point first = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE);//向上折点 points.addPoint(first); Point second = new Point((startPoint.x) + (sourceRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 points.addPoint(second); Point third = new Point(second.x,endPoint.y - (DEFAULT_SPACE+1));//向下折点 Point fourth = new Point(startPoint.x,third.y);//向左折点 //如果终点也冲突,不需要当前两个拐点 if(!targetAcrossCenterPoint){ points.addPoint(third); points.addPoint(fourth); } } //下边界向上 else if(sdirection == UP){ Point first = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE);//向下折点 Point second = new Point((startPoint.x) + (sourceRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 Point third = new Point(second.x,endPoint.y + DEFAULT_SPACE+1);//向上折点 Point fourth = new Point(endPoint.x,third.y);//向左折点 points.addPoint(first); points.addPoint(second); if(!targetAcrossCenterPoint){ points.addPoint(third); points.addPoint(fourth); } } //左边界向右 else if(sdirection == RIGHT){ Point first = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y);//向左折点 Point second = new Point(first.x,(sourceRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(startPoint.x + DEFAULT_SPACE + sourceRect.width,second.y);//向右折点 Point fourth = new Point(third.x,startPoint.y);//向上折点 points.addPoint(first); points.addPoint(second); //如果目标图元有冲突,不需要最后两个拐点 if(!targetAcrossCenterPoint){ points.addPoint(third); points.addPoint(fourth); } } //右边界向左 else if(sdirection == LEFT){ Point first = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y);//向右折点 Point second = new Point(first.x,(sourceRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(startPoint.x - DEFAULT_SPACE - sourceRect.width,second.y);//向左折点 Point fourth = new Point(third.x,startPoint.y);//向上折点 points.addPoint(first); points.addPoint(second); //如果目标图元有冲突,不需要最后两个拐点 if(!targetAcrossCenterPoint){ points.addPoint(third); points.addPoint(fourth); } } } //存在连线中布局冲突时 else{ for(Rectangle r : conflictRectangleList){ //TODO 绕开冲突图元 } } } //目标图元冲突 if(targetAcrossCenterPoint){ //连线中是否存在图元冲突 if(conflictRectangleList.isEmpty()){ //连线中只有目标图元冲突 //上边界向下连接(终点在下边界) if(sdirection == DOWN){ Point first = new Point(endPoint.x,endPoint.y + DEFAULT_SPACE);//向下折点 Point second = new Point((startPoint.x) + (sourceRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 Point third = new Point(second.x,targetRect.y - DEFAULT_SPACE);//向上折点 Point fourth = new Point(endPoint.x,third.y);//向左折点 //如果源图元有冲突,不需要头两个拐点 if(!sourceAcrossCenterPoint){ points.addPoint(fourth); points.addPoint(third); } points.addPoint(second); points.addPoint(first); } //下边界向上(终点在上边界) else if(sdirection == UP){ Point first = new Point(endPoint.x,endPoint.y - DEFAULT_SPACE);//向上折点 Point second = new Point(endPoint.x + (targetRect.width / 2+DEFAULT_SPACE),first.y);//向右折点 Point third = new Point(second.x,endPoint.y + targetRect.width + (DEFAULT_SPACE - 1));//向下折点 Point fourth = new Point(endPoint.x,third.y);//向左折点 ///////注意:这里添加拐点的顺序决定了线的形状 //如果源图元有冲突,不需要尾两个拐点 if(!sourceAcrossCenterPoint){ points.addPoint(fourth); points.addPoint(third); } points.addPoint(second); points.addPoint(first); } //左边界向右(终点在右边界) else if(sdirection == RIGHT){ Point first = new Point(endPoint.x + DEFAULT_SPACE,endPoint.y);//向左折点 Point second = new Point(first.x,(targetRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(endPoint.x - DEFAULT_SPACE - sourceRect.width,second.y);//向右折点 Point fourth = new Point(third.x,endPoint.y);//向上折点 //如果源图元有冲突,不需要尾两个拐点 if(!sourceAcrossCenterPoint){ points.addPoint(fourth); points.addPoint(third); } points.addPoint(second); points.addPoint(first); } //右边界向左(终点在左边界) else if(sdirection == LEFT){ Point first = new Point(endPoint.x - DEFAULT_SPACE,endPoint.y);//向左折点 Point second = new Point(first.x,(targetRect.height/2 + DEFAULT_SPACE) + first.y);//向下折点 Point third = new Point(endPoint.x + DEFAULT_SPACE + targetRect.width,second.y);//向右折点 Point fourth = new Point(third.x,endPoint.y);//向上折点 //如果源图元有冲突,不需要尾两个拐点 if(!sourceAcrossCenterPoint){ points.addPoint(fourth); points.addPoint(third); } points.addPoint(second); points.addPoint(first); } }else{ //存在连线中布局冲突 for(Rectangle r : conflictRectangleList){ //TODO 绕开冲突图元 } } } //2、折线情况,可能图元冲突也可能没有图元冲突 if(Arrays.asList(brokenLineArr).contains(sdirection)){ //没有冲突图元的情况 if(conflictRectangleList.isEmpty()){ //***************左上方向******************* if(sdirection == LEFT_UP){ leftUpOrRightDown(startPoint,endPoint,sourceSide,targetSide,sourceRect,targetRect); } //***************左下方向************* else if(sdirection == LEFT_DOWN){ leftDownOrRightUp(startPoint,endPoint,sourceSide,targetSide,sourceRect,targetRect); } //***************右上方向************* else if(sdirection == RIGHT_UP){ leftDownOrRightUp(endPoint,startPoint,targetSide,sourceSide,targetRect,sourceRect); } //***************右下方向************* else if(sdirection == RIGHT_DOWN){ leftUpOrRightDown(endPoint,startPoint,targetSide,sourceSide,targetRect,sourceRect); } } // 存在冲突图元的情况 else{ //取出当前冲突图元跟冲突线段,重新设置拐点 for(Map.Entry > relation : rectangleLinesRelationMap.entrySet()){ Rectangle rectangle = relation.getKey();//conflictPointArrayList List points = relation.getValue(); //通过冲突位置,重新绘制拐点 // TODO } } } } //左上&右下路由算法(右边图元为源图元) private void leftUpOrRightDown(Point startPoint,Point endPoint, String sourceSide,String targetSide, Rectangle sourceRect,Rectangle targetRect){ //有上下左右四个边起点 //上边情况 if(sourceSide.equals("上") && targetSide.equals("右")){ //上右边(两种情况) if(targetRect.y > sourceRect.y + DEFAULT_SPACE){ Point one = new Point(startPoint.x,endPoint.y); points.addPoint(one); }else{ Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(startPoint.x - sourceRect.width - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } } }else if(sourceSide.equals("上") && targetSide.equals("上")){ //上上边 Point one = new Point(startPoint.x,endPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("上") && targetSide.equals("左")){ //上左边 //目标图元在上方是一种连接方法,在下方是另一种连接方法 if((targetRect.y + targetRect.height) <= sourceRect.y){ //目标图元在源图元上方 Point one,two,three; //如果左边图元的下边框在右边图元的上边框+间距之上,走目标图元的下面连线 if(sourceRect.y > (targetRect.y+targetRect.height+DEFAULT_SPACE)){ one = new Point(startPoint.x,endPoint.y + targetRect.height/2 + DEFAULT_SPACE); two = new Point(endPoint.x - DEFAULT_SPACE,one.y); three = new Point(two.x,endPoint.y); }else{ //走目标图元的上边连线 one = new Point(startPoint.x,targetRect.y - DEFAULT_SPACE); two = new Point(targetRect.x - DEFAULT_SPACE,one.y); three = new Point(two.x,endPoint.y); } //通过连线方向控制折点顺序 if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else{ //走目标图元的上边连线 Point one = new Point(startPoint.x,targetRect.y - DEFAULT_SPACE); Point two = new Point(targetRect.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } } }else if(sourceSide.equals("上") && targetSide.equals("下")){ //上下边(两种情况) if(targetRect.y < sourceRect.y){ Point one = new Point(startPoint.x,endPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else{ Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x + targetRect.width/2 + DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y + DEFAULT_SPACE); Point four = new Point(endPoint.x,three.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } } } //左边情况 if(sourceSide.equals("左") && targetSide.equals("右")){ Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("左") && targetSide.equals("上")){ Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y - DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("左") && targetSide.equals("左")){ Point one = null,two = null,three=null,four=null; //1、左边图元下边在右边图元上边界之上 if((targetRect.y+targetRect.height) < (sourceRect.y - DEFAULT_SPACE)){ one = new Point(endPoint.x - DEFAULT_SPACE,startPoint.y); two = new Point(one.x,endPoint.y); } //2、左边图元下边在右边图元的高度范围内 else{ one = new Point(targetRect.x+targetRect.width+DEFAULT_SPACE,startPoint.y); two = new Point(one.x,targetRect.y+targetRect.height+DEFAULT_SPACE); three = new Point(endPoint.x - DEFAULT_SPACE,two.y); four = new Point(three.x,endPoint.y); } if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); if(null != three && null != four){ points.addPoint(three); points.addPoint(four); } }else{ if(null != three && null != four){ points.addPoint(four); points.addPoint(three); } points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("左") && targetSide.equals("下")){ Point one = new Point(endPoint.x,startPoint.y); points.addPoint(one); } //右边情况 if(sourceSide.equals("右") && targetSide.equals("右")){ //两种情况 //1、目标图元的下边在源图元上边的上方 if(sourceRect.y > (targetRect.y + targetRect.height)){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else{ //2、目标图元的下边界在源图元高度范围内 Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,startPoint.y - sourceRect.width/2 - DEFAULT_SPACE); Point three = new Point(sourceRect.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } } }else if(sourceSide.equals("右") && targetSide.equals("上")){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y - DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("右") && targetSide.equals("左")){ //1、目标图元下边界在源图元上边界上面 if((targetRect.y+targetRect.height) < sourceRect.y - DEFAULT_SPACE){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,sourceRect.y - DEFAULT_SPACE); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else{ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y - targetRect.width/2 - DEFAULT_SPACE); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } } }else if(sourceSide.equals("右") && targetSide.equals("下")){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y + DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } } //下边情况 if(sourceSide.equals("下") && targetSide.equals("右")){ Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(one.x - sourceRect.width - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("下") && targetSide.equals("上")){ Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(one.x - sourceRect.width - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y - DEFAULT_SPACE); Point four = new Point(endPoint.x,three.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("下") && targetSide.equals("左")){ Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("下") && targetSide.equals("下")){ Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_UP){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } } } //左下&右上路由算法 private void leftDownOrRightUp(Point startPoint,Point endPoint, String sourceSide,String targetSide, Rectangle sourceRect,Rectangle targetRect){ //异常处理 if(null==sourceSide || null==targetSide || null==sourceRect || null==targetRect) return; //左边图元在右边图元下边 if(sourceSide.equals("下") && targetSide.equals("右")){ Point one = new Point(startPoint.x,endPoint.y); points.addPoint(one); }else if(sourceSide.equals("下") && targetSide.equals("上")){ Point one = new Point(startPoint.x,endPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("下") && targetSide.equals("左")){ Point one = new Point(startPoint.x,startPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("下") && targetSide.equals("下")){ Point one = new Point(startPoint.x,endPoint.y + DEFAULT_SPACE); Point two = new Point(endPoint.x,one.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } } //右边图元右边 if(sourceSide.equals("右") && targetSide.equals("右")){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("右") && targetSide.equals("上")){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,endPoint.y - DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("右") && targetSide.equals("左")){ //1、目标图元上边界在源图元下边界上面 if((sourceRect.y + sourceRect.height) > targetRect.y){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,endPoint.y + DEFAULT_SPACE + targetRect.height/2); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else{ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,startPoint.y + DEFAULT_SPACE + sourceRect.height/2); Point three = new Point(endPoint.x - DEFAULT_SPACE,two.y); Point four = new Point(three.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } } }else if(sourceSide.equals("右") && targetSide.equals("下")){ Point one = new Point(startPoint.x + DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x ,endPoint.y + DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } } //右边图元上边 if(sourceSide.equals("上") && targetSide.equals("右")){ Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x + DEFAULT_SPACE ,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("上") && targetSide.equals("上")){ Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x ,one.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("上") && targetSide.equals("左")){ Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x - DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("上") && targetSide.equals("下")){ Point one = new Point(startPoint.x,startPoint.y - DEFAULT_SPACE); Point two = new Point(endPoint.x + targetRect.width/2 + DEFAULT_SPACE,one.y); Point three = new Point(two.x,endPoint.y + DEFAULT_SPACE); Point four = new Point(endPoint.x,three.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); points.addPoint(four); }else{ points.addPoint(four); points.addPoint(three); points.addPoint(two); points.addPoint(one); } } //右边图元左边 if(sourceSide.equals("左") && targetSide.equals("右")){ Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y); Point two = new Point(one.x,endPoint.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); }else{ points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("左") && targetSide.equals("上")){ Point one = new Point(endPoint.x,startPoint.y); points.addPoint(one); }else if(sourceSide.equals("左") && targetSide.equals("左")){ Point one = null,two = null,three = null,four = null; //1、右边图元中心点在左边图元上边界的上面 if(startPoint.y < targetRect.y){ one = new Point(endPoint.x - DEFAULT_SPACE,startPoint.y); two = new Point(one.x,endPoint.y); }else{ one = new Point(targetRect.x+targetRect.width+DEFAULT_SPACE,startPoint.y); two = new Point(one.x,targetRect.y - DEFAULT_SPACE); three = new Point(endPoint.x - DEFAULT_SPACE,two.y); four = new Point(three.x,endPoint.y); } if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); if(null != three && null != four){ points.addPoint(three); points.addPoint(four); } }else{ if(null != three && null != four){ points.addPoint(four); points.addPoint(three); } points.addPoint(two); points.addPoint(one); } }else if(sourceSide.equals("左") && targetSide.equals("下")){ Point one = new Point(startPoint.x - DEFAULT_SPACE,startPoint.y ); Point two = new Point(one.x,endPoint.y + DEFAULT_SPACE); Point three = new Point(endPoint.x,two.y); if(endDirection == LEFT_DOWN){ points.addPoint(one); points.addPoint(two); points.addPoint(three); }else{ points.addPoint(three); points.addPoint(two); points.addPoint(one); } } } // 设置上下左右方向 private void processPoints(Point startPoint, Vector direction, Rectangle parallelObs) { if (direction == UP) processUp(startPoint, parallelObs); else if (direction == DOWN) processDown(startPoint, parallelObs); else if (direction == LEFT) processLeft(startPoint, parallelObs); else if(direction == RIGHT) processRight(startPoint, parallelObs); } // 设置向右 private void processRight(Point startPoint, Rectangle parallelObs) { Point newStartPoint = new Point(startPoint);// 起始位置 //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_xd = 0; Rectangle obstracle = null;//布局冲突的图元 List list = content.getChildren();// 当前图元的子 // 遍历每个图元 for (IFigure f : list) { Rectangle fr = f.getBounds();// 当前子图元矩形 // 用户在矩形中连线,不操作 if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || fr.x > endPoint.x) continue; // 用户在矩形外连线(起点和终点没有同时在一个矩形上) int xd = fr.x - startPoint.x;// 矩形左边跟起始点x方向距离(正数:左侧;负数:右侧) // 如果当前连线起点在图元上 if (xd > 0 && fr.y <= startPoint.y && (fr.y + fr.height) >= startPoint.y) { // 图元之间水平距离控制 if (xd < min_xd || min_xd == 0) { min_xd = xd; obstracle = fr;// 最后一个子图元 conflictRectangleList.add(obstracle); } } } if (min_xd == 0) { // no obstacles if (parallelObs == null) { // y坐标直线 if (newStartPoint.y == endPoint.y) return; } else { // 连线未到目标图元,继续折叠 if (newStartPoint.x < parallelObs.x) newStartPoint.x -= (parallelObs.x - newStartPoint.x) / 2;// x坐标对半弯曲 } // 连线未到目标图元 if (newStartPoint.x < endPoint.x) { // 如果方向向上或者向下 if (isVertical(endDirection, RIGHT)) newStartPoint.x = endPoint.x;// 重新设置起始x坐标 else { // 如果方向向右 if (endDirection.equals(RIGHT)) { newStartPoint.x = endPoint.x + space;// 新起始点坐标 = 终点坐标 + // 距离障碍物距离 } else // 方向向左 newStartPoint.x += (endPoint.x - newStartPoint.x) / 2;// 折半弯曲 } } } // 跟图元还有水平间距 else { int x = newStartPoint.x + min_xd - space;// 重置水平方向 if (x < newStartPoint.x) x = newStartPoint.x + min_xd / 2; newStartPoint.x = x; } if (parallelObs != null) { if (newStartPoint.x >= parallelObs.x && newStartPoint.x <= parallelObs.x + parallelObs.width) newStartPoint.x = parallelObs.x + parallelObs.width + space; } if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint); // next Vector newDirection = UP; if (obstracle == null) { if (endPoint.y > newStartPoint.y) newDirection = DOWN; } else { if (endPoint.y > obstracle.y) newDirection = DOWN; } processPoints(newStartPoint, newDirection, obstracle); } // 处理向左的连接 private void processLeft(Point startPoint, Rectangle parallelObs) { Point newStartPoint = new Point(startPoint); //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_xd = 0; Rectangle obstracle = null;// 初始化障碍物 List list = content.getChildren(); for (IFigure f : list) { Rectangle fr = f.getBounds(); // 起始点和结束点在当前图元里面,不绘制连线 // ////////////////这里代表有障碍物,需要绘制绕开障碍物的连线折点/////////////////////////// if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || (fr.x + fr.width) <= endPoint.x) { continue; // TODO 注释掉continue,绘制避开障碍物的折点 } int xd = startPoint.x - fr.x - fr.width; if (xd > 0 && fr.y <= startPoint.y && (fr.y + fr.height) >= startPoint.y) { if (xd < min_xd || min_xd == 0) { min_xd = xd; obstracle = fr; conflictRectangleList.add(obstracle); } } } if (min_xd == 0) { // no obstacles // not need bend point if (parallelObs == null) { if (newStartPoint.y == endPoint.y) return; } else { if (newStartPoint.x > parallelObs.x + parallelObs.width) newStartPoint.x -= (newStartPoint.x - parallelObs.x - parallelObs.width) / 2; } if (newStartPoint.x > endPoint.x) { // 水平方向 if (isVertical(endDirection, LEFT)) newStartPoint.x = endPoint.x;// 直接连接到结束的坐标点(设置横线折点x坐标) else { // 垂直方向 if (endDirection.equals(LEFT)) { newStartPoint.x = endPoint.x - space; } else newStartPoint.x += (newStartPoint.x - endPoint.x) / 2; } } } else { int x = newStartPoint.x + min_xd - space; if (x < newStartPoint.x) x = newStartPoint.x + min_xd / 2; newStartPoint.x = x; } if (parallelObs != null) { if (newStartPoint.x >= parallelObs.x && newStartPoint.x <= (parallelObs.x + parallelObs.width)) { newStartPoint.x = parallelObs.x - space; } } if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint);// 添加转折点坐标 // next row point Vector newDirection = UP;// 初始化连线方向 if (obstracle == null) { if (endPoint.y > newStartPoint.y) newDirection = DOWN;// 判断真实的连线方向 } else { if (endPoint.y >= obstracle.y) newDirection = DOWN; } processPoints(newStartPoint, newDirection, obstracle); } // 处理向下的连接 private void processDown(Point startPoint, Rectangle parallelObs) { Point newStartPoint = new Point(startPoint);// 建立起始点位置 //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_yd = 0; Rectangle obstracle = null;// 初始化障碍图元(默认没有) // ///////////这里的图元获取不正确////////////// List list = content.getChildren();// 得到当前连线中子图元 for (IFigure f : list) { Rectangle fr = f.getBounds();// 当前图元的矩形 // 如果在当前单个图元绘制,不建立连接 if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || fr.y > endPoint.y) continue; int yd = fr.y - startPoint.y;// 当前起始点跟当前图元垂直方向距离(为负数时是起始图元,正数可能存在布局冲突) // 判断当前图元是否是障碍物 // ////////////会把目标图元也判定成障碍物,需要修改////////////////// if (yd > 0 && fr.x <= startPoint.x && (fr.x + fr.width) >= startPoint.x) { if (yd < min_yd || min_yd == 0) { min_yd = yd; obstracle = fr;// 设置障碍图元 conflictRectangleList.add(obstracle); } } } // 如果没有子图元或者没有障碍物 if (min_yd == 0) { // 不需要去弯曲其他点 if (parallelObs == null) { if (newStartPoint.x == endPoint.x) return; } else { // 设置第一个弯曲点 if (parallelObs.y > startPoint.y) newStartPoint.y += (parallelObs.y - startPoint.y) / 2; } // 如果还没有连线到结束点 if (newStartPoint.y < endPoint.y) { // 当前连线绘制方向是水平方向 if (isVertical(endDirection, DOWN)) { newStartPoint.y = endPoint.y; // 重新设置起始点y坐标 // TODO avoid itself } else { // 当前方向是向下 if (endDirection.equals(DOWN)) newStartPoint.y = startPoint.y + space;// 转折点y坐标设置 else newStartPoint.y += (endPoint.y - newStartPoint.y) / 2;// 取中间点位置作为折点 } } } else { // 存在障碍物情况 int y = newStartPoint.y + min_yd - space; if (y < newStartPoint.y) y = newStartPoint.y + min_yd / 2; newStartPoint.y = y; } // 父图元、障碍物都不为空 if (parallelObs != null) { // 起始y坐标在父图元内 if (newStartPoint.y > parallelObs.y && newStartPoint.y < parallelObs.y + parallelObs.height) newStartPoint.y = parallelObs.y + parallelObs.height + space;// 转折点y坐标赋值 } // 添加转折点到连线集合 if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint);// 依次添加转折点 // 下一个转折点 Vector newDirection = LEFT;// 初始化方向向左 // 没有障碍物情况 if (obstracle == null) { if (endPoint.x > newStartPoint.x) newDirection = RIGHT;// 连线方向判定 } else { // 存在障碍物情况 if (endPoint.x > (obstracle.x + obstracle.width)) newDirection = RIGHT; } // 调用折线算法,重新设置转折点 processPoints(newStartPoint, newDirection, obstracle); } // 是否垂直 boolean isVertical(Vector v1, Vector v2) { double val = v1.x * v2.x + v1.y * v2.y; if (val == 0) return true; return false; } // 当前点位置是否在矩形中 boolean containPoint(Rectangle r, Point p) { return p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height; } // 处理向上的连接 private void processUp(Point startPoint, Rectangle parallelObs) { Point newStartPoint = new Point(startPoint); //源图元冲突检测 monitorStartCollide(startPoint); //目标图元冲突检测 monitorEndCollide(endPoint); int min_yd = 0; Rectangle obstracle = null; List list = content.getChildren(); for (IFigure f : list) { Rectangle fr = f.getBounds(); if (containPoint(fr, endPoint) || containPoint(fr, startPoint) || (fr.y + fr.height) <= endPoint.y) continue; int yd = startPoint.y - fr.y - fr.height; if (yd > 0 && fr.x <= startPoint.x && (fr.x + fr.width) >= startPoint.x) { if (yd < min_yd || min_yd == 0) { min_yd = yd; obstracle = fr; conflictRectangleList.add(obstracle); } } } if (min_yd == 0) { // no obstacles // not need bend point if (parallelObs == null) { if (newStartPoint.x == endPoint.x) return; } else { if (newStartPoint.y > parallelObs.y + parallelObs.height) newStartPoint.y -= (newStartPoint.y - parallelObs.y - parallelObs.height) / 2; } if (newStartPoint.y > endPoint.y) { if (isVertical(endDirection, UP)) newStartPoint.y = endPoint.y; else { if (endDirection.equals(UP)) { newStartPoint.y = endPoint.y - space; } else newStartPoint.y -= (newStartPoint.y - endPoint.y) / 2; } } } else { int y = newStartPoint.y - min_yd + space; if (y > newStartPoint.y) y = newStartPoint.y - min_yd / 2; newStartPoint.y = y; } if (parallelObs != null) { if (newStartPoint.y >= parallelObs.y && newStartPoint.y <= parallelObs.y + parallelObs.height) newStartPoint.y = parallelObs.y - space; } if (!newStartPoint.equals(startPoint)) points.addPoint(newStartPoint); // next row point Vector newDirection = LEFT; if (obstracle == null) { if (endPoint.x > newStartPoint.x) newDirection = RIGHT; } else { if (endPoint.x >= obstracle.x) newDirection = RIGHT; } processPoints(newStartPoint, newDirection, obstracle); } //得到当前连线的斜向方向 private Vector getSlantDirection(Point p){ Vector direction = null; //右上方 if(endPoint.x > p.x && endPoint.y < p.y){ direction = RIGHT_UP; return direction; } //右下方 if(endPoint.x > p.x && endPoint.y > p.y){ direction = RIGHT_DOWN; return direction; } //左上方 if(endPoint.x < p.x && endPoint.y < p.y){ direction = LEFT_UP; return direction; } //左下方 if(endPoint.x < p.x && endPoint.y > p.y){ direction = LEFT_DOWN; return direction; } return direction; } // 得到当前线条的方向 protected Vector getDirection(Rectangle r, Point p, Connection conn) { // //////////////////////////////////////////////////// // 当前连线上只有两个图元: // // 第一次进来的是 源图元 // // 第二次进来的是目标图元 // // //////////////////////////////////////////////////// rectangleAffirm++; //1:源图元 ; 2:目标图元 Vector direction = LEFT;// 初始化方向 // 如果当前点没有在当前矩形里面,退出 if (!containPoint(r, p)) return null; // 当前连线矩形的四个顶点坐标 Point leftTop = new Point(r.x, r.y), leftBottom = new Point(r.x, (r.y + r.height)), rightTop = new Point((r.x + r.width), r.y), rightBottom = new Point((r.x + r.width), (r.y + r.height)); // 根据图元类别调用判定方向的方法 // *****************************源图元***********************************// //起点坐标跟边角坐标比较 if (rectangleAffirm == 1) { // 在上边界的情况 if (p.y == leftTop.y) { //起始边 sourceSide = "上"; //方向判定 if (endPoint.y == p.y && p.x < endPoint.x) { direction = RIGHT; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "上";// 跟上边界平行 return direction; } if (endPoint.y == p.y && p.x > endPoint.x) { parallelStartSide = true; // 平行于起始边界 parallelSideSource = "上";// 跟上边界平行 return direction; } if (p.x == endPoint.x && endPoint.y > p.y) { direction = DOWN; sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; } if (p.x == endPoint.x && endPoint.y < p.y) { direction = UP; return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } // 在下边界的情况 if ((p.y == rightBottom.y) ||(p.y == rightBottom.y-1)) { //设置起始边 sourceSide = "下"; //方向判定 //垂直、水平方向 if (endPoint.x == p.x && endPoint.y < leftTop.y) { direction = UP; sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; } if (endPoint.x == p.x && endPoint.y > leftBottom.y) { direction = DOWN; return direction; } if (endPoint.y == p.y && rightBottom.x > p.x) { direction = RIGHT; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "下";// 跟下边界平行 return direction; } if (endPoint.y == p.y && leftBottom.x < p.x) { parallelStartSide = true; // 平行于起始边界 parallelSideSource = "下";// 跟下边界平行 return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } // 在左边界的情况 if (p.x == leftTop.x) { //设置起始边 sourceSide = "左"; //方向判定 //水平、垂直方向情况 if (leftTop.x == endPoint.x && leftTop.y <= p.y) { direction = UP; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "左"; return direction; } if (leftTop.x == endPoint.x && rightBottom.y >= p.y) { direction = DOWN; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "左"; return direction; } if (endPoint.y == p.y && endPoint.x < leftTop.x) { return direction; } if ((endPoint.y-1 == p.y || p.y==endPoint.y) && endPoint.x > rightBottom.x) { direction = RIGHT; sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } // 在右边界的情况 if (p.x == rightTop.x) { //设置起始边 sourceSide = "右"; //方向判定 //水平、垂直 if (rightTop.x == endPoint.x && rightTop.y <= p.y) { direction = UP; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "右"; return direction; } if (rightTop.x == endPoint.x && rightBottom.y >= p.y) { direction = DOWN; parallelStartSide = true; // 平行于起始边界 parallelSideSource = "右"; return direction; } if ((endPoint.y == p.y || endPoint.y+1 == p.y) && endPoint.x < leftTop.x) { sourceAcrossCenterPoint = true;//源图元起点冲突 return direction; } if (endPoint.y == p.y && endPoint.x > rightBottom.x) { direction = RIGHT; return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } } // ********************目标图元*****************************// else { if(null == sourceRect || null == targetRect) return null; //源图元、目标图元的中心点 Point sourceCentPoint = new Point(sourceRect.x + sourceRect.width/2,sourceRect.y + sourceRect.height/2); Point targetCentPoint = new Point(targetRect.x + targetRect.width/2,targetRect.y + targetRect.height/2); //在上边界情况 if (p.y == leftTop.y) { //设置终点边 targetSide = "上"; //方向判定 //水平、垂直 if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x) { direction = RIGHT; parallelEndSide = true; // 平行于起始边界 parallelSideTarget = "上";// 跟上边界平行 return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x) { parallelEndSide = true; // 平行于边界 parallelSideTarget = "上";// 跟上边界平行 return direction; } if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) { direction = DOWN; return direction; } if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) { direction = UP; targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } // 在下边界的情况 if (p.y == rightBottom.y || p.y==rightBottom.y-1) { //设置终点边 targetSide = "下"; //方向判定 //水平、垂直 if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) { direction = UP; return direction; } if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) { direction = DOWN; targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x) { direction = RIGHT; parallelEndSide = true; // 平行于边界 parallelSideTarget = "下";// 跟下边界平行 return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x) { parallelEndSide = true; // 平行于边界 parallelSideTarget = "下";// 跟下边界平行 return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } // 在左边界的情况 if (p.x == leftTop.x) { //设置终点边 targetSide = "左"; //方向判定 //直线方向 if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x && sourceSide.equals(targetSide)) { direction = UP; parallelEndSide = true; // 平行于边界 parallelSideTarget = "左"; return direction; } if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x && sourceSide.equals(targetSide)) { direction = DOWN; parallelEndSide = true; // 平行于边界 parallelSideTarget = "左"; return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x && sourceSide.equals(targetSide)) { targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x && sourceSide.equals(targetSide)) { direction = RIGHT; return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } // 在右边界的情况 if (p.x == rightTop.x) { //设置终点边 targetSide = "右"; //方向判定 //直线方向 if (sourceCentPoint.y > targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x) { direction = UP; parallelEndSide = true; // 平行于边界 parallelSideTarget = "右"; return direction; } if (sourceCentPoint.y < targetCentPoint.y && targetCentPoint.x == sourceCentPoint.x ) { direction = DOWN; parallelEndSide = true; // 平行于边界 parallelSideTarget = "右"; return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x < sourceCentPoint.x) { return direction; } if (sourceCentPoint.y == targetCentPoint.y && targetCentPoint.x > sourceCentPoint.x) { direction = RIGHT; targetAcrossCenterPoint = true;//终点图元跟连线冲突 return direction; } //斜向方向的情况 direction = getSlantDirection(p); if(null != direction) return direction; } } return direction; } // 得到当前连接线起始方向 protected Vector getStartDirection(Connection conn) { ConnectionAnchor anchor = conn.getSourceAnchor();// 获取源连接锚点 Point p = getStartPoint(conn);// 通过连接线获取到起始点坐标 // 如果获取不到源连接锚点,自定义一个矩形图元 if (anchor.getOwner() == null) sourceRect = new Rectangle(p.x - 1, p.y - 1, 2, 2); else { sourceRect = conn.getSourceAnchor().getOwner().getBounds().getCopy();// 得到当前矩形 conn.getSourceAnchor().getOwner().translateToAbsolute(sourceRect);// 转换当前矩形 } return getDirection(sourceRect, p, conn); } // 得到当前连线的结束方向 protected Vector getEndDirection(Connection conn) { ConnectionAnchor anchor = conn.getTargetAnchor(); Point p = getEndPoint(conn); // Point p = endPoint; if (anchor.getOwner() == null) targetRect = new Rectangle(p.x - 1, p.y - 1, 2, 2); else { targetRect = conn.getTargetAnchor().getOwner().getBounds().getCopy(); conn.getTargetAnchor().getOwner().translateToAbsolute(targetRect); } return getDirection(targetRect, p, conn); } // 起点跟源图元冲突时 private void monitorStartCollide(Point startPoint) { if (parallelStartSide) { Point bendPoint = null;// 初始化弯曲点 int bendPointSpace = 10;// 初始化点间距 // 上边界 if ("上".equals(parallelSideSource)) { bendPoint = new Point(startPoint.x, startPoint.y - bendPointSpace); points.addPoint(bendPoint); return; } // 下边界 if ("下".equals(parallelSideSource)) { bendPoint = new Point(startPoint.x, startPoint.y + bendPointSpace); points.addPoint(bendPoint); return; } // 左边界 if ("左".equals(parallelSideSource)) { bendPoint = new Point(startPoint.x - bendPointSpace, startPoint.y); points.addPoint(bendPoint); return; } // 右边界 if ("右".equals(parallelSideSource)) { bendPoint = new Point(startPoint.x + bendPointSpace, startPoint.y); points.addPoint(bendPoint); return; } } } // 终点连线跟源图元冲突时 private void monitorEndCollide(Point endPoint) { if (parallelEndSide) { Point bendPoint = null;// 初始化弯曲点 int bendPointSpace = 10;// 初始化点间距 // 上边界 if ("上".equals(parallelSideTarget)) { bendPoint = new Point(endPoint.x, endPoint.y - bendPointSpace); points.addPoint(bendPoint); return; } // 下边界 if ("下".equals(parallelSideTarget)) { bendPoint = new Point(endPoint.x, endPoint.y + bendPointSpace); points.addPoint(bendPoint); return; } // 左边界 if ("左".equals(parallelSideTarget)) { bendPoint = new Point(endPoint.x - bendPointSpace, endPoint.y); points.addPoint(bendPoint); return; } // 右边界 if ("右".equals(parallelSideTarget)) { bendPoint = new Point(endPoint.x + bendPointSpace, endPoint.y); points.addPoint(bendPoint); return; } } } }