检查共面三维点时出现浮点错误
Floating-point error when checking for coplanar 3D points
我正在寻找一种算法来检查一个点是否与由三个顶点定义的给定三维平面共面,同时最大限度地减少浮点误差。
我想尽量减少乘法和除法的数量,以减少浮点错误。
我的实现使用float
s,我不能使用double
。
我不能使用外部图书馆。
我当前的方法存在以下错误:
我有使用平面方程的一般形式定义平面的代码:
ax + by + cz + d = 0
我使用三个3D顶点v0
、v1
和v2
计算这些系数,如下所示:
// Pseudo-code to define a plane (with class Vector3 defining a vector in 3D)
Vector3 A = v1 - v0;
Vector3 B = v2 - v0;
Vector3 N = cross_product(A,B); // Normal vector
N.Normalize(); // Unit normal vector storing coefs. a, b, c
float d = dot_product(N,v0);
为了检查另一个顶点p
是否共面,我将该点插入平面方程,并检查结果是否为0
:
// Pseudo-code for coplanar test:
bool is_coplanar()
{
float res = N.x()*p.x() + N.y()*p.y() + N.z()*p.z() - d;
return true if res is "almost" null; // "almost" is: abs(res)<EPSILON
}
在这种情况下,我的代码失败:
v0 = [-8.50001907, 0, 323]
v1 = [8.49998093, 0, 323]
v2 = [-8.50001907, 1.49999976, 322.598083]
则平面系数为:
N = [-0, 0.258814692, 0.965926945]
d = 311.994415
当我插入点v2
时,我发现与0
"相距甚远"的结果(尽管v2
用于定义平面):
res = -3.05175781e-05
我的EPSILON
当前为1e-5
。
在编译器qcc 4.4.2(QNX Momentics,类似于gcc)上进行了测试。无优化-O0
。
这样的几何谓词在很多方面都会受到浮点错误的影响。唯一的工业强度解决方案是使用自适应算术滤波(前提是coplanar
测试的稳健实现不适用于您)。
幸运的是,这样的实现(需要相当长的时间来编写)已经可用。在上一个链接中,oriental3d谓词可以满足您的需要:给定3个平面形成点,决定第四个点是位于平面上方、下方还是在平面上
如果这样的实现过于夸张,请检查简单的实现。它总共提供4个:
orienta3dfast()近似三维定向测试。不稳健
orienta3dexact()精确的三维方位测试。稳健
orienta3dslow()另一个精确的三维定向测试。稳健
orient3d()自适应精确三维定向测试。强健的
免责声明:代码列表是作为实现稳健解决方案所需的数学概念和编程技术的教程提供的。我既不建议也不暗示复制粘贴任何东西。
相关文章:
- 如何将三维尺寸不固定的三维阵列展平为一维阵列
- 如何使用qt缩放三维网格
- 三维数组中的C/C++DWORD到BYTE和BYTE到DWORD的转换
- 使用vtkImageReslice重新切片三维原始图像
- 特征:创建一个具有函数的三维阵列
- 扩充矩阵的行缩减-三维样条曲线计算
- 使用pcl transformcloud将三维点平移并旋转到原点
- 用C++从三维矢量中删除元素
- 如何访问CGAL三维三角测量中的面
- 如何在Openscenegraph中从二维鼠标点击的屏幕坐标点计算三维点(世界坐标)
- std::将三维数组复制到三维向量中
- 显示结构的三维数组
- 如何将X 2维数组连接到一个三维阵列中
- 使用unique_ptr来管理三维数组
- 如何访问三维矩阵元素
- 无法访问三维数组中的特定位置
- 如何将 HDC 位图快速复制到三维阵列?
- 内存相关崩溃:Cocos2d游戏中的三维数组
- 检查共面三维点时出现浮点错误
- 删除三维数组时出现0xfeeefee2错误