我已经设法以两种方式计算了边界球半径,但没有一种能够正确地给出我想要的东西。我不需要一个“像素”完美的边界球,但我想要比现在更好的东西。
我正在使用Wavefront .obj模型并计算这些模型的边界球半径我提取当前模型尺寸(我使用的是Nate Robbins的GLM库),这将给出每个轴上的尺寸。 / p>
第一种方法: 将每个轴除以2,这将给出每个轴的半径。最大的是我将用于我的边界球体的那个。这适用于特定于我的项目的大多数对象。对于像立方体形状的一些,它不适用。基本上,如果我有一个立方体并用这种方法计算半径,球体将使立方角落在外面。
第二种方法: 将每个轴除以2,这将给出每个轴的半径。然后我这样做取出边界球的半径:
r = SQRT(x*x + y*y + z*z)
但这给了我一个相当大的半径。物体将完全封闭在球体中,但是球体非常大,比它应该更大。
我不明白我在上面的公式中做错了什么,据我所知,它应该有效。但我显然错了......
答案 0 :(得分:4)
你的第二种方法应该为你的边界框提供边界球,但是正如你所发现的那样,它会比一个盒子以外的任何东西都大。
可以通过平移模型点找到更好的边界球,使它们使用您已有的边界框尺寸居中于原点,然后对于每个单独的顶点计算原点的半径对于那一点使用sqrt(x*x + y*y + z*z)
公式。无论哪个是最大的是你的边界球的半径。
请注意,这不是最佳边界球。为此,您必须找到模型的凸包,并使用旋转卡尺之类的东西来选择球体的最佳中心点。
要在2D中显示,红色轮廓是形状的边界框,蓝色圆圈是框的边界圆。使用多边形顶点并以框为中心的改进圆是绿色。请注意,黑色多边形的任何一点都不会触及蓝色圆圈。
答案 1 :(得分:1)
一种简单的方法是使用Miniball来计算模型的精确边界球。将它集成到您的项目中是无忧无虑的,因为它只包含一个标题。然而,它是根据GPL许可的,这可能是一个问题。例如:
#include "Miniball.h"
// ...
Miniball<3> boundingSphere;
// Iterate over all vertices in the model
for (int vertexId = 0; vertexId < model.getNumVertices(); ++vertexId) {
// Convert vertex position to Miniball point type
Point<3> point;
for (int dim = 0; dim < 3; ++dim) {
point[dim] = model.getVertex(vertexId)[dim];
}
// Add point to bounding sphere
boundingSphere.check_in(point);
}
// Actually calculate the sphere
boundingSphere.build();
// Get back the results
Point<3> center = boundingSphere.center();
double radiusSq = boundingSphere.squared_radius();
答案 2 :(得分:0)
如果它是一个球体,那么你不需要根据一个轴进行计算吗?我可能会离开这里 - 但根据定义,球体的宽度,高度和深度是否相同?那么一个轴上的半径=另一个轴上的半径=另一个轴的半径?