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