내가 가레스리스 '좋은 지침에 따라 파이썬에서 ray-/세그먼트 교차점을 찾을 수있는 기능을 구현하기 위해 노력하고 있습니다 : https://stackoverflow.com/a/14318254/7235455 및 https://stackoverflow.com/a/565282/7235455Ray-/세그먼트 교차 시험은 파이썬에서 부동 소수점 정밀도의 BCZ 실패
을 교차로가있는 경우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)
아무 것도 없음을 반환합니다. 은 if 블록 전에 RXS 및 qpxr의 인쇄 문을 추가하면 내 결론은
rxs = 2.22044604925e-16 qpxr = -1.11022302463e-16
이 기능 때문에 부동 소수점 문제의 첫 번째 경우 문의 조건을 잡으려고 실패 할 수 있습니다. 2.22044604925e-16과 -1.11022302463e-16은 꽤 작지만, 불행히도 정확하게 0은 아닙니다. 저는 float가 바이너리에서 정확한 표현을 가질 수 없다는 것을 알고 있습니다.
내 결론이 맞았습니까? 이 문제를 피하기위한 구현 아이디어가 있습니까? 감사합니다.
잠깐 들러서 조사해 보았습니다.작은 숫자와 정규화와 비교하려는 당신의 생각이 가장 실용적인 것 같습니다. 단점은, 그것은 약간의 병렬/동일 선상을 제공하지만, 나는 그것으로 살 수 있다고 생각합니다. – Thodor