51node1264(判断线段相交)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1264

 

题意:中文题诶~

 

思路:对于直线a1a2, b1b2,我们可以通过跨立实验判断其是否相交(通过计算斜率也可以啦,不过好像有点麻烦);

其公式为:s=((向量)a1a2叉乘a1b1)*(a1a2)叉乘a1b2),若 s <=0 ,则有点b1, b2分别在线段a1a2的两边或者在同一条直线上;

我们可以很直观的知道如果a1, b2分别位于b1b2两边并且b1, b2分别位于a1a2两边,那么a1a2, b1b2一定相交;

所以我们之要通过两次跨立实验即可判断两直线是否相交,不过还要判断一下a1a2, b1b2处于同一条直线上的情况(我们前面说了跨立实验不能判断两直线是否位于同一条直线上嘛);

对于这点我们可以通过快速排斥实验解决啦;

 

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct node{
 5     double x, y;
 6 };
 7 
 8 double determinant(node a1, node a2, node b){ //用行列式计算有向面积
 9     double x1=a1.x-a2.x, x2=a1.x-b.x, y1=a1.y-a2.y, y2=a1.y-b.y;
10     return x1*y2-y1*x2;
11 }
12 
13 bool is_intersect(node a1, node a2, node b1, node b2){
14     if(max(a1.x, a2.x)<min(b1.x, b2.x)||max(b1.x, b2.x)<min(a1.x, a2.x)){ //快速排斥实验
15         return false;
16     }else if(max(a1.y, a2.y)<min(b1.y, b2.y)||max(b1.y, b2.y)<min(a1.y, a2.y)){
17         return false;
18     }
19     if(determinant(a1, a2, b1)*determinant(a1, a2, b2)>0){ //跨立实验
20         return false;
21     }else if(determinant(b1, b2, a1)*determinant(b1, b2, a2)>0){
22         return false;
23     }
24     return true;
25 }
26 
27 int main(void){
28     int t;
29     scanf("%d", &t);
30     while(t--){
31         node a1, a2, b1, b2;
32         scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &a1.x, &a1.y, &a2.x, &a2.y, &b1.x, &b1.y, &b2.x, &b2.y);
33         if(is_intersect(a1, a2, b1, b2)){
34             printf("Yes\n");
35         }else{
36             printf("No\n");
37         }
38     }
39     return 0;
40 }

 

posted @ 2017-01-02 17:28  geloutingyu  阅读(271)  评论(0编辑  收藏  举报