简介:
在GIS算法中我们最常用的算法计算,面和面是否相交,线段之间是否相交,今天我就分享一个直线或线段与线段相交并求其交点的算法。
基本思路:
如图:(请忽略我的作图水平)
1. 则先判断L0和L1是否相交,如图进行两次跨立实验 分别是q1q2和q1p2结果为temp1,q1q2和q1p1结果为temp2.
2. 根据temp1和temp2的值的正负,是否为0,进行考虑。
if((temp1==0)&&(temp2!=0))//p1在q1q2方向
else if((temp1!=0)&&(temp2==0))//p2在q1q2方向
else if((temp1==0)&&(temp2==0))//p1p2在q1q2方向共线
else if(temp1*temp2>0)printf("线不相交无交点)");//p1p2在q1q2同一侧无交点
else if(temp1*temp2<0)//有交点且不共线,可将L0,L1都当成直线看了
3.最后考虑相交且不共线的情况,计算出直线方程,进行求解。
#完整代码:
#include<stdio.h>
#include<math.h>
typedef struct {
float x;
float y;
}spot;
spot input(spot p)
{
//printf("输入点:\n");
scanf("%f%f",&p.x,&p.y);
return p;
}
float max(float x,float y)
{
return (x>y)?x:y;
}
float min(float x,float y)
{
return (x>y)?y:x;
}
int main()
{
spot p1,p2,q1,q2;
int type;
float k0,k1,b0,b1;
printf("请输入线段L0的两个端点p1,p2\n");
p1=input(p1);
p2=input(p2);
printf("请输入线段L1的两个端点q1,q2\n");
q1=input(q1);
q2=input(q2);
printf("请输入线段L1是线段还是直线输入1为线段2为直线:\n");
scanf("%d",&type);
//判断是否相交,跨立实验
float temp2,temp1;
temp2 = (p2.x-q1.x)*(q2.y-q1.y)-(p2.y-q1.y)*(q2.x-q1.x);//(p2-q1)(q2-q1)
temp1 = (p1.x-q1.x)*(q2.y-q1.y)-(p1.y-q1.y)*(q2.x-q1.x);//(p1-q1)(q2-q1)
//printf("%f,%f",temp1,temp2);
if((temp1==0)&&(temp2!=0))//p1在q1q2方向
{
if(type==2)printf("只有一个交点且为p1:(%f,%f)",p1.x,p1.y);
else{if(p1.x>max(q1.x,q2.x)||p1.x<min(q1.x,q2.x))printf("无交点");
else printf("只有一个交点且为p1:(%f,%f)",p1.x,p1.y);}
}
else if((temp1!=0)&&(temp2==0))//p2在q1q2方向
{
if(type==2)printf("只有一个交点且为p2:(%f,%f)",p2.x,p2.y);
else{if(p2.x>max(q1.x,q2.x)||p2.x<min(q1.x,q2.x))printf("无交点");
else printf("只有一个交点且为p1:(%f,%f)",p2.x,p2.y);}
}
else if((temp1==0)&&(temp2==0))//p1p2在q1q2方向共线
{
if(type==2)printf("共线无数交点\");
else {if(min(p1.x,p2.x)>max(q1.x,q2.x)||max(p1.x,p2.x)<min(q1.x,q2.x))printf("无交点");
else if(min(p1.x,p2.x)==max(q1.x,q2.x))printf("只有一个交点且为p:(%f,%f)",max(q1.x,q2.x),max(q1.y,q2.y));
else if(max(p1.x,p2.x)==min(q1.x,q2.x))printf("只有一个交点且为p:(%f,%f)",min(q1.x,q2.x),min(q1.y,q2.y));
else printf("共线无数交点)");}
}
else if(temp1*temp2>0)printf("线不相交无交点)");//p1p2在q1q2同一侧无交点
else if(temp1*temp2<0)//有交点且不共线,可将L0,L1都当成直线看了
{
//排除斜率为0,和斜率不存在的情况,为后面求斜率排除bug
if(p1.x==p2.x){
k1 = (q2.y-q1.y)/(q2.x-q2.x);
b1 = q1.y-k1*q1.x;
printf("只有一个交点且为p:(%f,%f)",p1.x,(k1*p1.x+b1));}
if(q1.x==q2.x){
k0 = (p2.y-p1.y)/(p2.x-p2.x);
b0 = p1.y-k1*p1.x;
printf("只有一个交点且为p:(%f,%f)",q1.x,(k0*q1.x+b0));}
if(p1.y==p2.y){
k1 = (q2.y-q1.y)/(q2.x-q2.x);
b1 = q1.y-k1*q1.x;
printf("只有一个交点且为p:(%f,%f)",((p1.y-b1)/k1),p1.y);}
if(q1.y==q2.y){
k0 = (p2.y-p1.y)/(p2.x-p2.x);
b0 = p1.y-k1*p1.x;
printf("只有一个交点且为p:(%f,%f)",((q1.y-b0)/k0),q1.y);}
k0 = (p2.y-p1.y)/(p2.x-p1.x);
b0 = p1.y-k0*p1.x;
k1 = (q2.y-q1.y)/(q2.x-q1.x);
b1 = q1.y-k1*q1.x;
printf("%f,%f",k0,b0);
float x ,y;
x = (b1-b0)/(k0-k1);
y = x*k0+b0;
printf("只有一个交点且为p:(%f,%f)",x,y);
}
}