我有一个由两个点a和b确定的线段。我也有一个由x0&lt; x&lt; x1和y0 < y&lt; y1其中x1-x0 = y1-y0。我试图检查片段的任何部分是否与正方形内的区域相交。 (如果该段恰好触及不计入交叉点的边)。
我的想法是使用这张照片
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);
}
}
}
我想知道是否有更好的方法来解决这个问题。
答案 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 <>