获取2个矩形的交点

时间:2018-07-12 02:15:29

标签: javascript geometry collision intersection

如何获取2个矩形的交点。到目前为止,我已经知道了:

module.exports.boxIntersection = function(box1, box2) {
    var xMin1 = box1.x - box1.width;
    var xMin2 = box2.x - box2.width;
    var xMax1 = box1.x + box1.width;
    var xMax2 = box2.x + box2.width;
    var zMin1 = box1.z - box1.length;
    var zMin2 = box2.z - box2.length;
    var zMax1 = box1.z + box1.length;
    var zMax2 = box2.z + box2.length;
    var xMin = Math.max(xMin1, xMin2);
    var xMax = Math.min(xMax1, xMax2);
    if (xMax > xMin) {
        var zMin = Math.max(zMin1, zMin2);
        var zMax = Math.min(zMax1, zMax2);
        if (zMax > zMin) return [xMin, zMin, xMax, zMax];
    } return null;
};

这仅返回2个交点。但是我需要像这样返回所有的交点:

enter image description here

在这种情况下,它只能返回2分:

enter image description here

我在这里看到了这个问题:Get the points of intersection from 2 rectangles

但是它只返回2分。

编辑: 在矩形与另一边对齐的情况下,应仅返回真正交点处的点,如下所示: enter image description here

1 个答案:

答案 0 :(得分:1)

您链接的答案实际上是将矩形作为多边形“相交”,作为平面上的多边形点集,并返回所得矩形的左下角和右上角(以多边形集)。实际上,这两个返回点简单地定义了所得矩形的所有四个角。因此,不,它不会“返回两分”。它实际上返回了四个点。

为了解决您的问题,您必须决定保留这四个点中的哪一个以及将其丢弃。规则很简单:您只需保留与原始矩形的相应顶点不重合的那些点。您可以简单而直接地以琐碎而乏味的方式进行检查。八次检查(如果我没有丢失的话),您就完成了。

或者您可以使用稍微棘手的方法。

假设我们有两个矩形:(x11, y11)-(x12, y12)(x21, y21)-(x22, y22)。矩形已标准化(如链接中所定义)。在计算重叠矩形时,我们仍然使用相同的最小-最大技术,但同时我们还记住了哪个原始矩形提供了极值

int x1 = max(x11, x21);
unsigned flags_x1 = (x1 == x11) | ((x1 == x21) << 1);

int y1 = max(y11, y21);
unsigned flags_y1 = (y1 == y11) | ((y1 == y21) << 1);

int x2 = min(x12, x22);
unsigned flags_x2 = (x2 == x12) | ((x2 == x22) << 1);

int y2 = min(y12, y22);
unsigned flags_y2 = (y2 == y12) | ((y2 == y22) << 1);

现在我们检查这些矩形是否有适当的重叠

if (x1 >= x2 || y1 >= y2)
 /* No overlap. Done */;

但是如果存在重叠,我们将使用flags_...变量来仅输出由来自两个不同矩形的极值形成的那些点

/* Lower-left */
if ((flags_x1 & flags_y1) == 0)
  /* Output (x1, y1) as intersection point */;

/* Lower-right */
if ((flags_x2 & flags_y1) == 0)
  /* Output (x2, y1) as intersection point */;

/* Upper-left */
if ((flags_x1 & flags_y2) == 0)
  /* Output (x1, y2) as intersection point */;

/* Upper-right */
if ((flags_x2 & flags_y2) == 0)
  /* Output (x2, y2) as intersection point */;

请注意,如果一个矩形完全位于另一矩形内,则上面的无重叠测试将通过(因为矩形实际上 do 重叠),但是flags_...测试将丢弃所有四个顶点。

和往常一样,可能需要(或不需要)额外的努力来正确处理边界情况,例如触摸矩形(内部或外部触摸)。