51nod1264線段相交
阿新 • • 發佈:2018-12-25
題意:
解題思路:
剛開始想了個思路 算斜率判斷相交 然後發現需要特判的情況很多,斜率為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;
}