原文参考博客http://blog.csdn.net/keyboarderqq/article/details/51222441
已知:其中一条线段两个端点为(x1,y1),(x2,y2),另一条线段的两个端点为(x3,y3),(x4,y4)
问题:判断两条线段是否相交
解题思路:
方法1:利用向量的叉积判断
(向量叉积得到的非零系数与0比较大小)
向量AB×向量AC>0 -----> C在直线AB上方
向量AB×向量AD<0 -----> D在直线AB下方
对于线段AB和线段BD,判断他们是否相交,只需利用上述原理,判断C和D是否位于AB所在直线的两侧以及判断
A和B是否位于CD所在直线的两侧即可,若是,则两条线段相交
具体代码:
#include<iostream>
#include<cmath>
using namespace std;
#define temp 1e-10
int main(){
double x1,y1,x2,y2,x3,y3,x4,y4;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
//共线的情况单独考虑
if( abs((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1))<temp ){
if( (x1==x3)&&((y3-y1)*(y3-y2)<=temp||(y4-y1)*(y4-y2)<=temp) ) printf("Yes\n");
else printf("No\n");
}
else{
double m=(x2-x1)*(y3-y1)-(x3-x1)*(y2-y1);
double n=(x2-x1)*(y4-y1)-(x4-x1)*(y2-y1);
double p=(x4-x3)*(y1-y3)-(x1-x3)*(y4-y3);
double q=(x4-x3)*(y2-y3)-(x2-x3)*(y4-y3);
if( m*n<=temp && p*q<=temp ) printf("Yes\n");
else printf("No\n");
}
return 0;
}
double x1,y1,x2,y2,x3,y3,x4,y4;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
//共线的情况单独考虑
if( abs((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1))<temp ){
if( (x1==x3)&&((y3-y1)*(y3-y2)<=temp||(y4-y1)*(y4-y2)<=temp) ) printf("Yes\n");
else printf("No\n");
}
else{
double m=(x2-x1)*(y3-y1)-(x3-x1)*(y2-y1);
double n=(x2-x1)*(y4-y1)-(x4-x1)*(y2-y1);
double p=(x4-x3)*(y1-y3)-(x1-x3)*(y4-y3);
double q=(x4-x3)*(y2-y3)-(x2-x3)*(y4-y3);
if( m*n<=temp && p*q<=temp ) printf("Yes\n");
else printf("No\n");
}
return 0;
}
方法2:利用直线的函数表达式判断
计算出AB、CD所在直线的函数表达式:
(1)当两条直线对的斜率都存在时,算出各点在另外一条直线上沿y轴方向的投影点,即A',B',C',D',如果(w1-y1)*(w2-y2)<=0 &&(w3-y3)*(w4-y4)<=0 ,则相交;
(2)当直线AB斜率不存在(即x1==x2),CD斜率存在时,算出点A,B在CD直线上沿y轴的投影点A',B',如果(w1-y1)*(w2-y2)<=0 &&(x3-x1)*(x4-x1)<=0,则相交;
(3)当直线CD斜率不存在(即x3==x4),AB斜率存在时,算出点C,D在AB直线上沿y轴的投影点A',B',如果(w3-y3)*(w4-y4)<=0 &&(x1-x3)*(x2-x3)<=0,则相交;
(4)当斜率都不存在时,如果(x1==x3)&&((y3-y1)*(y3-y2)<=0 || (y4-y1)*(y4-y2)<=0),则相交。
具体代码:
double x1,y1,x2,y2,x3,y3,x4,y4;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
double k1,k2;
double b1,b2;
double w1,w2,w3,w4;
int flag=0;
if(x2==x1&&x3==x4){
if( (x1==x3)&&((y3-y1)*(y3-y2)<=temp||(y4-y1)*(y4-y2)<=temp) ) flag=2;
else flag=0;
}
else{
if(x2!=x1){
k1=(double)(y2-y1)/(x2-x1);
b1=y1-k1*x1;
w3=k1*x3+b1;
w4=k1*x4+b1;
if( (w3-y3)*(w4-y4)<=temp ) flag++;
}
else if( (x3-x1)*(x4-x1)<=temp ) flag++;
if(flag){
if(x3!=x4){
k2=(double)(y3-y4)/(x3-x4);
b2=y3-k2*x3;
w1=k2*x1+b2;
w2=k2*x2+b2;
if( (w1-y1)*(w2-y2)<=temp ) flag++;
}
else if( (x1-x3)*(x2-x3)<=temp ) flag++;
}
}
if(flag==2) printf("Yes\n");
else printf("No\n");
return 0;
}
(第一次发博客,如有错误还请指正,不胜感激)