我有一行,由参数m, h
定义,其中
y = m*x + h
这条线穿过网格(即对于网格的每个正方形(a, b)
(即正方形[a, a+1] x [b, b+1]
),我想确定给定的直线是否与这个正方形相交,如果是,正方形中线段的长度是多少。
最终,我希望能够一次使用多行代码(即m
和h
是matlab风格的向量),但我们现在可以专注于“简单”的情况。
我想知道如何判断直线是否与正方形相交:
1.计算直线与垂直线x = a
和x = a + 1
以及水平线y = b
和y = b + 1
的交点
1.检查这4个点中是否有2个在正方形边界上(即a <= x < a + 1
和b <= y < b + 1
)
如果这些点上的两个点在正方形上,则直线与正方形相交。然后,要计算长度,只需减去这两个点,并使用毕达哥拉斯定理。
我的问题更多的是在执行方面:我怎样才能很好地实现这一点(特别是在选择减去哪两个点时)?
4条答案
按热度按时间kninwzqo1#
设正方形由角点**(a,b),(a+1,b),(a,b+1),(a+1,b+1)定义。
步骤1:检查直线是否与正方形相交。
(a)将4个角点的坐标中的每一个依次代入y-mx- h**。如果该评估的符号包括正项和负项,则转到步骤b。否则,直线不与正方形相交。
(B)现在有两个子案例:
(b1)情况1:在步骤(a)中,您有三个点,其中y - mx - h评估为一个符号,第四个点评估为另一个符号。假设第四个点是某个**(x*,y*)。则交点是(x*,mx*+h)和((y*-h)/m,y*)。
(b2)情况2:在步骤(a)中,你有两个点,其中y-mx- h评估为一个符号,另外两个点评估为另一个符号。选择任意两个符号相同的点,比如(x*,y*)和(x*+1,y*)。则交点为(x*,mx* + h)和(x*+1,m(x*+1)+ h)**。
你将不得不考虑一些退化的情况,其中直线恰好接触四个角点中的一个,以及直线恰好位于正方形的一侧的情况。
zlwx9yxi2#
当
m
为0时(当试图计算与y = k
的交集时),您提出的方法可能会遇到步骤(1)中的问题。如果
m
为0,那么很容易(线段长度为1或0,取决于b <= h <= b+1
是否为0)。否则,您可以通过替换找到
x = a
和a+1
的交集,例如y_a
,y_{a+1}
。然后,将y_a
和y_{a+1}
裁剪到b
和b+1
之间(比如,y1
和y2
,即y1 = min(b+1, max(b, y_a))
和类似的y2
),并使用比例abs((y1-y2)/m) * sqrt(m^2+1)
。这利用了
x=k
和x=k+1
之间的线段是sqrt(m^2+1)
,y
的差是m
以及相似性的事实。j2cgzkjk3#
你可以这样做:先求正方形的圆心,再求对角线的长度。如果从正方形中心到直线的距离小于对角线的长度,那么直线将与正方形相交。一旦你知道这条线会相交,你就可以很容易地找到相交的线段。我想你是想为代数重建技术做权重矩阵。我希望这是正确的答案。这是我在堆栈流中的第一个答案。:)
ni65a41a4#
下面是Tryer给出的答案在python3中的实现。
在开发过程中,我遇到了一个他没有触及的b2子用例的边缘情况。也就是说,如果斜率的大小大于1,则交点的形式为**((Y*-h)/m,Y*)和((Y*+1-h)/m,Y*+1),而不是(x*,mx* + h)和(x*+1,m(x*+1)+ h)**。