2012-04-02 144 views
4

我试图了解这个演示的工作:http://raphaeljs.com/graffle.html 但我不明白这个循环中,graffle.js源代码:RaphaelJS形状拖放演示

for (var i = 0; i < 4; i++) { 
    for (var j = 4; j < 8; j++) { 
     var dx = Math.abs(p[i].x - p[j].x), 
      dy = Math.abs(p[i].y - p[j].y); 
     if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) { 
      dis.push(dx + dy); 
      d[dis[dis.length - 1]] = [i, j]; 
     } 
    } 
} 

可有人向我解释它做什么,它是如何工作的?谢谢。

回答

12

在此for循环之前,构造一个单个数组,其中包含路径可以从中加入的每个对象的4个位置。

var bb1 = obj1.getBBox(), 
    bb2 = obj2.getBBox(), 
    p = [{x: bb1.x + bb1.width/2, y: bb1.y - 1}, 
    {x: bb1.x + bb1.width/2, y: bb1.y + bb1.height + 1}, 
    {x: bb1.x - 1, y: bb1.y + bb1.height/2}, 
    {x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height/2}, 
    {x: bb2.x + bb2.width/2, y: bb2.y - 1}, 
    {x: bb2.x + bb2.width/2, y: bb2.y + bb2.height + 1}, 
    {x: bb2.x - 1, y: bb2.y + bb2.height/2}, 
    {x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height/2}], 

所以你有2个对象obj1和obj2,你想要连接在一起的路径。这个路径被吸引到的物体的边缘的4个可能的点中的任意一个:

path positions

在那里我有标记基于其在标普指数的顶点。现在我们将循环obj1上的点和obj2上的点,使用i作为obj1上的点的索引,并使用j作为obj2上的点。这样我们就obj1上的每个点测试obj1上的每个点。我们想要做的就是测量(排序)只有那些我们认为适合连接的点之间的距离。

// For each pair of adjacent points 
for (var i = 0; i < 4; i++) { 
    for (var j = 4; j < 8; j++) { 

     // Calculate the difference in the X and Y direction (dy and dx) 
     var dx = Math.abs(p[i].x - p[j].x), 
      dy = Math.abs(p[i].y - p[j].y); 

      // If the points are on the same side OR 
     if ((i == j - 4) || 
      // If the points are **not** opposites (3 and 6) or (2 and 7) or (0 and 5) or (1 and 4) 
      // or, if we have 3 and 6, and the obj1 is to the left side of obj2 
      // or, if we have 2 and 7, and the obj1 is to the right side of obj2 
      // or, if we have 0 and 5, and the obj1 is higher than obj2 
      // or, if we have 1 and 4, and the obj1 is lower than obj2 

      (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) { 
      // push the sum of dx and dy onto out distance list 
      // and push the associated pair of points onto the d list. 
      // This is so we can pick the sort-of-closest pair of points. 
      dis.push(dx + dy); 
      d[dis[dis.length - 1]] = [i, j]; 
     } 
    } 
} 

因此打破,如果大的语句

IF

  • 我们在同一侧有两个点

    (我==的J - 4)

  • 我们没有3和6,或者如果我们做点3个位于6点

    ((我!= 3 & & j的左侧!= 6)|| P [I] .X < P [j]的.X)& &

  • 我们没有图2和7,或者如果我们做点2个位于6点

    ((i的右!= 2 & & J 1 = 7)|| p [I] .X> p [j]的.X)& &

  • 我们没有0和5,或者如果我们做点0以上在于点5

    ((i!= 0 & & j!= 5)|| P [I] .Y> P [j]的.Y)& &

  • 我们没有1和4,或者如果我们做点1个位于下方点4

    (第(i!= 1 & & j!= 4)|| p [i] .y < p [j]。Y)

THEN

  • 这方面是有效的,做点的接近程度(DY + DX)便宜的措施,把这些有效的连接在数组中。稍后我们将选择“最短”​​距离。

only if connections

如果被测试的点不是这些相反对之一,然后还要测量它。如果我们能够提供帮助的话,这就是为了阻止两个物体内部的路径。首先测试它们是否在同一侧是跳过所有这些相反测试代码的廉价方法。在我们测量了所有允许的点后,我们选择最小的dy + dx并使用这些点绘制路径。