给定一个线段,即两个点(x1,y1)和(x2,y2),一个点P(x,y)和一个角度θ。我们如何找到这条线段和从水平方向θ角度θ发出的线光线是否相交?如果它们相交,如何找到交点?
答案 0 :(得分:22)
让我们标记点 q =( x1 , y1 )和 q + s < / strong> =( x2 , y2 )。因此 s =( x2 - x1 , y2 - y1 )。然后问题看起来像这样:
设 r =(cosθ,sinθ)。然后通过 p 的光线上的任何点都可以表示为 p + t r (对于标量参数0≤ t )并且线段上的任何点都可表示为 q + u s (对于标量参数0 ≤ u ≤1)。
如果我们能找到 t 和 u 这两条线相交,那么 p + t r = q + u s :
请参阅this answer了解如何找到这一点(或确定没有这一点)。
如果0≤t且0≤u≤1,则线段与光线相交。
答案 1 :(得分:6)
以下是其他答案中给出的算法的C#代码:
<button>
答案 2 :(得分:3)
感谢Gareth给出了一个很好的答案。这是用Python实现的解决方案。随意删除测试,只需复制粘贴实际功能。我已经跟踪了这里出现的方法https://rootllama.wordpress.com/2014/06/20/ray-line-segment-intersection-test-in-2d/。
import numpy as np
def magnitude(vector):
return np.sqrt(np.dot(np.array(vector),np.array(vector)))
def norm(vector):
return np.array(vector)/magnitude(np.array(vector))
def lineRayIntersectionPoint(rayOrigin, rayDirection, point1, point2):
"""
>>> # Line segment
>>> z1 = (0,0)
>>> z2 = (10, 10)
>>>
>>> # Test ray 1 -- intersecting ray
>>> r = (0, 5)
>>> d = norm((1,0))
>>> len(lineRayIntersectionPoint(r,d,z1,z2)) == 1
True
>>> # Test ray 2 -- intersecting ray
>>> r = (5, 0)
>>> d = norm((0,1))
>>> len(lineRayIntersectionPoint(r,d,z1,z2)) == 1
True
>>> # Test ray 3 -- intersecting perpendicular ray
>>> r0 = (0,10)
>>> r1 = (10,0)
>>> d = norm(np.array(r1)-np.array(r0))
>>> len(lineRayIntersectionPoint(r0,d,z1,z2)) == 1
True
>>> # Test ray 4 -- intersecting perpendicular ray
>>> r0 = (0, 10)
>>> r1 = (10, 0)
>>> d = norm(np.array(r0)-np.array(r1))
>>> len(lineRayIntersectionPoint(r1,d,z1,z2)) == 1
True
>>> # Test ray 5 -- non intersecting anti-parallel ray
>>> r = (-2, 0)
>>> d = norm(np.array(z1)-np.array(z2))
>>> len(lineRayIntersectionPoint(r,d,z1,z2)) == 0
True
>>> # Test ray 6 --intersecting perpendicular ray
>>> r = (-2, 0)
>>> d = norm(np.array(z1)-np.array(z2))
>>> len(lineRayIntersectionPoint(r,d,z1,z2)) == 0
True
"""
# Convert to numpy arrays
rayOrigin = np.array(rayOrigin, dtype=np.float)
rayDirection = np.array(norm(rayDirection), dtype=np.float)
point1 = np.array(point1, dtype=np.float)
point2 = np.array(point2, dtype=np.float)
# Ray-Line Segment Intersection Test in 2D
# http://bit.ly/1CoxdrG
v1 = rayOrigin - point1
v2 = point2 - point1
v3 = np.array([-rayDirection[1], rayDirection[0]])
t1 = np.cross(v2, v1) / np.dot(v2, v3)
t2 = np.dot(v1, v3) / np.dot(v2, v3)
if t1 >= 0.0 and t2 >= 0.0 and t2 <= 1.0:
return [rayOrigin + t1 * rayDirection]
return []
if __name__ == "__main__":
import doctest
doctest.testmod()