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;
}