交点 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 L2 即 intersection_Y = m2 * intersection_X +c2
intersection_Y 应该相等。
如果你 运行 下面的代码并检查 point1.Y 和 Y,你会发现两者都是 不等于.
我认为这里的精度处理有问题。
由于这种差异,崩溃正在发生。
有人可以投光吗?
#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 之间的一个点处相交。
假设我们有两条线。
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 L2 即 intersection_Y = m2 * intersection_X +c2
intersection_Y 应该相等。
如果你 运行 下面的代码并检查 point1.Y 和 Y,你会发现两者都是 不等于.
我认为这里的精度处理有问题。
由于这种差异,崩溃正在发生。
有人可以投光吗?
#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 之间的一个点处相交。