判断两条直线(线段)的交点问题


要判断两条直线是否有交点首先要求出两直线的斜率,如果相等级两直线平行的话就肯定没有了,反之就一定有了,就可以联立两条直线的方程(我们假定直线的方程都是可以表示出来的),求出两直线的交点然后结果就有了,但是如果是判断线段有无交点的话,我们就要加一步判断了,先按照直线的步骤求出交点,这里设交点是(x0,y0),那么如果交点的坐标都在已知的两条线段的中间,那么就是这个交点就存在啦。
下面给出杭电上的一道题hdu1086.借题来说明一下。


You can Solve a Geometry Problem too

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7770    Accepted Submission(s): 3793


Problem Description
Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is very easy, after all we are now attending an exam, not a contest :)
Give you N (1<=N<=100) segments(线段), please output the number of all intersections(交点). You should count repeatedly if M (M>2) segments intersect at the same point.

Note:
You can assume that two segments would not intersect at more than one point. 
 

Input
Input contains multiple test cases. Each test case contains a integer N (1=N<=100) in a line first, and then N lines follow. Each line describes one segment with four float values x1, y1, x2, y2 which are coordinates of the segment’s ending. 
A test case starting with 0 terminates the input and this test case is not to be processed.
 

Output
For each case, print the number of intersections, and one line one case.
 

Sample Input
 
   
2 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.00 3 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.000 0.00 0.00 1.00 0.00 0
 

Sample Output
 
   
1 3
 

Author
lcy
 

首先说明一下这题的数据真的好水。。

#include 
#include 
#include 
using namespace std;

double f(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double x)
{
    double x0,y0;
    x0 = ((x2-x1)*(x4-x3)*(y3-y1)+(y2-y1)*(x4-x3)*x1-(y4-y3)*(x2-x1)*x3)/(-x);
    y0 = ((y2-y1)*(y4-y3)*(x3-x1)+(x2-x1)*(y4-y3)*y1-(x4-x3)*(y2-y1)*y3)/(x);
    //printf(">>%lf%lf<<\n",x0,y0);
    if((x0-x1)*(x0-x2)<=0 && (x0-x3)*(x0-x4) <=0 && (y0-y1)*(y0-y2) <=0 && (y0-y3)*(y0-y4) <=0)
    return 1;
    else
        return 0;
}
int main()
{
    int n;
    int i,j;
    double x1[102],x2[102],y1[102],y2[102];
    while (~scanf("%d",&n))
    {
        if(n == 0)
            break;
        int ans = 0;
        for(i = 0 ; i < n; i++)
        {
            scanf("%lf%lf%lf%lf",&x1[i],&y1[i],&x2[i],&y2[i]);
        }
        for(i = 0; i < n ;i++)
        {
            for(j = i+1; j < n ;j++)
            {
                int d = (y2[i]-y1[i])*(x1[j]-x2[j]) - (x2[i]-x1[i])*(y1[j]-y2[j]);
             //   printf(">>%d<<",d);
                if(d == 0)
                    continue;
                else
                {
                    if(f(x1[i],y1[i],x2[i],y2[i],x1[j],y1[j],x2[j],y2[j],d)&&f(x1[j],y1[j],x2[j],y2[j],x1[i],y1[i],x2[i],y2[i],d))
                        ans++;
                }

            }
        }
        printf("%d\n",ans);
    }

  //  cout << "Hello world!" << endl;
    return 0;
}

这题的问题是没有解决交点重合问题。。我还没想好,暂且放在这里,等想出办法来再写。。

给代码加一下备注啊

//首先判断d   =   (y2-y1)(x4-x3)-(y4-y3)(x2-x1),
 // 若d=0,则直线AB与CD平行或重合,
 // 若d!=0,则直线AB与CD有交点,设交点为E(x0,y0):
  // x0   =   [(x2-x1)*(x4-x3)*(y3-y1)+(y2-y1)*(x4-x3)*x1-(y4-y3)*(x2-x1)*x3]/d
  //y0   =   [(y2-y1)*(y4-y3)*(x3-x1)+(x2-x1)*(y4-y3)*y1-(x4-x3)*(y2-y1)*y3]/(-d)
 /* 求出交点后在判断交点是否在线段上,即判断以下的式子:
        (x0-x1)*(x0-x2) <=0
        (x0-x3)*(x0-x4) <=0
        (y0-y1)*(y0-y2) <=0
        (y0-y3)*(y0-y4) <=0
只有上面的四个式子都成立才可判定(x0,y0)是线段AB与CD的交点,否则两线段无交点*/






你可能感兴趣的:(算法)