提高 LineLine 相交法(3D)的数值精度
Improve numerical accuracy of LineLine intersection method (3D)
我编写了以下 LineLine 相交方法:
double LineLineIntersection(
const Eigen::Vector3d& origin1,
const Eigen::Vector3d& ray1,
const Eigen::Vector3d& origin2,
const Eigen::Vector3d& ray2)
{
if(abs((origin1 - origin2).norm() - 1.0) < 0.000001) return 0;
auto n1 = (origin2 - origin1).cross(ray2);
auto n2 = ray1.cross(ray2);
// Use this to test whether the vectors point in the same or opposite directions
auto n = n2.normalized();
// If n2 is the 0 vector or if the cross products are not colinear, no solution exists
if(n2.norm() < 0.00001 || abs(abs(n1.dot(n)) - n1.norm()) > 0.000001)
return std::numeric_limits<double>::infinity();;
return n1.dot(n) / n2.dot(n);
}
解释了其工作原理here。但是页面有错误,只取绝对值只有大小,抹去了方向。因此,必须取横向的点积。这样,距离可以是正数也可以是负数,具体取决于向量是否指向同一方向。
这在技术上可行,但我 运行 遇到了很大的数字错误。例如,在我的一项测试中,我得到:
The difference between i1.x() and Eigen::Vector3d(-0.581, 1.232, 0).x() is 0.0024061184231309873, which exceeds 0.001, where
i1.x() evaluates to -0.58340611842313095,
Eigen::Vector3d(-0.581, 1.232, 0).x() evaluates to -0.58099999999999996, and
0.001 evaluates to 0.001.
大于 0.001 的错误是巨大的。我该怎么做才能使该方法更准确?
这是 i1
的值:-0.583406 1.23237 0
很抱歉之前没有包含它。
您正在使用类型“double”,尝试将其更改为“long double”或“__float128”(如果它存在于您的 G++ 版本中)。此外,您可以在 Java 中使用“BigDecimal”以获得更高的准确性,或者使用 Python.
中的一些长算术
我编写了以下 LineLine 相交方法:
double LineLineIntersection(
const Eigen::Vector3d& origin1,
const Eigen::Vector3d& ray1,
const Eigen::Vector3d& origin2,
const Eigen::Vector3d& ray2)
{
if(abs((origin1 - origin2).norm() - 1.0) < 0.000001) return 0;
auto n1 = (origin2 - origin1).cross(ray2);
auto n2 = ray1.cross(ray2);
// Use this to test whether the vectors point in the same or opposite directions
auto n = n2.normalized();
// If n2 is the 0 vector or if the cross products are not colinear, no solution exists
if(n2.norm() < 0.00001 || abs(abs(n1.dot(n)) - n1.norm()) > 0.000001)
return std::numeric_limits<double>::infinity();;
return n1.dot(n) / n2.dot(n);
}
解释了其工作原理here。但是页面有错误,只取绝对值只有大小,抹去了方向。因此,必须取横向的点积。这样,距离可以是正数也可以是负数,具体取决于向量是否指向同一方向。
这在技术上可行,但我 运行 遇到了很大的数字错误。例如,在我的一项测试中,我得到:
The difference between i1.x() and Eigen::Vector3d(-0.581, 1.232, 0).x() is 0.0024061184231309873, which exceeds 0.001, where
i1.x() evaluates to -0.58340611842313095,
Eigen::Vector3d(-0.581, 1.232, 0).x() evaluates to -0.58099999999999996, and
0.001 evaluates to 0.001.
大于 0.001 的错误是巨大的。我该怎么做才能使该方法更准确?
这是 i1
的值:-0.583406 1.23237 0
很抱歉之前没有包含它。
您正在使用类型“double”,尝试将其更改为“long double”或“__float128”(如果它存在于您的 G++ 版本中)。此外,您可以在 Java 中使用“BigDecimal”以获得更高的准确性,或者使用 Python.
中的一些长算术