我将计算从一个点到一个三角形的最短距离(3d)。我已将该点投影到三角形平面上,然后采用该点投影的重心坐标。但是我找不到将坐标固定在三角形内的方法。
搜索时我只找到了 0 <= [u,v,w] 和 u+v+w = 1。但是如何解决呢?
我意识到这是一个老问题,但它还没有真正得到回答,而且它目前是谷歌上“钳重心坐标”的第一个热门话题。
下面,p0
, p1
,p2
是三角形的顶点,u
, v
,w
是点 的重心坐标p = p0*u + p1*v + p2*w
。我假设u+v+w = 1
.
正如 MSN 指出的那样,三角形上最近的点取决于三角形,所以任何对u
, v
,的操作w
都不起作用。
如果所有u
, v
,w
都是正数,则该点在三角形中,无事可做。
如果其中任何一个为负数,则该点位于相应边的错误一侧。我们需要将点移动到该边上。对于相应的重心坐标,三角形边缘上的点为零。另外两个只是点从一端到另一端的距离。
if ( u < 0)
{
float t = Dot(p-p1,p2-p1)/Dot(p2-p1,p2-p1);
t = Clamp01( t );
return Vector3( 0.0f, 1.0f-t, t );
}
else if ( v < 0 )
{
float t = Dot(p-p2,p0-p2)/Dot(p0-p2,p0-p2);
t = Clamp01( t );
return Vector3( t, 0.0f, 1.0f-t );
}
else if ( w < 0 )
{
float t = Dot(p-p0,p1-p0)/Dot(p1-p0,p1-p0);
t = Clamp01( t );
return Vector3( 1.0f-t, t, 0.0f );
}
else
{
return Vector3( u, v, w );
}
Clamp01()
t
如果它介于0
和之间1
,0
如果它是负数,或者1
如果它大于,则返回1
。Dot( a, b )
是两个向量a
和的点积b
。
如果您想找到从点到三角形的最短距离,则不能以这种方式将点夹在三角形上。距离在笛卡尔空间中,而重心坐标不在。
为了确定一个点到三角形外部的三角形的距离,您需要确定该点最接近三角形的哪个特征(线段或角),然后确定到该特征的距离。以任何不考虑转换回笛卡尔空间的方式来钳制重心坐标根本行不通。
尝试钳位u
和v
到0..1
,然后设置w = 1 - u - v
以保持规范化约束。
u
,v
并且w
需要夹在 之间0..1
。就是这样。
所以例如
[u,v,w] = [-0.17, 0.64, 1.85]
在三角形上将是
[u,v,w] = [0, 0.64, 1]
万一有人想知道,我通过首先夹紧u
和v
而w = 1 - u - v
不是夹紧u
和w
而v = 1 - u - w
不是夹紧v
和w
和来解决它u = 1 - v - w
其他 2 个建议的解决方案给了我奇怪的输出,并且似乎正确地夹住了。
可能有更好/更快的方法,但现在这项工作。