判断两条线段是否相交

Hdoj1086

 

题意,给你n条线段然后让你判断有几个交点。

 

所以思路就是判断两条线段是否相交,然后for一下就好了啊

 

 

那么怎么判断两条线段相交呢

 

1.      好像普遍用叉积的方法吧【T^T

叉积:矢量的矢量积

记作a×b,其模等于由b作成的平行四边形的面积,方向与平行四边形所在平面垂直。

判断两条线段是否相交_第1张图片

三角形ABC的面积=

1】那么我们知道叉积是正数, b 的顺时针方向;负数, 的顺时针方向; 0的话, 模相等且共线

(单纯补充)拉格朗日公式

a× (b×c) =b(a·c)-c(a·b),

那么根据【1】,我们就可以知道判定条件

       cb×cdcd×ca同号且bd×baba×bc同号时是相交的,否则不香蕉

 判断两条线段是否相交_第2张图片

 

2.   以前有一个学长说过一个idea,然后我也是一直这么做的

 

这里只讲相交时的情况;不香蕉时满不满足只能自己感受了。

判断两条线段是否相交_第3张图片

1】先根据一条线段,计算另一条线段的点在该线段的【直线上】的点的纵坐标,然后和原来的点的纵坐标比较,if((y3>=w3&&y4<=w4)||(y3<=w3&&y4>=w4))
 
 
2】再根据【另一条线段】,计算【另另线段】的点在【另一条线段】的【直线】上的点的纵坐标,然后比较,if((y2>=w2&&y1<=w1)||(y2<=w2&&y1>=w1))

 

3】当然你还得判断一下两条线段斜率的不存在的时候

其中一条线段斜率不存在时,判断另一条线段(斜率存在)的两点是否在该线段的两端;if((x3>=x2&&x4<=x2)||(x4>=x2&&x3<=x2))

//很明显这样一个条件是不能判断相交的,但是接下来还是要去判断上面的【1】或者【2

所以就可以证明了。

= =其实这样解释起来好烦

这道题看代码吧,代码可能好理解但是我觉得我讲的也蛮清楚的T^T

【判断两条线段相交的一道题目】

Description

   现在有两条线段在一个平面上,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)

Input

   第一行输入一个整数T,表示输入的测试数量(1<=T<=1000),后面T组测试用例,每组占一行,每行8个数

   x1,y1,x2,y2,x3,y3,x4,y4(-10^8 <= xi, yi <=10^8)直线1的两个端点为(x1,y1),(x2,y2)。直线2

   的两个端点为(x3,y3),(x4,y4)

Output

   输出共T行,如果相交输出"Yes",否则输出"No"

Sample Input

2

1 2 2 1 0 0 2 2

-1 1 1 1 0 0 1 -1

Sample Output

Yes

No

 

代码如下

#include 
#include 
#include 
#include 
#include 
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        double x1,x2,y1,y2,x3,x4,y3,y4,k1,k2;
        double w1,w2,w3,w4;
        int flag=0;
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
        if((x2-x1)==0)              //如果斜率不存在
        {
            if((x3>=x2&&x4<=x2)||(x4>=x2&&x3<=x2))
                flag+=1;
        }
        else                    //如果存在
        {
            k1=(double)(y2-y1)/(x2-x1);
            w3=k1*(x3-x2)+y2;
            w4=k1*(x4-x2)+y2;
            if((y3>=w3&&y4<=w4)||(y3<=w3&&y4>=w4))      //看图模拟
                flag+=1;
        }
        if((x4-x3)==0)                  //继续判断斜率是否存在
        {
            if((x2>=x3&&x1<=x3)||(x1>=x3&&x2<=x3))
                flag+=1;
        }
        else
        {
            k2=(double)(y4-y3)/(x4-x3);
            w1=k2*(x1-x3)+y3;
            w2=k2*(x2-x3)+y3;
            if((y2>=w2&&y1<=w1)||(y2<=w2&&y1>=w1))
                flag+=1;
        }
        if(flag==2)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}


ZOJ2870【判断 直线和线段相交】
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
typedef pair PII;
using namespace std;

bool Judge(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
{
        double k1,w3,w4;
        int flag=0;
        if((x2-x1)==0)              //如果斜率不存在
        {
            if((x3>=x2&&x4<=x2)||(x4>=x2&&x3<=x2))
                flag+=1;
        }
        else                    //如果存在
        {
            k1=(double)(y2-y1)/(x2-x1);
            w3=k1*(x3-x2)+y2;
            w4=k1*(x4-x2)+y2;
            if((y3>=w3&&y4<=w4)||(y3<=w3&&y4>=w4))      //看图模拟
                flag+=1;
        }
        if(flag) return true;
        return false;
}
int main()
{
    double x[205];
    double y[205];
    double po[105][4];
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int n1,n2;
        n1=n2=0;
        for(int i=0;i





你可能感兴趣的:(数学,hdoj,线段相交)