判断线段相交的实现

根据算法导论33章里的算法实现。

算法如下:

判断线段相交的实现_第1张图片


代码如下:

#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

输出结果为1.

可以用图像验证。

gnuplot> plot 'data.dat' w lp
判断线段相交的实现_第2张图片

你可能感兴趣的:(判断线段相交的实现)