nyoj 1132 promise me a medal(线段相交问题)

来源:互联网 发布:网络开发项目管理培训 编辑:程序博客网 时间:2024/06/16 03:03

题意:给你两条线段的四个端点,判断两条线段是否相交,相交并求交点。

这题不严谨,还有两条线段重合的部分,如果重合,交点有无数个,而ac的代码仅输出了重合的端点。

///判断两直线相交方法:两条相交的线段必然相互跨立,简单的讲就是p1和p2两点位于L2的两侧且p3和p4两点位于L1的两侧,这样就可利用外积做出判断了。#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;struct point{    double x,y;} a[4];bool Equal(double f1, double f2){    return (abs(f1 - f2) < 1e-4f);}bool operator==(const point &p1, const point &p2)///重载函数,用于判断两点是否相等{    return (Equal(p1.x, p2.x) && Equal(p1.y, p2.y));}bool operator>(const point &p1, const point &p2)///比较两点坐标大小,先比较x坐标,若相同则比较y坐标{    return (p1.x > p2.x || (Equal(p1.x, p2.x) && p1.y > p2.y));}double cross(point p1,point p2,point p3){    return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);}int main(){    int t;    double k1,k2,k3,k4,b1,b2,x,y,D,D1,D2;    cin>>t;    while(t--)    {        for(int i=0; i<4; i++)            cin>>a[i].x>>a[i].y;        if(a[0]>a[1])            swap(a[0],a[1]);        if(a[2]>a[3])            swap(a[2],a[3]);            ///为方便运算,保证各线段的起点在前,终点在后。        b1=(a[1].y-a[0].y)*a[0].x+(a[0].x-a[1].x)*a[0].y;        b2=(a[3].y-a[2].y)*a[2].x+(a[2].x-a[3].x)*a[2].y;        D=(a[1].x-a[0].x)*(a[3].y-a[2].y)-(a[3].x-a[2].x)*(a[1].y-a[0].y);        D1=b2*(a[1].x-a[0].x)-b1*(a[3].x-a[2].x);        D2=b2*(a[1].y-a[0].y)-b1*(a[3].y-a[2].y);        x=D1/D;        y=D2/D;        ///以上是根据坐标求交点        k1=cross(a[3],a[0],a[1]);        k2=cross(a[2],a[0],a[1]);        k3=cross(a[0],a[2],a[3]);        k4=cross(a[1],a[2],a[3]);        if(k1*k2==0&&k3*k4==0)///共线        {            if(a[1]==a[2])                printf("yes %.1lf %.1lf\n",a[1].x,a[1].y);            else if(a[3]==a[0])                printf("yes %.1lf %.1lf\n",a[3].x,a[3].y);                else if(a[1]>a[2])                    printf("yes %.1lf %.1lf\n",a[1].x,a[1].y);                else if(a[3]>a[0])                    printf("yes %.1lf %.1lf\n",a[3].x,a[3].y);            else                cout<<"no"<<endl;        }        else if(k1*k2<=0&&k3*k4<=0)///相交        {            printf("yes %.1lf %.1lf\n",x,y);        }        else            cout<<"no"<<endl;    }}


0 0
原创粉丝点击