查看一个点是否位于一条直线(向量)上

Kar*_*son 0 c++ algorithm math

在此输入图像描述

我的程序中目前有以下行。我还有另外两个整数变量,xy

我想看看这个新点是否(x, y)在这条线上。我一直在看以下主题:

给定起点和终点以及距离,计算沿线的点

我想出了以下几点:

if(x >= x1 && x <= x2 && (y >= y1 && y <= y2 || y <= y1 && y >= y2))
{
    float vx = x2 - x1;
    float vy = y2 - y1;
    float mag = sqrt(vx*vx + vy*vy);
    // need to get the unit vector (direction)
    float dvx = vx/mag; // this would be the unit vector (direction) x for the line
    float dvy = vy/mag; // this would be the unit vector (direction) y for the line

    float vcx = x - x1;
    float vcy = y - y1;
    float magc = sqrt(vcx*vcx + vcy*vcy);
    // need to get the unit vector (direction)
    float dvcx = vcx/magc; // this would be the unit vector (direction) x for the point
    float dvcy = vcy/magc; // this would be the unit vector (direction) y for the point

    // I was thinking of comparing the direction of the two vectors, if they are the same then the point must lie on the line?
    if(dvcx == dvx && dvcy == dvy)
    {
        // the point is on the line!
    }
}
Run Code Online (Sandbox Code Playgroud)

它似乎不起作用,或者这个想法很糟糕?

Mik*_*our 5

浮点数的精度有限,因此计算时会出现舍入误差,结果是数学上应该相等的值最终会略有不同。

您需要以较小的误差容差进行比较:

if (std::abs(dvcx-dvx) < tolerance && std::abs(dvcy-dvy) < tolerance)
{
    // the point is (more or less) on the line!
}
Run Code Online (Sandbox Code Playgroud)

困难的部分是选择宽容。如果您不能接受任何错误,那么您需要使用固定精度浮点值以外的其他值(可能是整数),并重新排列计算以避免除法和其他不精确的运算。

无论如何,您可以更简单地完成此操作,无需平方根之类的东西。你想知道两个向量是否平行;如果矢量积为零,或者等价地,如果它们具有相等的切线,则它们是。所以你只需要

if (vx * vcy == vy * vcx)  // might still need a tolerance for floating-point
{
    // the point is on the line!
}
Run Code Online (Sandbox Code Playgroud)

如果您的输入是整数,足够小以至于乘法不会溢出,那么根本不需要浮点运算。