线段相交

线段相交——两个步骤:1、快速排斥。 2、跨立实验。

 

快速排斥:先最大限度的将buke不可能相交的情况给排除,例如 线段 : a——b  线段 :c——d 。(线段的表示都是点)

如果线段ab两点最大的坐标 x 的值都没有线段cd最小的x值大,这就可以确定 这两条线段肯定不相交。

 总共有四种情况 线段ab的坐标x,坐标y,线段cd的坐标x坐标y。

	if(min(a.y,b.y)>max(c.y,d.y)    || 
       max(a.x,b.x)<min(c.x,d.x)    || 
       min(c.y,d.y)>max(a.y,b.y)    || 
       max(c.x,d.x)<min(a.x,b.x)    ) //当满足这四种情况那线段肯定不相交
                        
		return false;

跨立实验:线段ab与线段cd相交的话,那么肯定会有 a、b 两点在线段cd的两侧,同理 cd也是 这时就需要判断线段ac、dc的叉积乘上 线段 bc、dc 的叉积的值是否小于0 如果小于0 代表在其两侧。则相交

	//跨立实验
	double u = (a.x-c.x)*(d.y-c.y)-(a.y-c.y)*(d.x-c.x);
	double v = (b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);
	double w = (c.x-b.x)*(a.y-b.y)-(a.x-b.x)*(c.y-b.y);
	double z = (d.x-b.x)*(a.y-b.y)-(a.x-b.x)*(d.y-b.y);
	if(u*v<=0.0000001 && w*z<=0.0000001)   
		return true;

 

全部代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
struct node {
	double x,y;
};
struct edge {
	node a,b;
} e[100];

int judge(edge xx,edge yy) {
	node a = xx.a;
	node b = xx.b;
	node c = yy.a;
	node d = yy.b;
	//快速排斥
	if(min(a.y,b.y)>max(c.y,d.y)|| max(a.x,b.x)<min(c.x,d.x) || min(c.y,d.y)>max(a.y,b.y) || max(c.x,d.x)<min(a.x,b.x))
		return false;
	//跨立实验
	double u = (a.x-c.x)*(d.y-c.y)-(a.y-c.y)*(d.x-c.x);
	double v = (b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);
	double w = (c.x-b.x)*(a.y-b.y)-(a.x-b.x)*(c.y-b.y);
	double z = (d.x-b.x)*(a.y-b.y)-(a.x-b.x)*(d.y-b.y);
	if(u*v<=0.0000001 && w*z<=0.0000001)
		return true;
}

int main() {
	scanf("%d",&n);
	for(int i=0; i<n; i++) {
		scanf("%lf%lf%lf%lf",&e[i].a.x,&e[i].a.y,&e[i].b.x,&e[i].b.y);
	}
	int res=0;
	for(int i=0; i<n; i++) {
		for(int j=i+1; j<n; j++) {
			if(judge(e[i],e[j]))
				res++;
		}
	}
	printf("%d\n",res);

	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值