这是我需要的:
给定3d空间中的点(x,y,z),并由一些顶点(x,y,z)组成的网格,以计算并返回该网格上的闭合点坐标。
该功能可能是这样的:
bool closePointOnMesh(const Point& queryPoint, const Mesh& myMesh, float maxDistance);
我已经做了一些搜索,可能我会选择octree来减少计算量。
但是,仍有许多我无法理解的细节:
1:八叉树节点如何 segmentation ,因此每个节点包含的可能包含0〜一些三角形?更容易根据顶点进一步 segmentation 单元格,而直接存储顶点。
2:八叉树结构如何帮助减少计算,我知道如果单元格为空,我将不理会它。但是,是否需要获取八叉树单元格中每个三角形面内所有最接近的点到queryPoint,所以最后我得到了所有最接近的点?声音仍然沉重。除此之外,如果我遍历所有三角形,从它们中获得最接近的点,将会更容易,这意味着不需要八叉树?
3:有没有一种快速的方法来使最接近的点到三角形面内的点?
4:maxDistance限制如何帮助减少计算?
最佳答案
对于#3,下面是一些有关如何获取closest point of a triangle的代码。它将点投影到三角形的平面上,然后将重心坐标固定为[0,1],并使用这些值计算最近的点。
复制如下:
vector3 closesPointOnTriangle( const vector3 *triangle, const vector3 &sourcePosition )
{
vector3 edge0 = triangle[1] - triangle[0];
vector3 edge1 = triangle[2] - triangle[0];
vector3 v0 = triangle[0] - sourcePosition;
float a = edge0.dot( edge0 );
float b = edge0.dot( edge1 );
float c = edge1.dot( edge1 );
float d = edge0.dot( v0 );
float e = edge1.dot( v0 );
float det = a*c - b*b;
float s = b*e - c*d;
float t = b*d - a*e;
if ( s + t < det )
{
if ( s < 0.f )
{
if ( t < 0.f )
{
if ( d < 0.f )
{
s = clamp( -d/a, 0.f, 1.f );
t = 0.f;
}
else
{
s = 0.f;
t = clamp( -e/c, 0.f, 1.f );
}
}
else
{
s = 0.f;
t = clamp( -e/c, 0.f, 1.f );
}
}
else if ( t < 0.f )
{
s = clamp( -d/a, 0.f, 1.f );
t = 0.f;
}
else
{
float invDet = 1.f / det;
s *= invDet;
t *= invDet;
}
}
else
{
if ( s < 0.f )
{
float tmp0 = b+d;
float tmp1 = c+e;
if ( tmp1 > tmp0 )
{
float numer = tmp1 - tmp0;
float denom = a-2*b+c;
s = clamp( numer/denom, 0.f, 1.f );
t = 1-s;
}
else
{
t = clamp( -e/c, 0.f, 1.f );
s = 0.f;
}
}
else if ( t < 0.f )
{
if ( a+d > b+e )
{
float numer = c+e-b-d;
float denom = a-2*b+c;
s = clamp( numer/denom, 0.f, 1.f );
t = 1-s;
}
else
{
s = clamp( -e/c, 0.f, 1.f );
t = 0.f;
}
}
else
{
float numer = c+e-b-d;
float denom = a-2*b+c;
s = clamp( numer/denom, 0.f, 1.f );
t = 1.f - s;
}
}
return triangle[0] + s * edge0 + t * edge1;
}