How to get the nearest point outside a polygon from a point inside a polygon?

后端 未结 2 1708
夕颜
夕颜 2021-01-12 10:21

I have a map with a lot of polygons and a point inside in one of them, like this: \"polygons\"

The x and y coordina

2条回答
  •  臣服心动
    2021-01-12 10:29

    To know in which polygon the point is in you can use the Ray Casting algorithm.

    For finding the closest edge you could use a naive approach computing the distance to each edge and then take the minimum. Just remember to check if the intersection with edge is outside the edge (check this). If it is outside take the distance to the closest extreme of the edge.

    Ok better explaining the intuition with some pseudo-code:

    dot(u,v) --> ((u).x * (v).x + (u).y * (v).y)
    norm(v)  --> sqrt(dot(v,v))     // norm = length of vector
    dist(u,v)--> norm(u-v)          // distance = norm of difference
    
    // Vector contains x and y
    // Point contains x and y
    // Segment contains P0 and P1 of type Point
    // Point  = Point ± Vector
    // Vector = Point - Point
    // Vector = Scalar * Vector
    Point closest_Point_in_Segment_to(Point P, Segment S)
    {
         Vector v = S.P1 - S.P0;
         Vector w = P - S.P0;
    
         double c1 = dot(w,v);
         if ( c1 <= 0 )   // the closest point is outside the segment and nearer to P0
              return S.P0;
    
         double c2 = dot(v,v);
         if ( c2 <= c1 )  // the closest point is outside the segment and nearer to P1
              return S.P1;
    
         double b = c1 / c2;
         Point Pb = S.P0 + b * v;
         return Pb;
    }
    
    [Point, Segment] get_closest_border_point_to(Point point, Polygon poly) {
    
        double bestDistance = MAX_DOUBLE;
        Segment bestSegment;
        Point bestPoint;
    
        foreach s in poly.segments {
            Point closestInS = closest_Point_in_Segment_to(point, s);
            double d = dist(point, closestInS);
            if (d < bestDistance) {
                bestDistance = d;
                bestSegment = s;
                bestPoint = closestInS; 
            }
        }
    
        return [bestPoint, bestSegment];
    }
    

    I think this pseudo-code should get you going, of course once you have the polygon your point is in!.

提交回复
热议问题