两个直线/线段的交点 - C++

两个直线/线段的交点 - C++_第1张图片

问题,求上图中线段AB 和线段CD的交点P的坐标

根据《算法艺术与信息学竞赛》,公式如下

两个直线/线段的交点 - C++_第2张图片

 原理:

利用叉积求得点P分线段DC的比,然后利用高中学习的定比分点坐标公式求得分点P的坐标

要注意的是

若判断是两条线段,需先判断能否相交,相交的时候才可调用该公式求相交点

c++代码如下

#include
#include
#include
#include
using namespace std;

const double eps = 1e-6;

struct Point
{
    Point(){}
    Point(double x,double y):x(x),y(y){}
    double x,y;
};

int sgn(double x)
{
    return x<-eps ? -1 : (x>eps);
}

double Cross(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
    return (p2.x-p1.x)*(p4.y-p3.y) - (p2.y-p1.y)*(p4.x-p3.x);
}

double Area(const Point& p1,const Point& p2,const Point& p3)
{
    return Cross(p1,p2,p1,p3);
}

double fArea(const Point& p1,const Point& p2,const Point& p3)
{
    return fabs(Area(p1,p2,p3));
}

bool Meet(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
    return max(min(p1.x,p2.x),min(p3.x,p4.x)) <= min(max(p1.x,p2.x),max(p3.x,p4.x))
        && max(min(p1.y,p2.y),min(p3.y,p4.y)) <= min(max(p1.y,p2.y),max(p3.y,p4.y))
        && sgn(Cross(p3,p2,p3,p4) * Cross(p3,p4,p3,p1)) >= 0
        && sgn(Cross(p1,p4,p1,p2) * Cross(p1,p2,p1,p3)) >= 0;
}

Point Inter(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
    double k = fArea(p1,p2,p3) / fArea(p1,p2,p4);
    return Point((p3.x + k*p4.x)/(1+k),(p3.y + k*p4.y)/(1+k));
}

int main()
{
        Point p1(300, 300);
        Point p2(500, 500);

        Point p3(500, 300);
        Point p4(300, 500);

        if (Meet(p1, p2, p3, p4))
        {
                cout<< "p1p2和p3p4相交" <                 Point re = Inter(p1, p2, p3, p4);
                cout << re.x<                 cout << re.y <         }
        else
        {
                cout<< "p1p2和p3p4不相交" <         }

        Point p5(100, 100);
        Point p6(100, 500);
        if (Meet(p1, p2, p5, p6))
        {
                cout<< "p1p2和p5p6相交" <                 Point re = Inter(p1, p2, p5, p6);
                cout << re.x<                 cout << re.y <         }
        else
        {
                cout<< "p1p2和p5p6不相交" <         }
        return 0;
}

 执行结果如下图

两个直线/线段的交点 - C++_第3张图片

 

你可能感兴趣的:(两条直线的交点,两条线段的交点,线段的交点)