给定空间长方体的八个顶点坐标,求取长宽高对应向量的方法。
背景
最近有一个需求,给定OBB(Orient Bounding Box,最小包围盒)的八个顶点后,这八个顶点是无序的,我们要找出其长,宽,高对应的向量。
算法描述
首先,定义: 长为长方体的最长边,宽高为较短的两条边。
算法描述
随便选取八个顶点中的一个,在本算法,初始顶点的选取并没有什么限制,为了下面表示方便,我们直接选取V7。
令V7 与其他七个顶点Vj (j∈[0,6])分别相差,得到向量 Dj(j∈[0,6]);
对D按照向量模进行升序排序,得到N,**N0**模最小,**N6**模最大。
那么模最小的两个向量N0,N1,这两个向量对应的就是长方体的宽和高。
设L=N0-N1 (向量减法),比较L和N2的模,若|N2<|L|(或者差异较大),那么D2 即为长方体的长,若|N2|=|L|或者是二者非常接近,那么我们认为D2 和L相等,那么**D3**就是长方体的长
算法实现
bool compareNorm(Eigen::Vector3d i,Eigen::Vector3d j)
{
return i.norm() < j.norm();
}
class cuboid
{
private Eigen::Vector3d length;
private Eigen::Vector3d height;
private Eigen::Vector3d width;
void computeNormals(std::vector<Eigen::Vector3d>& vertices)//八个顶点
{
assert(vertices.size() == 8);
std::vector<Eigen::Vector3d> N;
for (int i = 0; i < 7; i++)
{
N.push_back(vertices[i] - vertices[7]);
}
std::sort(tris.begin(), tris.end(), compareNorm);//对这些向量按照模进行升序排序
width = N[0]; //最短的那两个向量肯定一个是宽,一个是高
height = N[1];
//面对角线
Eigen::Vector3d L = width-height;
//这边判断第三短的向量到底是面对角线还是长,
//如果面对角线比第三短的向量长,那么第三短的向量就是 长,如果没有的话 第四短才是 长
length = L.norm() - tris[2].norm() > 0.01 ? tris[2] : tris[3];
}
}