/* check if (i, i + 2) is a diagonal */ static int dpd_isdiagonal(int i, int ip2, Ppoint_t ** pointp, int pointn) { int ip1, im1, j, jp1, res; /* neighborhood test */ ip1 = (i + 1) % pointn; im1 = (i + pointn - 1) % pointn; /* If P[i] is a convex vertex [ i+1 left of (i-1,i) ]. */ if (dpd_ccw(pointp[im1], pointp[i], pointp[ip1]) == ISCCW) res = (dpd_ccw(pointp[i], pointp[ip2], pointp[im1]) == ISCCW) && (dpd_ccw(pointp[ip2], pointp[i], pointp[ip1]) == ISCCW); /* Assume (i - 1, i, i + 1) not collinear. */ else res = ((dpd_ccw(pointp[i], pointp[ip2], pointp[ip1]) == ISCW) ); /* && (dpd_ccw (pointp[ip2], pointp[i], pointp[im1]) != ISCW)); */ if (!res) { return FALSE; } /* check against all other edges */ for (j = 0; j < pointn; j++) { jp1 = (j + 1) % pointn; if (!((j == i) || (jp1 == i) || (j == ip2) || (jp1 == ip2))) if (dpd_intersects (pointp[i], pointp[ip2], pointp[j], pointp[jp1])) { return FALSE; } } return TRUE; }
static int dpd_between (Ppoint_t * pa, Ppoint_t * pb, Ppoint_t * pc) { Ppoint_t pba, pca; pba.x = pb->x - pa->x, pba.y = pb->y - pa->y; pca.x = pc->x - pa->x, pca.y = pc->y - pa->y; if (dpd_ccw (pa, pb, pc) != ISON) return FALSE; return (pca.x * pba.x + pca.y * pba.y >= 0) && (pca.x * pca.x + pca.y * pca.y <= pba.x * pba.x + pba.y * pba.y); }
/* line to line intersection */ static int dpd_intersects (Ppoint_t *pa, Ppoint_t *pb, Ppoint_t *pc, Ppoint_t *pd) { int ccw1, ccw2, ccw3, ccw4; if (dpd_ccw(pa, pb, pc) == ISON || dpd_ccw (pa, pb, pd) == ISON || dpd_ccw (pc, pd, pa) == ISON || dpd_ccw (pc, pd, pb) == ISON) { if (dpd_between (pa, pb, pc) || dpd_between (pa, pb, pd) || dpd_between (pc, pd, pa) || dpd_between (pc, pd, pb)) return TRUE; } else { ccw1 = (dpd_ccw (pa, pb, pc) == ISCCW) ? 1 : 0; ccw2 = (dpd_ccw (pa, pb, pd) == ISCCW) ? 1 : 0; ccw3 = (dpd_ccw (pc, pd, pa) == ISCCW) ? 1 : 0; ccw4 = (dpd_ccw (pc, pd, pb) == ISCCW) ? 1 : 0; return (ccw1 ^ ccw2) && (ccw3 ^ ccw4); } return FALSE; }