计算几何算法基础————判断线段相交

计算几何中最基本重要的算法之一~判断线段相交基础。

只需判断线段是否同时满足

1.快速排斥实验

2.跨立实验


1.快速排斥实验:

设以线段P1P2为对角线的矩形为T,以Q1Q2线段为对角线的矩形为R,那么下图这种状态时P1P2和Q1Q2肯定不相交



判断P1 P2 Q1 Q2是否满足这种关系就是快速排斥实验。

max(p1.x,p2.x) < min(q1.x,q2,x) || max(q1.x,q2.x) < min(p1,x,p2,x) ||max(p1.y,p2.y) < min(q1.y,q2,y) || max(q1.y,q2.y) < min(p1.y,p2.y)

上式为真,则表明两个矩形不想交,一般是取上式的否定,直接判断是否满足矩形相交,即。

min(p1.x,p2.x) <= max(q1.x,q2,x) && min(q1.x,q2.x) <= max(p1,x,p2,x) &&min(p1.y,p2.y) <= max(q1.y,q2,y) && min(q1.y,q2.y) <= max(p1.y,p2.y)

2.跨立实验

前提:如果两线段相交,必定互相跨立。


也即是说:

1.P1 P2 在Q1Q2的两侧

2.Q1Q2 在P1P2的两侧

判断两点是否在一条直线的两侧就用到叉乘了。

(Q1P1 x Q1Q2) * (Q1Q2 x Q1P2)  <= 0 表示P1P2在Q1Q2的两侧

(P1Q2 x P1P2)  *  (P1P2 x P1Q2)  <= 0 表示Q1Q2在P1P2的两侧

这就满足跨立实验的要求了~

小试一下:HDU 1086 http://acm.hdu.edu.cn/showproblem.php?pid=1086

#include<stdio.h>
#include<stdlib.h>
//注意题目说了线段与线段之间最多只有一个交点,不存在重合或者在一条直线的情况 
struct line{
    double x1,y1;
    double x2,y2;
};
long Judge(struct line Line1,struct line Line2)//跨立实验 
{
    double Xa1 = Line1.x1;
    double Ya1 = Line1.y1;
    double Xa2 = Line1.x2;
    double Ya2 = Line1.y2;
    double Xb1 = Line2.x1;
    double Yb1 = Line2.y1;
    double Xb2 = Line2.x2;
    double Yb2 = Line2.y2;

    if(((Xa2-Xa1)*(Yb1-Ya1)-(Xb1-Xa1)*(Ya2-Ya1))*((Xa2-Xa1)*(Yb2-Ya1)-(Xb2-Xa1)*(Ya2-Ya1))>0)
        return 0;
    if(((Xb2-Xb1)*(Ya1-Yb1)-(Xa1-Xb1)*(Yb2-Yb1))*((Xb2-Xb1)*(Ya2-Yb1)-(Xa2-Xb1)*(Yb2-Yb1))>0)
        return 0;
    return 1;
}
int main()
{
    struct line Line[100];
    int num;
    
    while(scanf("%d",&num) != EOF && num)
    {
        int count = 0;
        for(int i = 0 ; i < num ; ++i)
        	scanf("%lf%lf%lf%lf",&Line[i].x1,&Line[i].y1,&Line[i].x2,&Line[i].y2);
        for(int i = 0 ; i < num - 1 ; ++i)
            for(int j = i + 1 ; j < num ; ++j)
                if(Judge(Line[i],Line[j]))
                	count++;
        printf("%d\n",count);
	}	
    return 0;
}


转载于:https://www.cnblogs.com/sixdaycoder/p/4348368.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值