angle sum decision method, check whether point(x,y) is inside polygon - Java 2D Graphics

Java examples for 2D Graphics:Point

Description

angle sum decision method, check whether point(x,y) is inside polygon

Demo Code


import java.lang.Math;

public class Main{

    private static final double EPS = 1e-8;
    /**/*from ww w. ja  v a  2s .com*/
     * angle sum decision method, check whether point(x,y) is inside polygon;
     * this method is useful for both convex polygon and reentrant polygon;
     * key point: accuracy control, must set an number small enough, such as 0.00000001
     * @param  x  double  coordinate x
     * @param  y  double  coordinate y
     * @param  frame  Double[]  unit polygon's frame, consisted of many point(x,y) one by one anticlockwise or clockwise 
     * @return  boolean
     * */
    public static boolean inPolygon1(double x, double y, Double[] frame) {
        double sum = 0.0;
        System.out.println("frame.length:" + frame.length);
        System.out.println("y:" + x + "y:" + y);
        for (int i = 0; i < frame.length - 2; i += 2) {
            System.out.println("i:" + i);
            double x0 = frame[i], y0 = frame[i + 1]; //current start point
            double x1 = frame[i + 2], y1 = frame[i + 3]; //current target point
            System.out.println("x0:" + x0 + " y0:" + y0 + " x1:" + x1
                    + " y1:" + y1);
            if ((x == x0 && y == y0) || (x == x1 && y == y1)) //check whether the point is same with the point in frame    
                return true;
            //if(pointOnSegment(x0,y0,x1,y1,x,y))  //check whether the point on edge of the polygon
            //return true; 
            double a = Len_ab(x, y, x0, y0); //get 3 side length of the triangle formed by current 3 points
            double b = Len_ab(x, y, x1, y1);
            double c = Len_ab(x0, y0, x1, y1);

            //calculate angle sum, add if cross product > 0, minus else
            sum += fabs(x_multi(x0, y0, x1, y1, x, y))
                    * Math.acos((a * a + b * b - c * c) / (2.0 * a * b));
        }
        sum = Math.abs(sum); //if angle sum equals 360, the point is inside polygon, else outside or upon
        if (Math.abs(sum - 2.0 * Math.PI) <= EPS) //compare the difference with a number small enough
            return true;
        return false;
    }
    /**
     * calculate side length
     * @param  x0  double  start coordinate x
     * @param  y0  double  start coordinate y
     * @param  x1  double  target coordinate x
     * @param  y1  double  target coordinate y
     * @return  double
     * */
    private static double Len_ab(double x0, double y0, double x1, double y1) {
        return Math.sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
    }
    /**
     * simplify the result got from method dot
     * @param  d  double  result from method dot
     * @return  double
     * */
    private static double fabs(double d) {
        if (Math.abs(d) < EPS)
            return 0;
        else
            return d > 0 ? 1 : -1;
    }
    
    private static double x_multi(double x0, double y0, double x1,
            double y1, double x, double y) { //?????
        return (x - x0) * (y1 - y0) - (x1 - x0) * (y - y0);
    }
}

Related Tutorials