Je cherchais une alternative python à MATLAB inpolygon () et je suis tombé sur contains_points comme une bonne option.

Cependant, les documents sont un peu nus, sans aucune indication du type de données que contains_points attend:

contient_points (points, transformation = aucune, rayon = 0,0)

Renvoie un tableau booléen qui est Vrai si le chemin contient le point correspondant.

Si transform n'est pas None, le chemin sera transformé avant d'effectuer le test.

Le rayon permet au chemin d'être légèrement plus grand ou plus petit.

J'ai le polygone stocké sous forme de tableau numpy n * 2 (où n est assez grand ~ 500). Pour autant que je puisse voir, j'ai besoin d'appeler la méthode Path () sur ces données qui semble fonctionner Ok:

poly_path = Path(poly_points)

Pour le moment, j'ai également les points que je souhaite tester stockés dans un autre tableau numpy n * 2 (catalog_points).

Peut-être que mon problème réside ici? Comme quand je cours:

in_poly = poly_path.contains_points(catalog_points)

Je récupère un ndarray contenant 'False' pour chaque valeur, peu importe l'ensemble de points que j'utilise (j'ai testé cela sur des tableaux de points bien à l'intérieur du polygone).

14
BJH 21 juil. 2015 à 18:04

2 réponses

Meilleure réponse

Souvent dans ces situations, je trouve la source éclairante ...

Nous pouvons voir la source de path.contains_point accepte un conteneur qui a au moins 2 éléments. La source de contains_points est un peu plus difficile à comprendre car elle appelle une fonction C Py_points_in_path. Il semble que cette fonction accepte un itérable qui donne des éléments de longueur 2:

>>> from matplotlib import path
>>> p = path.Path([(0,0), (0, 1), (1, 1), (1, 0)])  # square with legs length 1 and bottom left corner at the origin
>>> p.contains_points([(.5, .5)])
array([ True], dtype=bool)

Bien sûr, nous pourrions également utiliser un tableau de points numpy:

>>> points = np.array([.5, .5]).reshape(1, 2)
>>> points
array([[ 0.5,  0.5]])
>>> p.contains_points(points)
array([ True], dtype=bool)

Et juste pour vérifier que nous n'obtenons pas toujours True:

>>> points = np.array([.5, .5, 1, 1.5]).reshape(2, 2)
>>> points
array([[ 0.5,  0.5],
       [ 1. ,  1.5]])
>>> p.contains_points(points)
array([ True, False], dtype=bool)
29
mgilson 21 juil. 2015 à 15:26

Assurez-vous que les sommets sont ordonnés comme souhaité. Les sommets ci-dessous sont ordonnés de manière à dessiner un triangle au lieu d'un rectangle. Ainsi, il ne crée pas de point vrai pour l'intérieur du rectangle mais à l'intérieur du triangle.

>>> p = path.Path(np.array([bfp1,bfp2,bfp4,bfp3]))
>>> p
Path([[ 5.53147871  0.78330843]
 [ 1.78330843  5.46852129]
 [ 0.53147871 -3.21669157]
 [-3.21669157  1.46852129]], None)
>>> IsPointInside=np.array([[1,2],[1,9]])
>>> IsPointInside
array([[1, 2],
       [1, 9]])
>>> p.contains_points(IsPointInside)
array([False, False], dtype=bool)
>>> 

Le premier point aurait été Vrai si bfp3 et bfp4 avaient été correctement commandés.

2
mehmet ercan 20 avril 2016 à 21:03