仿VISIO连线

说明:

  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;
            }
        }
    }

}

 

你可能感兴趣的:(仿VISIO连线)