zoukankan      html  css  js  c++  java
  • poj 1269 Intersecting Lines——叉积求直线交点坐标

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

    相关知识:

    叉积
    求面积:https://www.cnblogs.com/xiexinxinlove/p/3708147.html
    什么是叉积:https://blog.csdn.net/sunbobosun56801/article/details/78980467
            其二维:https://blog.csdn.net/qq_38182397/article/details/80508303
    计算交点:
        方法1:面积的比例:https://blog.csdn.net/dgq8211/article/details/7952825
        方法2:叉积:https://blog.csdn.net/hktkfly6/article/details/69218777
                (其原因:https://www.jianshu.com/p/3468c9967fc7
    例题:POJ1269:https://www.xuebuyuan.com/1979631.html

    此题的链接使用的就是那个面积比例的方法。但自己不是很懂,所以用了那个另一种方法。

    利用面积算交点坐标应该还可以:https://www.cnblogs.com/Narh/p/9663099.html

      设直线有两个参数:p->起点坐标;t->终点坐标减起点坐标。设有线段 a 和 b 。设交点为 r 。

      double d=( (a.p-b.p)×a.t ) / ( b.t×a.t ) ,r = a.p + d * a.t ;

      那个 d 就是面积比,即交点与一条线段的相对该线段起点的坐标值之比。

        画一画,分子就是三角形面积的两倍,分母是那样的平行四边形的面积,但连一下发现它就是两线交叉的那个四边形的面积的两倍。面积比即高的比即那两段线段之比。

    关于这种方法的 a、b、c 怎么算,可以这样想:y=k*x+b 又 a*x+b*y+c=0 ,所以 a : b : c = -k : 1 : b;

      已知一条直线的两个点的坐标,联立可得 k=( y1-y2 ) / ( x1-x2 ) ; b=( x1*y2 - y1*x2 ) / ( x1-x2 ) ;

      所以 a : b : c = ( y2-y1) : ( x1-x2 ) : ( x1*y2 - y1*x2 ) 。可以说它们就等于这个,因为另一侧是0,可以随便乘。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define db double
    using namespace std;
    int T,tx,ty;
    struct Pt{
        db x,y;
        Pt(db x=0,db y=0):x(x),y(y) {}
    }ta,tb;
    struct Line{
        Pt p,t;
    }a,b;
    int operator* (const Pt &a,const Pt &b)
    {return a.x*b.y-a.y*b.x;}
    Pt operator- (const Pt &a,const Pt &b)
    {return Pt(a.x-b.x,a.y-b.y);}
    int check(Line a,Line b)
    {
        int d1=(b.p-a.p)*(a.t-a.p);
        int d2=(b.t-a.p)*(a.t-a.p);
        if(!d1&&!d2) return -1;//line
        if(d1==d2) return 1;//none
        if(d1*d2<=0) return 0;//point ==0 for 端点相交
    }
    Pt find(Line a,Line b)
    {
        db x1=a.p.x,y1=a.p.y,x2=a.t.x,y2=a.t.y;
        db a0=y2-y1,b0=x1-x2,c0=y1*x2-x1*y2;
        x1=b.p.x,y1=b.p.y,x2=b.t.x,y2=b.t.y;
        db a1=y2-y1,b1=x1-x2,c1=y1*x2-x1*y2;
        int tmp=a0*b1-a1*b0;
        return Pt((b0*c1-b1*c0)/tmp,(-a0*c1+a1*c0)/tmp);
    }
    int main()
    {
        scanf("%d",&T);
        puts("INTERSECTING LINES OUTPUT");
        while(T--)
        {
            scanf("%d%d",&tx,&ty); ta=Pt(tx,ty);
            scanf("%d%d",&tx,&ty); tb=Pt(tx,ty);
            a.p=ta; a.t=tb;
            scanf("%d%d",&tx,&ty); ta=Pt(tx,ty);
            scanf("%d%d",&tx,&ty); tb=Pt(tx,ty);
            b.p=ta; b.t=tb;
            int d=check(a,b);
            if(d==-1) puts("LINE");
            else if(d==1) puts("NONE");
            else
            {
                printf("POINT ");
                Pt c=find(a,b);
                printf("%.2lf %.2lf
    ",c.x,c.y);
            }
        }
        puts("END OF OUTPUT");
        return 0;
    }
  • 相关阅读:
    Linux软件安装
    虚拟地址和物理地址
    python 读写txt文件
    python 浮点数保留几位小数
    Contiki源码结构
    Contiki Rtimer 模块
    Contiki Ctimer模块
    Contiki Etimer 模块
    Contiki Timer & Stimer 模块
    Contiki clock模块
  • 原文地址:https://www.cnblogs.com/Narh/p/9678068.html
Copyright © 2011-2022 走看看