计算距离移动的盒子除去路口盒子、路口、距离

2023-09-11 06:57:42 作者:我的世界不允许你消失

我有两个框,重叠,我想弄清楚如何将之一删除交集。

I have two boxes that are overlapping and I want to figure out how to move one to remove the intersection.

予定义的向量从一箱的中心到其他和移动一个盒沿着该行,但是这可以进一步比它需要移动,或者可以不是足够远。所以,我想我需要做的是找出哪些最靠近中心之间,然后该行的固定框线条的角落找出多远沿着这条线(或可能伸出的线)的那个角落会。然后我就可以多我的载体由量,但我有麻烦包装我的头周围。

I defined a vector from the center of one box to the other and move one box along that line, but that may be further than it needs to move, or may not be far enough. So I think what I need to do is figure out which corner of the stationary box lines closest to the line between the centers and then figure out how far along that line (or possibly projecting beyond that line) that corner would be. Then I can multiple my vector by that amount, but I'm having trouble wrapping my head around it.

下面就是我的那一刻,我将与项目 X 宽度高度属性列表,并为我添加的每个项目,我检查交点列表中的项目已。如果找到一个路口,我尝试将新的项目,然后再试一次:

Here's what I have at the moment, I'm adding items with an x,y,width and height property to a list and as I add each item, I'm checking for intersections with items already in the list. If an intersection is found, I try to move the new item and then try again:

function BoxList() {
    var self = this;
    var boxes = [];

    self.add = function(item, iteration) {
        // check intersections with existing boxes
        iteration = iteration || 0;
        if (iteration < 5) {
            for (var i=0; i < boxes.length; i++) {
                if (doesIntersect(getBounds(item),getBounds(boxes[i]))) {
                    item.elem.addClass("overlapped");
                    // 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: boxes[i].x + boxes[i].width / 2, y: boxes[i].y + boxes[i].height / 2 };
                    var line = { x1 : centerA.x, y1 : centerA.y, x2 : centerB.x, y2 : centerB.y };
                    var vector = { x : line.x1 - line.x2, y: line.y1 - line.y2 };
                    item.x = item.x + vector.x;
                    item.y = item.y + vector.y;
                    item.elem.offset({ left: item.x , top: item.y });       // TODO: calculate size of move needed
                    return self.add(item, iteration + 1);
                }
            }
        }
        boxes.push(item);
    }

    function getBounds(item) {
        return { x1: item.x, x2: item.x + item.width, y1: item.y, y2: item.y + item.height };
    }

    function doesIntersect(a,b) {
        return a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1;
    }
}

下面是一个简单的小提琴

点击移动试图安排两箱,注意重叠框移动两次,并得到进一步的移动比它真正需要。

Click move to attempt to arrange the two boxes, note that the overlapping box is moved twice and gets moved further than it really needs to.

有什么想法?更好的方法的建议,以处理这也大大AP preciated。

Any thoughts? Suggestions on better ways to approach this also greatly appreciated.

推荐答案

当我读到它,现在你计算两个框的中心,并使用这两个点,以使该推的一个箱子的载体。这是错误的载体。如果将箱子对上彼此顶部的载体将是(0,0)。如果箱子才刚刚剪辑对方的载体将是在它的最高的价值。

As I read it now you calculate the centers of both boxes and use those two points to make the vector that pushes one of the boxes. That's the wrong vector. If you place the boxes right on top of each other that vector will be (0,0). If the boxes only just clip each other the vector will be at it's highest possible value.

您可以看到这与鬼的行动。首先,它被推开只有一点点,那么它就会被推开了很多。

You can see this in action with the ghosts. First it gets pushed only a little bit, then it gets pushed a lot.

相反,您需要的矢量应根据重叠的大小。如果重叠是由30像素20像素的载体是(+ 20,+ 30)

Instead the vector you need should be based on the size of the overlap. If the overlap is 20px by 30px your vector is (+20,+30)

var vector = {
    x: Math.min(box1.x + box2.width, box2.x + box2.width) - Math.max(box1.x, box2.x),
    y: Math.min(box1.y + box2.height, box2.y + box2.height) - Math.max(box1.y, box2.y)
}

vector.x 的边框减去边框的左下角的右上角。同上对 vector.y

vector.x is the top-right of the bounding box minus the bottom-left of the bounding box. Idem for vector.y.

这正好适量的移动箱: http://jsfiddle.net/x8MT3/2/

This moves the box by exactly the right amount: http://jsfiddle.net/x8MT3/2/

我补充说,需要2次迭代,大概是顶盒应该移动的其他方式第3盒对。因为我已经设置它的矢量总是(+,+),你可以做你的中心点计算,以确定哪个牌子每个方向上应该有。

I added a 3rd box pair that needs 2 iterations, probably the top box should move the other way. The vector as I've set it up is always (+,+), you can do your center point calculation to determine which sign each direction should have.