重心坐标夹紧 3D 三角形

barycentric coordinate clamping on 3d triangle

本文关键字:三角形 3D 重心坐标      更新时间:2023-10-16

我将计算从点到三角形(3d)的最短距离。我已经将点投影到三角形的平面上,然后取了点投影的重心坐标。但是我找不到一种方法来夹住坐标以始终在三角形内。

搜索时,我只找到了 0 <= [u,v,w] 和 you+v+w = 1。 但是这将如何解决呢?

我意识到这是一个古老的问题,但它还没有真正得到答案,它目前是谷歌上"钳重心坐标"的第一个命中。

在下文中,p0p1p2是三角形的顶点,u v w是点p = p0*u + p1*v + p2*w的重心坐标。 我假设u+v+w = 1.

正如MSN所指出的,三角形上最近的点取决于三角形,因此仅对uvw的任何操作都不起作用。

如果uvw都是正的,那么点就在三角形中,没有什么可做的。

如果其中任何一个是负数,则该点位于相应边的错误一侧。 我们需要将点移到该边缘。 三角形边缘上的点对于相应的重心坐标为零。 另外两个只是点从一端到另一端的距离。

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()介于 01 之间,则返回 t,如果它为负数,则返回0,如果它大于 1 则返回 1 个。 Dot( a, b ) 是两个向量 ab 的点积。

如果要

查找从点到三角形的最短距离,则不能以这种方式将点固定到三角形。距离在笛卡尔空间中,而重心坐标则不在。

为了确定点到三角形外三角形

的距离,您需要确定该点最接近三角形的哪个要素(线段或角),然后确定到该要素的距离。以任何不考虑转换回笛卡尔空间的方式夹紧重心坐标都是行不通的。

尝试将uv固定到0..1,然后设置w = 1 - u - v以保留规范化约束。

uvw需要夹在0..1之间。就是这样。

所以例如

[u,v,w] = [-0.17, 0.64, 1.85]

在三角形上将是

[u,v,w] = [0, 0.64, 1]

如果有人想知道,我先解决了夹紧uvw = 1 - u - v比夹紧uwv = 1 - u - w比夹紧vwu = 1 - v - w

其他 2 个建议的解决方案给了我奇怪的输出,并且 dident 似乎可以正确夹紧。

可能有更好/更快的方法来做到这一点,但现在这项工作。