-1

I have a question

I used two different library

import matplotlib.path as mplPath

point = (0.3, 0.2)
poly = [(0, 0), (0, 1), (1, 0), (1,1)]
polygon = mplPath.Path( np.array(poly) )
print(polygon.contains_point(point))

return: False

from shapely.geometry import Point, Polygon

point = Point(0.3, 0.2)
polygon = Polygon([(0, 0), (0, 1), (1, 0), (1,1)])
print(polygon.contains(point))
print( point.within(polygon) )

return: False False

However, two library all failed to detect (0.3, 0.2) is within the given polygon...

Why..? And, How do I can check weather a point is within more complicate polygon ?

Thank you !

  • 3
    Maybe you should look more closely at your "polygon". The order you specify the points is important. – BoarGules Jul 07 '21 at 07:23
  • 1
    In addition to @BoarGules your polygon isn't closed. [Here's a plot of the polygon and point](https://i.stack.imgur.com/NhdfK.png). You should look at the [path tutorial](https://matplotlib.org/stable/tutorials/advanced/path_tutorial.html) – Alex Jul 07 '21 at 07:28
  • @Alex Thank you, but, as I mentioned below, in a complicate case below, how I find whether to contain this point....? point = (144.977, -37.8350) poly = [[144.936868, -37.788838], [144.936665, -37.789517], [144.936607, -37.789511], [144.936551, -37.789616], [144.936633, -37.789625], [144.936439, -37.790276], [144.936387, -37.790453], [144.936223, -37.790436], ....] – Dae-Young Park Jul 07 '21 at 07:45
  • You would do what you are attempting in your post, however I think you need to look at how you are generating your `Path` as these seem to not be what you are expecting. – Alex Jul 07 '21 at 07:52
  • @Alex Um.. Do you know how to generate appropriate path for making correct shape? Should I sort these points above? – Dae-Young Park Jul 07 '21 at 08:12
  • Each point is a vertex on your shape. Each consecutive pair of points is (usually) joined by a straight line. The order they are in is important to get the correct shape, so sorting will not work; this is why your original coords produced an odd result. To generate the appropriate path you need to look at what is producing those points initially as it is likely incorrect. – Alex Jul 07 '21 at 08:20

1 Answers1

1

Your polygon is invalid because its boundary crosses itself. Even if you filled it in, it would not include the point you've specified (0.3, 0.2).

A polygon is defined by connecting the points you provide in the order you give them, then returning to the first point. So your polygon has these legs:

  • (0, 0), to (0, 1): straight line up the y axis
  • (0, 1) to (1, 0): diagonal down to the x axis, one unit out
  • (1, 0) to (1,1): vertical line to (1, 1)
  • (1, 1) to (0, 0): diagonal back to the first point, at (0, 0)

A lot of software will treat this as an invalid path, because it crosses itself. Even if it does treat this as a shape, it will be two triangles, with edges along the y axis and along the (0, 1) - (1, 1) path, with points that meet at (0.5, 0.5). Your point (0.3, 0.2) falls in the empty triangle below them (connecting (0, 0) to (0.5, 0.5) to (1, 0)).

Matthias Fripp
  • 17,670
  • 5
  • 28
  • 45
  • Thank you for your rapid explanation but, in a complicate case below, how I find whether to contain this point....? point = (144.977, -37.8350) poly = [[144.936868, -37.788838], [144.936665, -37.789517], [144.936607, -37.789511], [144.936551, -37.789616], [144.936633, -37.789625], [144.936439, -37.790276], [144.936387, -37.790453], [144.936223, -37.790436], ....] – Dae-Young Park Jul 07 '21 at 07:37
  • Should I search appropriate connected lines...? But, How? – Dae-Young Park Jul 07 '21 at 07:39
  • 1
    @Alex gave a plot of the shape you defined, at https://i.stack.imgur.com/NhdfK.png . This shape does not contain the point you specified, and it seems like your code is telling you that correctly. Try using `Polygon([(0, 0), (0, 1), (1,1), (1, 0)])` instead and you may get the answer you expected. (Or you may need to add `(0, 0)` to the end of the list; I don't have much experience with these libraries.) – Matthias Fripp Jul 07 '21 at 07:41
  • @Dae-YoungPark The additional `point` you gave is also not in the `poly` you gave. All the `y` values in `poly` are above -37.8, and `point` has a `y` value below -37.8. When I run `poly.contains(point)`, I get `False`, which is the correct answer. – Matthias Fripp Jul 07 '21 at 08:26
  • @Dae-YoungPark You haven't given a polygon definition that actually includes a point yet, so your code may be working correctly. But if your bigger polygon definition has vertices that are out of sequence like the first example (or don't have any defined sequence), then you might want to create a polygon that is the convex hull of your points, instead of a polygon that uses them directly as vertices? – Matthias Fripp Jul 07 '21 at 08:29