2012-04-02 2 views
4

я пытался понять этого дема работу: http://raphaeljs.com/graffle.html Но я не могу понять этот цикл в graffle.js исходного кода:RaphaelJS форма Drag & падение дем

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

Перед этим циклом цикла создается один массив, который содержит 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 на каждую точку на obj2. Мы стремимся к тому, чтобы измерить (сорт) расстояние между теми точками, которые мы считаем подходящими для соединения.

// 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

  • мы имеем две точки на одной стороне

    (I == J - 4)

OR

  • мы не имеем 3 и 6, или если мы делаем пункт 3 лежит слева от точки 6

    ((я! = 3 & & J! = 6) || р [я] .x < р [J] .x) & &

  • мы не имеем 2 и 7, или если мы делаем точка 2 лежит справа от точки 6

    ((я ! = 2 & & J! = 7) || р [я] .x> р [у] .x) & &

  • мы не имеем 0 и 5, или если мы делаем точку 0 лежит выше пункт 5

    ((i! = 0 & & j! = 5) || р [я] .y> р [у] .y) & &

  • мы не имеем 1 и 4, или если мы делаем точка 1 лежит ниже точки 4

    ((я! = 1 & & j! = 4) || p [i] .y < p [j].у)

ТОГДА

  • это соединение действительно, делать дешевую меру, как близко точки (ау + дх) и положить эти правильные соединения в массиве. Мы выберем «самое короткое» расстояние позже.

only if connections

Если точки испытывается не один из этих противоположных пар, то измерить его до сих пор. Это все, чтобы остановить путь от того, чтобы быть внутри двух объектов, если мы можем ему помочь. Первый тест, чтобы увидеть, находятся ли они на одной стороне, - это дешевый способ пропустить весь этот противоположный тестовый код. После того, как мы измерили все точки, которые разрешены, мы выбираем наименьший dy + dx и используем эти точки для рисования пути.

Смежные вопросы