Intersecting Lines(判断线段相交)

题目:http://poj.org/problem?id=1269

 

题意:给出两条直线(4个点),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。

 

分析:先判断是否共线,否则判断是否平行,否则只能相交,求出交点。


所用到的公式:


1、已知(x1,y1),求ax+by+c=0;
   a=y2-y1;b=x1-x2;c=y1 * x2 - x1 * y2;


2、已知(x0,y0),求关于ax+by+c=0的对称点(x1,y1);
   k=-2*(a*x0+b*y0+c)/(a*a+b*b);

   x1=x0+k*a;

   y1=y0+k*b;


3、已知a1x+b1y+c1=0,a2x+b2y+c2=0,求交点(x1,y1);

   x1=(c2*b1-c1*b2)/(a1*b2-a2*b1);

   y1=(-a1*x1-c1)/b1;


<span style="font-size:12px;">    //直线AB与直线CD的关系,如果相交就输出交点坐标  
    void Solve(Point A,Point B,Point C,Point D)  
    {  
        if(fabs(cross(A,B,C))<=EPS&&fabs(cross(A,B,D))<=EPS) puts("LINE");  //共线  
        else if((B.x-A.x)*(D.y-C.y)==(D.x-C.x)*(B.y-A.y))    puts("NONE");  //平行  
        else   //相交  
        {  
            double a1=A.y-B.y;  
            double b1=B.x-A.x;  
            double c1=A.x*B.y-B.x*A.y;  
      
            double a2=C.y-D.y;  
            double b2=D.x-C.x;  
            double c2=C.x*D.y-D.x*C.y;  
      
            double x=(b1*c2-b2*c1)/(a1*b2-a2*b1);  
            double y=(a2*c1-a1*c2)/(a1*b2-a2*b1);  
      
            printf("%.2lf %.2lf\n",x,y);  
        }  
    } </span> 


AC代码:

<span style="font-size:12px;">#include <cstdio>
#include <cmath>
#include <iostream>
#define exp 1e-10 //两个向量的叉积等于0,说明两向量共线;(通过一元函数证明);

using namespace std;

struct Point
{
    double x1,x2,y1,y2;
}A,B;


double cross(double x1, double y1, double x2, double y2)
{
    return x1 * y2 - x2 * y1;
}

void check(Point a, Point b)
{
    double c[4];
    c[0] = cross(a.x2 - a.x1, a.y2 - a.y1, b.x1 - a.x1, b.y1 - a.y1);
    c[1] = cross(a.x2 - a.x1, a.y2 - a.y1, b.x2 - a.x1, b.y2 - a.y1);
//    c[2] = cross(b.x2 - b.x1, b.y2 - b.y1, a.x1 - b.x1, a.y1 - b.y1);
//    c[3] = cross(b.x2 - b.x1, b.y2 - b.y1, a.x2 - b.x1, a.y2 - b.y1);
    if(fabs(c[0])<= exp && fabs(c[1])<= exp) puts("LINE"); //两向量的叉积为0,则共线;
    else  if( (a.x1 - a.x2) * (b.y1 - b.y2) == (a.y1 - a.y2) * (b.x1 - b.x2) ) puts("NONE"); //平行,斜率相等,不共线肯定平行;
    else //求交点(计算几何公式)
    {
        double a1 = a.y2 - a.y1;
        double b1 = a.x1 - a.x2;
        double c1 = a.y1 * a.x2 - a.x1 * a.y2;

        double a2 = b.y2 - b.y1;
        double b2 = b.x1 - b.x2;
        double c2 = b.y1 * b.x2 - b.x1 * b.y2;

        double x = (b1 * c2 - b2 * c1) / (a1 * b2 - b1 * a2);
        double y = (a2 * c1 - a1 * c2) / (a1 * b2 - b1 * a2);

        printf("POINT %.2lf %.2lf\n",x,y);
    }
}


int main()
{
    int n;
//    freopen("in.txt","r",stdin);
    scanf("%d",&n);
    puts("INTERSECTING LINES OUTPUT");
    while(n--)
    {
        scanf("%lf %lf %lf %lf",&A.x1,&A.y1,&A.x2,&A.y2);
        scanf("%lf %lf %lf %lf",&B.x1,&B.y1,&B.x2,&B.y2);
        check(A,B);
    }
    puts("END OF OUTPUT");
    return 0;
}</span>



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值