版权声明:原创文章如需转载请注明出处 https://blog.csdn.net/holly_Z_P_F/article/details/84792291
题意:
解题思路:
刚开始想了个思路 算斜率判断相交 然后发现需要特判的情况很多,斜率为0, 斜率不存在 ,一个有斜率,一个没斜率,一个斜率是0,一个不是0,两个都是0.。。。。。简直要烦死,程序改了又改,最终写了六层大嵌套if else判断语句 实在写不下去了 百度一搜 果然 又是万恶的线性代数 叉乘!
唉 早该想到的 上次写三角形顺序用的就是叉乘
做法:
两个线段 四个点 判断线段是否相交 ---->就是判断一条线段和一个直线是否相交
如果 c和d在直线 ab 的两侧 那么 线段cd 一定和直线 ab 相交
同理 如果a和b在直线 cd 两侧 那么直线cd一定和线段ab相交
而这两个条件同时成立 就说明 线段ab和线段cd一定相交
那如何判断两个点是否在直线的两侧呢
叉乘
根据右手定则
向量ab 叉乘 向量bc 与 向量ab 叉乘 向量bd 符号相反 说明c d在ab两侧 符号相同 说明在同一侧
好了 做两次叉乘 问题就解决了
作为一个线性代数不好的人 这里记录下叉乘的做法
各个点坐标 a(a1,a2) b(b1,b2) c(c1,c2) d(d1,d2)
向量ab (b1-a1 , b2-a2, 0)
向量bc (c1-b1 , c2-b2, 0)
向量bd (d1-b1 , d2-b2, 0)
ab叉乘bc
| i j k |
|b1-a1 b2-a2 0 |
|c1-b1 c2-b2 0 |
就等于 k* 就等于k* (b1-a1)*(c2-b2)-(c1-b1)*(b2-a2)
代码如下
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long ll;
int T;
bool cc(double a1,double a2,double b1,double b2,double c1,double c2,double d1,double d2){
//向量ab (b1-a1,b2-a2,0)
//向量bc (c1-b1,c2-b2,0)
//向量bd (d1-b1,d2-b2,0)
double x=(b1-a1)*(c2-b2)-(c1-b1)*(b2-a2); //ab bc 叉乘
double y=(b1-a1)*(d2-b2)-(d1-b1)*(b2-a2); //ab bd 叉乘
if(x*y<=0)return true;
else return false;
}
int main(){
scanf("%d",&T);
double ax,ay,bx,by,cx,cy,dx,dy;
while(T--){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy);
if(cc(ax,ay,bx,by,cx,cy,dx,dy)&&cc(cx,cy,dx,dy,ax,ay,bx,by)){
printf("Yes\n");
}
else{
printf("No\n");
}
}
return 0;
}