Javascript 布局算法中避免振荡移动

Javascript 布局算法中避免振荡移动,javascript,algorithm,layout,geometry,Javascript,Algorithm,Layout,Geometry,以下是这个问题的答案: 我有一个问题,移动一个框会导致它与另一个框重叠,而当前的算法只会将第一个框移回(几乎)它原来的方向,从而导致它再次与第一个框重叠,以此类推。有没有避免这种情况的好方法?我想记住上次的向量,并以某种方式将其与新提议的移动相结合可能是解决方案 这里有一把简单的小提琴: 请注意,一个长方体是如何移动的,但随后与另一个长方体重叠,因此该长方体再次以相反的方向向后移动,并且在6个循环后,仍然重叠 下面是add方法的代码-它将框添加到列表中,检查当前成员是否有其他LAP:

以下是这个问题的答案:

我有一个问题,移动一个框会导致它与另一个框重叠,而当前的算法只会将第一个框移回(几乎)它原来的方向,从而导致它再次与第一个框重叠,以此类推。有没有避免这种情况的好方法?我想记住上次的向量,并以某种方式将其与新提议的移动相结合可能是解决方案

这里有一把简单的小提琴:

请注意,一个长方体是如何移动的,但随后与另一个长方体重叠,因此该长方体再次以相反的方向向后移动,并且在6个循环后,仍然重叠

下面是add方法的代码-它将框添加到列表中,检查当前成员是否有其他LAP:

    self.add = function (item, iteration) {
        // check intersections with existing boxes
        iteration = iteration || 0;
        if (iteration < 6) {
            for (var i = 0; i < boxes.length; i++) {
                var stationary = boxes[i];
                var boundsA = getBounds(item);
                var boundsB = getBounds(stationary);
                if (doesIntersect(boundsA, boundsB)) {
                    item.elem.addClass("overlapped");
                    // move item
                    // Find vector from mid point of one box to the other
                    var centerA = {
                        x: item.x + item.width / 2,
                        y: item.y + item.height / 2
                    };
                    var centerB = {
                        x: stationary.x + stationary.width / 2,
                        y: stationary.y + stationary.height / 2
                    };
                    var line = {
                        x1: centerA.x,
                        y1: centerA.y,
                        x2: centerB.x,
                        y2: centerB.y
                    }
                    var vector = {
                        x: Math.min(item.x + item.width, stationary.x + stationary.width) - Math.max(item.x, stationary.x),
                        y: Math.min(item.y + item.height, stationary.y + stationary.height) - Math.max(item.y, stationary.y)
                    };
                    var signX = line.x1 - line.x2 > 0 ? 1 : -1;
                    var signY = line.y1 - line.y2 > 0 ? 1 : -1;
                    item.x = item.x + vector.x * signX;
                    item.y = item.y + vector.y * signY;
                    item.elem.offset({
                        left: item.x,
                        top: item.y
                    });     
                    return self.add(item, iteration + 1);
                }
            }
        }
        boxes.push(item);
    }
self.add=函数(项目,迭代){
//检查与现有框的交点
迭代=迭代| | 0;
if(迭代<6){
对于(变量i=0;i0?1:-1;
var signY=line.y1-line.y2>0?1:-1;
item.x=item.x+vector.x*signX;
item.y=item.y+vector.y*signY;
项目要素抵销({
左:第x项,
顶部:item.y
});     
返回self.add(项目,迭代+1);
}
}
}
盒子。推(物品);
}

为什么不使用迭代过程

  • 如我所见,您希望重新排列框,以便它们不会重叠
  • 但不要改变太多的布局
  • 如果您不介意盒子之间留一些空间(不会接触),则:

算法:

1.查找重叠框

  • 红盒子
2.寻找运动方向

  • 绿色矢量
  • 盒子中心之间
  • 然后将其大小更改为移动步长(几个像素…)
3.计算重叠的新位置

  • 然后检查新的重叠
  • 如果离另一个箱子太近,停止向该方向移动
  • 蓝色箭头显示碰撞停止
4.对所有重叠的盒子应用此(项目符号1中的循环)

  • 只需执行一个或几个步骤
  • 不是整个运动
5.迭代循环全部(从项目符号1开始)

  • 未找到重叠框时停止
  • 或进程已超时
  • 因为这也会被卡住
[附注]

  • 如果长方体中心相同
  • 然后将随机方向添加到运动向量
  • 整个过程可以应用更多次,降低步骤以提高速度