根据算法导论33章里的算法实现。
算法如下:
代码如下:
#include <stdio.h> struct point { int x; int y; }; int cross_product(struct point *p1, struct point *p2) { return p1->x * p2->y - p1->y * p2->x; } int on_segment(struct point *pi, struct point *pj, struct point *pk) { int max_x, max_y, min_x, min_y; max_x = pi->x > pj->x ? pi->x : pj->x; max_y = pi->y > pj->y ? pi->y : pj->y; min_x = pi->x < pj->x ? pi->x : pj->x; min_y = pi->y < pj->y ? pi->y : pj->y; if(pk->x >= min_x && pk->x <= max_x && pk->y >= min_y && pk->y <= max_y) { return 1; } else { return 0; } } int direction(struct point *pi, struct point *pj, struct point *pk) { struct point p1 = {pk->x - pi->x, pk->y - pi->y}; struct point p2 = {pj->x - pi->x, pj->y - pi->y}; return cross_product(&p1, &p2); } int segments_intersect(struct point *p1, struct point *p2, struct point *p3, struct point *p4) { int d1 = direction(p1, p2, p3); int d2 = direction(p1, p2, p4); int d3 = direction(p3, p4, p1); int d4 = direction(p3, p4, p2); if( (((d1 > 0) && (d2 < 0)) || ((d1 < 0) && (d2 > 0))) && (((d3 > 0) && (d4 < 0)) || ((d3 < 0) && (d4 > 0))) ) { return 1; } if( d1 == 0 && on_segment(p1, p2, p3) == 1) { return 1; } if(d2 == 0 && on_segment(p1, p2, p4) == 1) { return 1; } if(d3 == 0 && on_segment(p3, p4, p1) == 1) { return 1; } if(p4 == 0 && on_segment(p3, p4, p2) == 1) { return 1; } return 0; } int main(int argc, char **argv) { struct point p1, p2, p3, p4; FILE *fp = freopen("/home/xx/data.dat", "r", stdin); if(!fp) { return -1; } scanf("%d %d", &p1.x, &p1.y); scanf("%d %d", &p2.x, &p2.y); scanf("%d %d", &p3.x, &p3.y); scanf("%d %d", &p4.x, &p4.y); int ret = segments_intersect(&p1, &p2, &p3, &p4); return 0; }
$ cat ~/data.dat -20 -10 5 9 -10 -30 2 19
可以用图像验证。
gnuplot> plot 'data.dat' w lp