ACM 几何基础(3)

2023-05-16

   几何基础(3

求线段交点:

前面已经讲了如何判断两条线段是否相交,现在我们来学下如何求线段的交点坐标

首先先了解下

定比分点公式

公式介绍

数学中常用的重要公式之一!

直角坐标系内,已知两点A(x1,y1),B(x2,y2);在两点连线上有一点P,设它的坐标为(x,y),且向量AP比向量PB的比值为λ,那么我们说P分有向线段AB的比为λ

P的坐标为

x=(x1 + λ · x2) / (1 + λ)

y=(y1 + λ · y2) / (1 + λ)



求得直线 AB 与直线 CD 的交点P



如此就可求出 λ

再有公式:

x=(x1 + λ · x2) / (1 + λ)

y=(y1 + λ · y2) / (1 + λ)

求出坐标.

 

 

point jiaodian(line l1,line l2)//求交点

{

 

    double t=fabs(((l1.e-l2.s)^(l1.s-l2.s))/((l1.e-l2.e)^(l1.s-l2.e)));

    point p;

    p.x=(l2.s.x+t*l2.e.x)/(1+t);

    p.y=(l2.s.y+t*l2.e.y)/(1+t);

    return p;

}

 

完整代码如下

#include <iostream>

#include <cstdio>

#include <cmath>

using namespace std;

const double eps=1e-8;

const double PI=acos(-1.0);

int sgn(double x)

{

    if(fabs(x)<eps) return 0;

    if(x < 0) return -1;

    else return 1;

}

 

struct point

{

    double x,y;

    point(){}

    point (double _x,double _y)

    {

        x=_x,y=_y;

    }

    point operator -(const point &b)const

    {

        return point(x-b.x,y-b.y);

    }

    point operator +(const point &b)const

    {

        return point (x+b.x,y+b.y);

    }

    double operator ^(const point &b)const //叉积

    {

        return x*b.y-y*b.x;

    }

    double operator *(const point &b)const //点积

    {

        return x*b.x+y*b.y;

    }

    void transxy(double B)  //绕原点旋转角度B(弧度值),后的xy

    {

        double tx=x,ty=y;

        x= tx*cos(B) - ty*sin(B);

        y= tx*sin(B) + ty*cos(B);

    }

};

 

struct line//线

{

    point s,e;

    line(){}

    line(point _s,point _e)

    {

        s=_s,e=_e;

    }

};

 

double dist(point a,point b)//两点间距离

{

    return sqrt((a-b)*(a-b));

}

 

bool inter(line l1,line l2)//判断线段相交

{

    return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&

    max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&

    max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&

    max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&

    sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&

    sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;

}

 

point jiaodian(line l1,line l2)//求交点

{

 

    double t=fabs(((l1.e-l2.s)^(l1.s-l2.s))/((l1.e-l2.e)^(l1.s-l2.e)));

    point p;

    p.x=(l2.s.x+t*l2.e.x)/(1+t);

    p.y=(l2.s.y+t*l2.e.y)/(1+t);

    return p;

}

bool inter_line(line l1,line l2)//判断直线与线段是否相交

{

    return sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0;

}

int main()

{

    double ax,ay,bx,by,cx,cy,dx,dy;

    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy)!=EOF)//分别输入两条线段的首尾端点

    {

        point k1(ax,ay);

        point k2(bx,by);

        point k3(cx,cy);

        point k4(dx,dy);

        line l1(k1,k2);

        line l2(k3,k4);

        if(inter(l1,l2))

            {

                printf("Yes\n");

                point p;

                p=jiaodian(l1,l2);

                printf("%lf %lf\n",p.x,p.y);

            }

        else

            printf("No\n");

    }

  //  printf("%lf %lf\n",ke.x,ke.y);

    return 0;

}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ACM 几何基础(3) 的相关文章

随机推荐