交点 Point1.Y 和 Y 应该相等。但是 Point1.Y 和 Y 有区别。为什么?

Intersection points Point1.Y and Y should be equal. But there is a difference in Point1.Y and Y. WHY?

假设我们有两条线。

L1: y1 = m1.x1 +c1
L2: y2 = m2.x2 +c2
such that m1 != m2

intersection_X = (c2 - c1) / (m1 - m2)
intersection_Y = m1 * intersection_X + c1

此外,如果我们计算 intersection_Y w.r.t L2intersection_Y = m2 * intersection_X +c2
intersection_Y 应该相等。
如果你 运行 下面的代码并检查 point1.YY,你会发现两者都是 不等于.
我认为这里的精度处理有问题。
由于这种差异,崩溃正在发生。
有人可以投光吗?


#include <iostream>
#include<cmath>
#include<limits>

using namespace std;

#define FUZZ_GEN (1e-9)       //tolerance for vertical check
#define FEQUAL(a, b, fuzz)  (fabs(a - b) <= (fuzz))

struct Point {
    double X, Y;
};

class LineSegment {            //Line class

public:
    LineSegment(double x1, double y1, double x2, double y2);

    void IntersectionPoints(LineSegment side);        

    double X1, Y1, X2, Y2, M, C;
};

LineSegment::LineSegment(double fX1, double fY1, double fX2, double fY2)   //Constructor for line
    : X1(fX1),
    Y1(fY1),
    X2(fX2),
    Y2(fY2)
{
    if (FEQUAL(X1, X2, FUZZ_GEN))     // if vertical, slope is inf.
    {
        M = C = std::numeric_limits<double>::infinity();        // slope undefined
    }
    else
    {

        M = (Y2 - Y1) / (X2 - X1);
        C = Y1 - (M * X1);
    }
}
void LineSegment::IntersectionPoints (LineSegment side) {

    Point point1;
    point1.X = (C - side.C) / (side.M - M);     //intersection point 1
    point1.Y = M * point1.X + C;
    
    double Y = side.M * point1.X + side.C;       // ?? Y != point1.Y
}

int main()
{
// data coming from lower level APIs. Can't be changed
    LineSegment side = LineSegment(10.267716536547709,   //create first line
            6.8779527559055005,
            10.031496064106765,
            6.8779527559055005);

    LineSegment line = LineSegment(10.149606299212586,     // create second line
        9.1220472440944818,
        10.149606296983265,
        4.2665936725507594);

    line.IntersectionPoints(side);  //call to calc intersection point 
    return  0;
}

有限个双精度浮点数。

这意味着两个浮点数之间有无限多个实数。浮点数之间存在 巨大差距 - 充满了你无法表示的数字!

当您定义两条线时,它们的交点非常不可能正好位于双精度浮点数上。它将位于数字之间的巨大空隙中。

想象一下,您放大得如此之深,以至于可以清楚地看到浮动数字之间的 space。您可以像下图那样可视化交叉点,其中网格线是浮点数:

如果这里的底角坐标x=0 y=0,那么离交点最近的x-axis值为x=2。但是,如果您计算 x=2 处的两条线,对于行 C-D,您将得到 y=2,而对于行 A-B,您将得到 y=3。为什么?因为这些线不在 (2,2) 或 (2,3) 处相交,所以它们在 space 之间的一个点处相交。