TriangleNet.NewLocation.SplitConvexPolygon C# (CSharp) Method

SplitConvexPolygon() private method

Splits a convex polygons into one or two polygons through the intersection with the given line (regarding the directional vector of the given line).
http://www.mathematik.uni-ulm.de/stochastik/lehre/ws03_04/rt/Geometry2D.ps
private SplitConvexPolygon ( int numvertices, double convexPoly, double x1, double y1, double x2, double y2, double &polys ) : int
numvertices int
convexPoly double
x1 double
y1 double
x2 double
y2 double
polys double
return int
        private int SplitConvexPolygon(int numvertices, double[] convexPoly, double x1, double y1, double x2, double y2, ref double[][] polys)
        {
            // state = 0: before the first intersection (with the line)
            // state = 1: after the first intersection (with the line)
            // state = 2: after the second intersection (with the line)

            int state = 0;
            double[] p = new double[3];
            // poly1 is constructed in states 0 and 2
            double[] poly1 = new double[100];
            int poly1counter = 0;
            // poly2 is constructed in state 1
            double[] poly2 = new double[100];
            int poly2counter = 0;
            int numpolys;
            int i;
            double compConst = 0.000000000001;
            // for debugging
            int case1 = 0, case2 = 0, case3 = 0, case31 = 0, case32 = 0, case33 = 0, case311 = 0, case3111 = 0;
            // intersect all edges of poly with line
            for (i = 0; i < 2 * numvertices; i = i + 2)
            {
                int j = (i + 2 >= 2 * numvertices) ? 0 : i + 2;
                LineLineSegmentIntersection(x1, y1, x2, y2, convexPoly[i], convexPoly[i + 1], convexPoly[j], convexPoly[j + 1], ref p);
                // if this edge does not intersect with line
                if (Math.Abs(p[0] - 0.0) <= compConst)
                {
                    //System.out.println("null");
                    // add p[j] to the proper polygon
                    if (state == 1)
                    {
                        poly2counter++;
                        poly2[2 * poly2counter - 1] = convexPoly[j];
                        poly2[2 * poly2counter] = convexPoly[j + 1];
                    }
                    else
                    {
                        poly1counter++;
                        poly1[2 * poly1counter - 1] = convexPoly[j];
                        poly1[2 * poly1counter] = convexPoly[j + 1];
                    }
                    // debug
                    case1++;
                }
                // ... or if the intersection is the whole edge
                else if (Math.Abs(p[0] - 2.0) <= compConst)
                {
                    //System.out.println(o);
                    // then we can not reach state 1 and 2
                    poly1counter++;
                    poly1[2 * poly1counter - 1] = convexPoly[j];
                    poly1[2 * poly1counter] = convexPoly[j + 1];
                    // debug
                    case2++;
                }
                // ... or if the intersection is a point
                else
                {
                    // debug
                    case3++;
                    // if the point is the second vertex of the edge
                    if (Math.Abs(p[1] - convexPoly[j]) <= compConst && Math.Abs(p[2] - convexPoly[j + 1]) <= compConst)
                    {
                        // debug
                        case31++;
                        if (state == 1)
                        {
                            poly2counter++;
                            poly2[2 * poly2counter - 1] = convexPoly[j];
                            poly2[2 * poly2counter] = convexPoly[j + 1];
                            poly1counter++;
                            poly1[2 * poly1counter - 1] = convexPoly[j];
                            poly1[2 * poly1counter] = convexPoly[j + 1];
                            state++;
                        }
                        else if (state == 0)
                        {
                            // debug
                            case311++;
                            poly1counter++;
                            poly1[2 * poly1counter - 1] = convexPoly[j];
                            poly1[2 * poly1counter] = convexPoly[j + 1];
                            // test whether the polygon is splitted
                            // or the line only touches the polygon
                            if (i + 4 < 2 * numvertices)
                            {
                                int s1 = LinePointLocation(x1, y1, x2, y2, convexPoly[i], convexPoly[i + 1]);
                                int s2 = LinePointLocation(x1, y1, x2, y2, convexPoly[i + 4], convexPoly[i + 5]);
                                // the line only splits the polygon
                                // when the previous and next vertex lie
                                // on different sides of the line
                                if (s1 != s2 && s1 != 0 && s2 != 0)
                                {
                                    // debug
                                    case3111++;
                                    poly2counter++;
                                    poly2[2 * poly2counter - 1] = convexPoly[j];
                                    poly2[2 * poly2counter] = convexPoly[j + 1];
                                    state++;
                                }
                            }
                        }
                    }
                    // ... if the point is not the other vertex of the edge
                    else if (!(Math.Abs(p[1] - convexPoly[i]) <= compConst && Math.Abs(p[2] - convexPoly[i + 1]) <= compConst))
                    {
                        // debug
                        case32++;
                        poly1counter++;
                        poly1[2 * poly1counter - 1] = p[1];
                        poly1[2 * poly1counter] = p[2];
                        poly2counter++;
                        poly2[2 * poly2counter - 1] = p[1];
                        poly2[2 * poly2counter] = p[2];
                        if (state == 1)
                        {
                            poly1counter++;
                            poly1[2 * poly1counter - 1] = convexPoly[j];
                            poly1[2 * poly1counter] = convexPoly[j + 1];
                        }
                        else if (state == 0)
                        {
                            poly2counter++;
                            poly2[2 * poly2counter - 1] = convexPoly[j];
                            poly2[2 * poly2counter] = convexPoly[j + 1];
                        }
                        state++;
                    }
                    // ... else if the point is the second vertex of the edge
                    else
                    {
                        // debug
                        case33++;
                        if (state == 1)
                        {
                            poly2counter++;
                            poly2[2 * poly2counter - 1] = convexPoly[j];
                            poly2[2 * poly2counter] = convexPoly[j + 1];
                        }
                        else
                        {
                            poly1counter++;
                            poly1[2 * poly1counter - 1] = convexPoly[j];
                            poly1[2 * poly1counter] = convexPoly[j + 1];
                        }
                    }
                }
            }
            // after splitting the state must be 0 or 2
            // (depending whether the polygon was splitted or not)
            if (state != 0 && state != 2)
            {
                // 		printf("there is something wrong state: %d\n", state);
                // 		printf("polygon might not be convex!!\n");
                // 		printf("case1: %d\ncase2: %d\ncase3: %d\ncase31: %d case311: %d case3111: %d\ncase32: %d\ncase33: %d\n", case1, case2, case3, case31, case311, case3111, case32, case33);
                // 		printf("numvertices %d\n=============\n", numvertices);
                // if there is something wrong with the intersection, just ignore this one
                numpolys = 3;
            }
            else
            {
                // finally convert the vertex lists into convex polygons
                numpolys = (state == 0) ? 1 : 2;
                poly1[0] = poly1counter;
                poly2[0] = poly2counter;
                // convert the first convex polygon
                polys[0] = poly1;
                // convert the second convex polygon
                if (state == 2)
                {
                    polys[1] = poly2;
                }
            }
            return numpolys;
        }