有没有快速的方法来做这件事?在网上搜索显示函数或单个多边形的凸性。但我需要检查整个模型的凸性。一个物体可以有凸面,但整体上可能是凹的,比如一个环面。
有没有快速的方法来做这件事?在网上搜索显示函数或单个多边形的凸性。但我需要检查整个模型的凸性。一个物体可以有凸面,但整体上可能是凹的,比如一个环面。
Kneejerk: 如果您构建了一个多叶BSP树,并且最终将所有几何图形都放在一个节点中,则该对象是凸的。
更明智的方法:对于每个多边形,请获取超平面。确保模型中的每个顶点都在该超平面后面。
等效地:检查每对顶点之间的线段;如果它不与任何面相交,则该对象是凸的。
我想您也可以通过quickhull或其他方式获得凸包,并将其与原始对象进行比较。或者,类似地,获取凸包并检查原始对象的每个顶点是否位于凸包的面上。
bool IsConvex(std::vector<vec3> &points, std::vector<int> &triangles, float threshold = 0.001)
{
for (unsigned long i = 0; i < triangles.size() / 3; i++)
{
vec3 Atmp = points[triangles[i * 3 + 0]];
vec3 Btmp = points[triangles[i * 3 + 1]];
vec3 Ctmp = points[triangles[i * 3 + 2]];
btVector3 A(Atmp.x, Atmp.y, Atmp.z);
btVector3 B(Btmp.x, Btmp.y, Btmp.z);
btVector3 C(Ctmp.x, Ctmp.y, Ctmp.z);
B -= A;
C -= A;
btVector3 BCNorm = B.cross(C).normalized();
float checkPoint = btVector3(points[0].x - A.x(), points[0].y - A.y(), points[0].z - A.z()).dot(BCNorm);
for (unsigned long j = 0; j < points.size(); j++)
{
float dist = btVector3(points[j].x - A.x(), points[j].y - A.y(), points[j].z - A.z()).dot(BCNorm);
if((std::abs(checkPoint) > threshold) && (std::abs(dist) > threshold) && (checkPoint * dist < 0))
{
return false;
}
}
}
return true;
}
O(F.V)
,其中 F
表示面数,V
表示顶点数。O(V.Log(V))
。如果在算法的任何阶段丢弃一个顶点,则多面体不是凸的。你可以先将所有顶点添加到树结构中,以加速平面-顶点测试,这样如果整个叶子的边界框与平面不相交,则可以拒绝整个叶子。
BSP 的想法实际上应该与测试所有三角形平面相同,因为对于凸对象,没有 BSP 叶子能够细分顶点集。
你可能需要为你的平面测试包含一个 epsilon,因为浮点精度和手动创建网格的建模精度都可能导致顶点略微高于平面。