计算几何,判两线段相交模板

#include <stdio.h>
#include <math.h>
struct Point{double x,y;};

struct stline{Point a,b;} line1,line2;


int dblcmp(double a,double b)
{

if (fabs(a-b)<=1E-6) return 0;
if (a>b) return 1;
else return -1;
}

//***************点积判点是否在线段上***************

double dot(double x1,double y1,double x2,double y2) //点积
{
return x1*x2+y1*y2;
}

int point_on_line(Point a,Point b,Point c) //求a点是不是在线段bc上,>0不在,=0与端点重合,<0在。
{
return dblcmp(dot(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y),0);
}
//**************************************************

double cross(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
}

double ab_cross_ac(Point a,Point b,Point c) //ab与ac的叉集
{
return cross(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
}

int ab_cross_cd (Point a,Point b,Point c,Point d) //求ab是否与cd相交,交点为p。1规范相交,0交点是一线段的端点,-1不相交。
{
double s1,s2,s3,s4;
int d1,d2,d3,d4;
Point p;
d1=dblcmp(s1=ab_cross_ac(a,b,c),0);
d2=dblcmp(s2=ab_cross_ac(a,b,d),0);
d3=dblcmp(s3=ab_cross_ac(c,d,a),0);
d4=dblcmp(s4=ab_cross_ac(c,d,b),0);

//如果规范相交则求交点
if ((d1^d2)==-2 && (d3^d4)==-2)
{
   p.x=(c.x*s2-d.x*s1)/(s2-s1);
   p.y=(c.y*s2-d.y*s1)/(s2-s1);
   return 1;
}

//如果不规范相交
if (d1==0 && point_on_line(c,a,b)<=0)
{
   p=c;
   return 0;
}
if (d2==0 && point_on_line(d,a,b)<=0)
{
   p=d;
   return 0;
}
if (d3==0 && point_on_line(a,c,d)<=0)
{
   p=a;
   return 0;
}
if (d4==0 && point_on_line(b,c,d)<=0)
{
   p=b;
   return 0;
}
//如果不相交
return -1;
}
int main()
{
scanf("%lf%lf%lf%lf",&line1.a.x,&line1.a.y,&line1.b.x,&line1.b.y);
scanf("%lf%lf%lf%lf",&line2.a.x,&line2.a.y,&line2.b.x,&line2.b.y);
if (ab_cross_cd(line1.a,line1.b,line2.a,line2.b)>=0)
   printf("相交");
else printf("不相交");
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值