How to determine if a point is inside a 2D convex polygon?

后端 未结 8 1779
别那么骄傲
别那么骄傲 2020-11-27 12:58

I have a convex polygon (typically just a rotated square), and I know all of 4 points. How do I determine if a given point (yellow/green) is inside the polygon?

相关标签:
8条回答
  • 2020-11-27 13:32

    The java.awt.Polygon class has a number of contains(...) methods if you use Polygon objects to represent your polygon.

    0 讨论(0)
  • 2020-11-27 13:33

    Say, x[] is the array of x points and y[] is the array of y points.
    You are meant to return 1 if the point exists in the polygon and 2 if not. where (planeX,planeY) is the point you need to check.

    //check like this
    return new Polygon(x,y,x.length).contains(planeX, planeY)?1:2;
    
    0 讨论(0)
  • 2020-11-27 13:36

    Assuming that your point is at Y coordinate y, simply calculate the x positions where each of the polygon's (non-horizontal) lines cross y. Count the number of x positions that are less than the x position of your point. If the number of x positions is odd, your point is inside the polygon. Note: this works for all polygons, not just convex. Think of it this way: draw a line from infinitely far away straight in to your point. When that line crosses a polygon line, it is now inside the polygon. Cross the line again, outside. Cross again, inside (and so forth). Hope this helps!

    0 讨论(0)
  • 2020-11-27 13:36

    Just to add a (simple) Java implementation of the original code in C from code suggested by @Dean Povey (I don't know why @Dean Povey is referring to a large implementation):

    static boolean pnpoly(double[] vertx, double[] verty, double testx, double testy)
    {
        int nvert = vertx.length;
        int i, j;
        boolean c = false;
        for (i = 0, j = nvert-1; i < nvert; j = i++) {
            if ( ((verty[i]>testy) != (verty[j]>testy)) &&
                    (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
                c = !c;
        }
        return c;
    }   
    

    I did not change the case to comply with Java rule to show the minimal changes required. I have also tested it in simple cases and it works fine.

    0 讨论(0)
  • 2020-11-27 13:45

    Check to see if it's on the same side of the 4 half-planes defined by the lines that contain the line segments that make up the sides of the quad.

    Here is a good explanation.

    0 讨论(0)
  • 2020-11-27 13:48

    This page: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html shows how to do this for any polygon.

    I have a Java implementation of this, but it is too big to post here in its entirety. However, you should be able to work it out:

    class Boundary {
        private final Point[] points; // Points making up the boundary
        ...
    
    
        /**
         * Return true if the given point is contained inside the boundary.
         * See: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
         * @param test The point to check
         * @return true if the point is inside the boundary, false otherwise
         *
         */
        public boolean contains(Point test) {
          int i;
          int j;
          boolean result = false;
          for (i = 0, j = points.length - 1; i < points.length; j = i++) {
            if ((points[i].y > test.y) != (points[j].y > test.y) &&
                (test.x < (points[j].x - points[i].x) * (test.y - points[i].y) / (points[j].y-points[i].y) + points[i].x)) {
              result = !result;
             }
          }
          return result;
        }
    }
    

    And here is a sketch of the Point class

    /**
     * Two dimensional cartesian point.
     */
    public class Point {
      public final double x;
      public final double y;
      ...
    }
    
    0 讨论(0)
提交回复
热议问题