js之拖動節點放置鏈路上

在作項目的時候,甲方要求節點之間的鏈接關係若是不是直接相連,而是經過一系列網絡設備如路由器才存在的鏈接關係。那麼把中間這些路由器封裝起來用一個雲節點表示,在畫布上拖動這個雲節點到鏈路上,而後將本來節點之間的鏈路刪除,新建兩條鏈路,分別與該雲節點相連,以下圖所示。node

在思考這個問題的時候,雲節點拖動的時候判斷是否通過某條線路?首先遍歷全部的鏈路,獲得鏈路的兩端節點的座標,分別爲(x1,y1),(x2,y2)。咱們把節點的兩端看做質點,雲節點至關於一個矩形,這時問題就描述成一個數學問題了:如何判斷一個矩形跟一條線段有交點?網絡

跟同窗交流的時候,她提出一種方案,由於項目須要,這裏的矩形基本上是正方形。計算該正方形的外接圓,判斷圓心到線段的距離和圓的半徑比較。若是大於半徑則不相交,若是等於則相切,若是小於則相交。可是若是正方形的邊比較大的,仍是有必定的偏差的。因此就沒采用這種方法。code

方案二:線段與矩形相交,則線段必定與矩形的兩條對角線中的至少一條對角線有交點。那麼反推,線段與矩形的對角線有交點可不能夠斷定,矩形與線段有交點呢?答案是能夠的。其實咱們能夠先這樣,將線段假設成直線,計算它的直線方程,爲了不除法,應這樣設定:路由

(y1-y2)x+(x2-x1)y+x1y2-x2y1=0

而後判斷對角線是否與該直線相交,將對角線的兩個點座標帶入直線方程,乘積<=0則相交。接下來則去除矩形在線段某一側的狀況就ok了,代碼以下:
get

var links = scene.links;
for (var i in links) 
    if (links[i].nodeA && links[i].nodeZ) {
    //線段的端點座標
        var x1 = links[i].nodeA.x;
    	var y1 = links[i].nodeA.y;
    	var x2 = links[i].nodeZ.x;
    	var y2 = links[i].nodeZ.y;
    	//直線方程設(y1-y2)x+(x2-x1)y+x1y2-x2y1=0
    	var a = y1-y2;
    	var b = x2-x1;
    	var c = x1*y2-x2*y1;
	if ((a*target.x+b*target.y+c)*(a*(target.x+target.width)+b*(target.y+target.height)+c)<=0 || 
	(a*target.x+b*(target.y+target.height)+c)*(a*(target.x+target.width)+b*target.y+c)<=0) {
	if ((x1<target.x && x2<target.x) || 
	(x1>(target.x+target.width) && x2>(target.x+target.width)) || 
	((y1<target.y)&&(y2<target.y)) || 
	((y1>(target.y+target.width)) && (y2>(target.y+target.width)))) {
        }
	else { //相交
	    break;
	}
    }
}

其實這個代碼有個bug,就是若是這兩條鏈路相交,而云節點拖動到交點處又該如何處理呢?數學

相關文章
相關標籤/搜索