我想實現一個功能,找到射線性/段交叉口蟒蛇以下加雷思·雷斯偉大的說明: https://stackoverflow.com/a/14318254/7235455和https://stackoverflow.com/a/565282/7235455並行性和共線射線性/段相交測試失敗BCZ浮動精度在python
這裏是我的功能:
from math import radians, sin, cos
import numpy as np
def find_intersection(point0, theta, point1, point2):
# convert arguments to arrays:
p = np.array(point0, dtype=np.float) # ray origin
q = np.array(point1, dtype=np.float) # segment point 1
q2 = np.array(point2, dtype=np.float) # segment point 2
r = np.array((cos(theta),sin(theta))) # theta as vector (= ray as vector)
s = q2 - q # vector from point1 to point2
rxs = np.cross(r,s)
qpxs = np.cross(q-p,s)
qpxr = np.cross(q-p,r)
t = qpxs/rxs
u = qpxr/rxs
if rxs == 0 and qpxr == 0:
t0 = np.dot(q-p,r)/np.dot(r,r)
t1 = np.dot(t0+s,r)/np.dot(r,r)
return "collinear"
elif rxs == 0 and qpxr != 0:
return "parallel"
elif rxs != 0 and 0 <= t and 0 <= u and u <= 1: # removed t <= 1 since ray is inifinte
intersection = p+t*r
return "intersection is {0}".format(intersection)
else:
return None
功能正常工作時,有一個交集。但它不能識別並行性或共線性,因爲條件rxs == 0和qpxr == 0不符合(曾經?)。例如:
p0 = (0.0,0.0)
theta = radians(45.0)
p1 = (1.0,1.0)
p2 = (3.0,3.0)
c = find_intersection(p0,theta,p1,p2)
它返回無。如果 - 塊之前增加對RXS和qpxr打印語句給
rxs = 2.22044604925e-16 qpxr = -1.11022302463e-16
我的結論是,該功能未能趕上第一if語句,因爲浮點問題的條件。 2.22044604925e-16和-1.11022302463e-16是非常小的,但不幸的是不完全是0.我明白浮點數不能在二進制中有精確的表示。
我的結論是否正確或我錯過了什麼?有沒有什麼想法可以避免這個問題? 非常感謝!
花了我一段時間去挖掘它。您的想法與小數字和正常化進行比較似乎是最實際的。缺點是,它提供了一些虛假的並行/共線,但我想我可以忍受這一點。 – Thodor