如何检查线段是否与正方形相交

时间:2014-12-12 00:09:22

标签: javascript algorithm geometry

我有一个由两个点a和b确定的线段。我也有一个由x0&lt; x&lt; x1和y0 < y&lt; y1其中x1-x0 = y1-y0。我试图检查片段的任何部分是否与正方形内的区域相交。 (如果该段恰好触及不计入交叉点的边)。

我的想法是使用这张照片

pic

function(a, b, x0, x1, y0, y1) {
  if (a or b is inside square)
    return true;
  else {
    switch (which quadrant is a in) {
      case 1: return (ab intersects top of square);
      case 2: return (ab intersects left of square);
      case 3: return (ab intersects bottom of square);
      case 4: return (ab intersects right of square);
    }
  }
}

我想知道是否有更好的方法来解决这个问题。

4 个答案:

答案 0 :(得分:1)

我会将你的线段分为斜率和(可能是假设的,如果扩展的)y轴截距,从而形成y = mx + b形式的函数(其中m是斜率,b是截距)。然后在广场的范围和范围内检查该功能 - 即,对于左右两侧之间的任何x,是否会落在顶部和底部之间?

答案 1 :(得分:1)

我想到的一个简短答案就是测试段与你的线和方块的4行交叉 使用标准计算geom cross产品。

这是一个快速教程 http://web.stanford.edu/class/cs97si/09-computational-geometry.pdf

Define ccw(A,B,C) = (B-A) X (C-A) where A,B,C is some point ccw(A,B,C) < 0 means C lies on the left side of line AB ccw(A,B,C) > 0 means C lies on the right side of line AB

所以测试段交叉就像,给出两行AB(你的段)和CD(正方形的任何一面)

它们正确交叉(即不包括触摸外壳)iff

ccw(A,B,C) * ccw(A,B,D) < 0 AND ccw(C,D,A) * ccw(C,D,B) < 0

简单地表示“C和D位于线AB的不同侧,而A和B位于线CD的不同侧” - &gt;路口

答案 2 :(得分:0)

您只需要检查2个案例。

如果线在上顶点的第1行之上或在底部顶点的第3行之下。如果这些条件中的任何一个返回true,则没有交集。

例如,要检查第1行,您需要为a,b确定的行计算y=mx+n并检查y(x0) > y1是否与y(x1) > y1

类似

答案 3 :(得分:0)

您可以使用不等式和线段的参数方程式解析此问题(我们使用dx/dy来表示xb-xa/yb-ya):

    x0 < xa + t.dx < x1
    y0 < xb + t.dy < y1
     0 <      t    < 1

然后重写以显示同一术语的三个括号:

    (x0 - xa).dy < t.dx.dy < (x1 - xa).dy
    (y0 - ya).dx < t.dx.dy < (y1 - ya).dx
               0 < t.dx.dy < dx.dy

警告:当乘以负d时,必须交换不等式的成员;因此有四种情况。 (实际上9 d也可以是0。这些案例很容易被忽略。)

最后,表示这些括号是兼容的,即至少有一个t值:

    Max((x0 - xa).dy, (y0 - ya).dx, 0) < Min(x1 - xa).dy, (y1 - ya).dx, dx.dy)

仔细观察,您可以识别您的方法的元素:例如0 < (x1 - xa).dy是与右侧的比较,而(x0 - xa).dy < (y1 - ya).dx是与对角线的比较。

这种方法需要2 -来计算dx/dy,然后4 <>(比较)来讨论9个案,然后针对倾斜段,{{1} },4 -5 *得出结论。

这样的事情(谨慎,未经检查!):

5 <>