几何计算中的bug:必须合理设置float tolerance

在基于包围盒的寻路算法中遇到角色被粘在圆形障碍物上的问题,通过调整浮点数精度误差阈值解决了计算线段与圆交点时产生的误判。

之前在项目中实现了一套基于包围盒的寻路算法,但前几天无意中发现一个bug,导致角色被粘在一个圆形上,根据检查,发现是计算线段与圆交点时出的错,计算交点的算法给出了两个点的结果,但是判断是否在线段上时,被剔除了一个点。跟进去看了一下现场的情况,发现在比较边界时,出现了一个很明显的精度误差。

float 的 349.756256 与 349.756287,相差0.000031,之前设置的 float tolerance 是 1e-05f,但是这个误差明显大于这个值,后来考虑一下,因为我们地图用的尺度非常大,所以这个误差随着数值的变大只可能越来越大(float本身的误差问题),因为我们用的尺度大概在0-1000之间,所以,考虑到浮点数本身的精度问题,浮点数在表达1000左右的数值的时候,误差大概是 (1024-512)/ 8388608 约等于 0.00006103515625,也就是说,原来的0.00001的精度误差是不足以修正错误的。因此,考虑到各种情况,将float tolerance设置到0.0001解决问题。

``` import open3d as o3d import numpy as np def slice_point_cloud(pcd, axis='x', position=0.0, tolerance=0.1): """ 点云切片函数 :param pcd: 输入点云 :param axis: 切片轴向 ('x' 或 'y') :param position: 切片位置 :param tolerance: 切片厚度半径 :return: 切片后的点云 """ points = np.asarray(pcd.points) if axis.lower() == 'x': mask = (points[:, 0] > position - tolerance) & (points[:, 0] < position + tolerance) elif axis.lower() == 'y': mask = (points[:, 1] > position - tolerance) & (points[:, 1] < position + tolerance) else: raise ValueError("无效轴向,只支持 'x' 或 'y'") sliced_pcd = o3d.geometry.PointCloud() sliced_pcd.points = o3d.utility.Vector3dVector(points[mask]) return sliced_pcd if __name__ == "__main__": # 加载两个点云文件 pcd1 = o3d.io.read_point_cloud("source.pcd") # 请替换实际文件名 pcd2 = o3d.io.read_point_cloud("target.pcd") # 请替换实际文件名 # 设置不同颜色区分点云 pcd1.paint_uniform_color([1, 0, 0]) # 红色 pcd2.paint_uniform_color([0, 1, 0]) # 绿色 while True: # 用户输入控制 axis = input("请输入切片轴向 (x/y,输入q退出): ").lower() if axis == 'q': break if axis not in ['x', 'y']: print("输入错误,请重新输入!") continue try: position = float(input("请输入切片位置: ")) except ValueError: print("请输入有效数字!") continue # 执行切片操作 tolerance = 0.1 # 可调节切片厚度 sliced1 = slice_point_cloud(pcd1, axis, position, tolerance) sliced2 = slice_point_cloud(pcd2, axis, position, tolerance) # 可视化结果 coord_frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=10) # 添加坐标系 o3d.visualization.draw_geometries([sliced1, sliced2, coord_frame])```修改一下,我需要两个切片分别显示
03-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值