创建方向包围盒(OBB)中协方差矩阵计算存在问题

xiaohango 2015-06-03 02:33:13
加精
首先是通过quickHull计算凸包,得到凸包的点集,再通过凸包的点集求协方差矩阵,公式为:

pk 、 qk 、 rk 分别是三角形的3个顶点,三角形的面积记为 Ak ,三角形的质心记为 mk。
计算协方差矩阵出现问题,导致OBB方向不对:

代码如下:
float area;
unsigned int i;
SrPoint3D p0,p1,p2, mass;

float sumArea = 0.0f;
SrPoint3D sumMass = SrPoint3D(0, 0, 0);
float cxx = 0.0f, cxy = 0.0f, cxz = 0.0f, cyy = 0.0f, cyz = 0.0f, czz = 0.0f;

for (i = 0; i < tHVex.size(); i++)
{
p0.x = tHVex.at(i).x1; p0.y = tHVex.at(i).y1; p0.z = tHVex.at(i).z1;
p1.x = tHVex.at(i).x2; p1.y = tHVex.at(i).y2; p1.z = tHVex.at(i).z2;
p2.x = tHVex.at(i).x3; p2.y = tHVex.at(i).y3; p2.z = tHVex.at(i).z3;

area = (p2 - p0).cross(p1 - p0).normalize() / 2.0f;
mass = (p0 + p1 + p2) / 3;

sumArea += area;
sumMass += area * mass;

cxx += (9.0f*mass.x*mass.x + p0.x*p0.x + p1.x*p1.x + p2.x*p2.x)*(area / 12.0f);
cxy += (9.0f*mass.x*mass.y + p0.x*p0.y + p1.x*p1.y + p2.x*p2.y)*(area / 12.0f);
cxz += (9.0f*mass.x*mass.z + p0.x*p0.z + p1.x*p1.z + p2.x*p2.z)*(area / 12.0f);
cyy += (9.0f*mass.y*mass.y + p0.y*p0.y + p1.y*p1.y + p2.y*p2.y)*(area / 12.0f);
cyz += (9.0f*mass.y*mass.z + p0.y*p0.z + p1.y*p1.z + p2.y*p2.z)*(area / 12.0f);
czz += (9.0f*mass.z*mass.z + p0.z*p0.z + p1.z*p1.z + p2.z*p2.z)*(area / 12.0f);
}

sumMass = sumMass / sumArea;
cxx /= sumArea; cxy /= sumArea; cxz /= sumArea; cyy /= sumArea; cyz /= sumArea; czz /= sumArea;

cxx -= sumMass.x*sumMass.x; cxy -= sumMass.x*sumMass.y; cxz -= sumMass.x*sumMass.z;
cyy -= sumMass.y*sumMass.y; cyz -= sumMass.y*sumMass.z; czz -= sumMass.z*sumMass.z;
...全文
2935 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
青芒Only 2017-06-27
  • 打赏
  • 举报
回复
我也是用的这套思路求obb.也是感觉求出来的obb 不对,有什么问题?
莫_问 2016-04-11
  • 打赏
  • 举报
回复
我擦,有人挖坟,我日
莫_问 2016-04-11
  • 打赏
  • 举报
回复
以前实现过。呵呵
mompidan 2016-04-03
  • 打赏
  • 举报
回复
是由于基于凸包表面积协方差求三个特征向量来定位OBB 这个算法本身的问题,它本身并不能构造紧凑的OBB。考虑案例:物体对象A及其方向包围盒B,向A中增加某些几何元素并在B的范围内进行一定扩展。利用上述两种解决方案,一般针对更新的物体对象A’将产生另一个方向包围盒B’。但一般情况下,由于两个OBB存在尺寸差异,必定有其中一个为次优。该情形可以考虑将OBB围绕最小主分量即最小特征向量进行旋转然后求解垂直于该轴的最小包围矩形来改善算法。
yaozhiyong110 2015-06-04
  • 打赏
  • 举报
回复
同意1楼 你这个计算估计float精度不够 还有你可疑调试下 看数据有没溢出什么的...
yaozhiyong110 2015-06-04
  • 打赏
  • 举报
回复
引用 4 楼 xiaohango 的回复:
[quote=引用 2 楼 yaozhiyong110 的回复:] 同意1楼 你这个计算估计float精度不够 还有你可疑调试下 看数据有没溢出什么的...
数据也没有溢出,应该就是计算的问题,或者是在计算特征向量的时候错了。[/quote] 那就只能是你代码里的算法错了...
zgl7903 2015-06-04
  • 打赏
  • 举报
回复
没详细研究过 瞎猜一下 公式里有高次幂的计算,float型的精度是否够用?先把float改为double 把数据类型限制'f'去掉,试试看
xiaohango 2015-06-04
  • 打赏
  • 举报
回复
引用 2 楼 yaozhiyong110 的回复:
同意1楼 你这个计算估计float精度不够 还有你可疑调试下 看数据有没溢出什么的...
数据也没有溢出,应该就是计算的问题,或者是在计算特征向量的时候错了。
xiaohango 2015-06-04
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
没详细研究过
瞎猜一下 公式里有高次幂的计算,float型的精度是否够用?先把float改为double 把数据类型限制'f'去掉,试试看

我都试过了,做成double类型计算协方差也存在问题。
根据凸包计算的协方差矩阵如下:

求出特征向量如下:

应该为(1,0,0)(0,1,0)(0,0,1)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧