Je suis en train de mettre en œuvre une fonction pour trouver des intersections Ray-/segment en python suivant les instructions de grandes Gareth Rees: https://stackoverflow.com/a/14318254/7235455 et https://stackoverflow.com/a/565282/7235455essai Ray-/segment intersection pour le parallélisme et colinéarité ne BCZ de précision float en python
Voilà ma fonction:
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
La fonction fonctionne très bien quand il y a une intersection. Mais il ne reconnaît pas le parallélisme ou la colinéarité, car les conditions rxs == 0 et qpxr == 0 ne sont pas (jamais?) Remplies. Exécuter par exemple:
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)
qui renvoie None. Ajout d'une déclaration d'impression pour RXS et qpxr avant que le cas du bloc donne
rxs = 2.22044604925e-16 qpxr = -1.11022302463e-16
Ma conclusion est, la fonction ne parvient pas à attraper les conditions de la première instruction if en raison de problèmes de virgule flottante. 2.22044604925e-16 et -1.11022302463e-16 sont assez petits, mais malheureusement pas exactement 0. Je comprends que les flottants ne peuvent pas avoir une représentation exacte en binaire.
est ma conclusion correcte ou ai-je manqué quelque chose? Existe-t-il des idées de mise en œuvre pour éviter ce problème? Merci beaucoup!
Ça m'a pris un moment pour creuser dedans.Votre idée de comparer avec de petits nombres et la normalisation semble la plus pratique. L'inconvénient est, il donne un faux parallèle/colinéaire, mais je suppose que je peux vivre avec ça. – Thodor