I am trying to determine the distance from a point to a polygon in 2D space. The point can be inside or outside the polygon; The polygon can be convex or concave.
If the point is within the polygon or outside the polygon with a distance smaller than a user-defined constant d
, the procedure should return True
; False
otherwise.
I have found a similar question: Distance from a point to a polyhedron or to a polygon. However, the space is 2D in my case and the polygon can be concave, so it's somehow different from that one.
I suppose there should be a method simpler than offsetting the polygon by d
and determining it's inside or outside the polygon.
Any algorithm, code, or hints for me to google around would be appreciated.
Corrected as per @jcaron's comment
Your best bet is to iterate over all the lines and find the minimum distance from a point to a line segment.
To find the distance from a point to a line segment, you first find the distance from a point to a line by picking arbitrary points
P1
andP2
on the line (it might be wise to use your endpoints). Then take the vector fromP1
to your pointP0
and find(P2-P1) . (P0 - P1)
where.
is the dot product. Divide this value by||P2-P1||^2
and get a valuer
.Now if you picked
P1
andP2
as your points, you can simply check ifr
is between 0 and 1. Ifr
is greater than 1, thenP2
is the closest point, so your distance is||P0-P2||
. Ifr
is less than 0, thenP1
is the closest point, so your distance is||P0-P1||
.If
0<r<1
, then your distance issqrt(||P0-P1||^2 - r * ||P2-P1||^2)
The pseudocode is as follows:
If you have a working point to line segment distance function, you can use it to calculate the distance from the point to each of the edges of the polygon. Of course, you have to check if the point is inside the polygon first.
I can help you with this pointers:
and some remarks:
Do you need fast or simple?
Does it have to be always absolutely correct in edge cases or will good enough most of the time be OK?
Typical solution are to find the distance to each vertex and find the pair with the smallest values ( note that for a point outside a convex polygon these might not be adjacent) and then check point to line intersections for each segment.
For large complex shapes you can also store approx polygon bounding boxes (either rectangular or hexagons) and find the closest side before checking more detail.
You may also need code to handle the special case of exactly on a line.