您的位置:首页 > 编程语言 > Go语言

Algorithm Design——判断线段是否相交

2013-12-01 11:03 225 查看
/**
给出线段AB以及线段CD,只要判断A、B两点在直线CD的两端,并且C、D两点在直线AB的两端即可。
用叉乘进行判断。

问题描述
下面给出的是一个判断线段相交的次数

输入:
n:线段的个数
seg.begin.x,seg.begin.y,seg.end.x,seg.end.y:分别表示线段p1p2的点坐标

输出:
n个线段中两两相交的次数

样例输入
2
1 0 0 0
0 1 0 0
样例输出:
1
*/

#include<cstdio>
using namespace std;

struct point
{
double x, y;
};

struct segment
{
point begin, end;
};

double min(double x, double y)
{
return (x < y) ? x : y;
}

double max(double x, double y)
{
return (x > y) ? x : y;
}

//判断pk是否在线段<pi, pj>上
bool onsegment(point pi, point pj, point pk)
{
if(min(pi.x, pj.x) <= pk.x && pk.x <= max(pi.x, pj.x))
{
if(min(pi.y, pj.y) <= pk.y && pk.y <= max(pi.y, pj.y))
{
return true;
}
}
return false;
}

//计算向量<pk, pi>与向量<pj, pi>的叉乘
double direction(point pi, point pj, point pk)
{
return (pi.x - pk.x) * (pi.y - pk.y) - (pi.x - pj.x) * (pi.y - pk.y);
}

//判断p1p2以及p3p4是否相交
bool judge(point p1, point p2, point p3, point p4)
{
double d1 = direction(p3, p4, p1);
double d2 = direction(p3, p4, p2);
double d3 = direction(p1, p2, p3);
double d4 = direction(p1, p2, p4);

if((d1 * d2 < 0) && (d3 * d4 < 0))
return true;

//判断点是否在另一个线段上(包罗万象)
if((d1 == 0) && onsegment(p3, p4, p1))
return true;
if((d2 == 0) && onsegment(p3, p4, p2))
return true;
if((d3 == 0) && onsegment(p1, p2, p3))
return true;
if((d4 == 0) && onsegment(p1, p2, p4))
return true;

return  false;
}

int main()
{
int n, count;
segment seg[101];
while(scanf_s("%d", &n, 1) != EOF && n != 0)
{
count = 0;
for(int i = 1 ; i <= n ; i ++)
{
scanf_s("%d%d%d%d", &seg[i].begin.x, &seg[i].begin.y, &seg[i].end.x, &seg[i].end.y);
}

for(int i = 1 ; i < n ; i ++)
{
for(int j = i + 1 ; j <= n ; j ++)
{
if(judge(seg[i].begin, seg[i].end, seg[j].begin, seg[j].end))
count ++;
}
}

printf_s("%d\n", count);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: