简体   繁体   中英

barycentric coordinate clamping on 3d triangle

I am going to calculate the shortest distance from a point to a triangle(3d). I have projected the point to the plane of the triangle and than taken the barycentric coordinates of the projection of the point. But i could not find a way to clamp the coordinates to always be inside the triangle.

when searching I've only found the 0 <= [u,v,w] and u+v+w = 1. but how would this be solved?

I realise this is an old question, but it hasn't really been answered yet, and it's currently the first hit on Google for "clamp barycentric coordinates".

In the following, p0 , p1 , p2 are the vertices of the triangle and u , v , w are the barycentric coordinates of the point p = p0*u + p1*v + p2*w . I'm assuming that u+v+w = 1 .

As MSN points out, the nearest point on the triangle depends on the triangle, so any operation on just u , v , w can't work.

If all of u , v , w are positive, then the point is in the triangle and there is nothing to do.

If any of them are negative, then the point is on the wrong side of the corresponding edge. We need to move the point onto that edge. Points on the edge of a triangle have zero for the corresponding barycentric coordinate. The other two are simply how far the point is from one end to the other.

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() returns t if it is between 0 and 1 , 0 if it is negative, or 1 if it is greater than 1 . Dot( a, b ) is the dot product of two vectors a and b .

You can't clamp a point to a triangle that way if you want to find the shortest distance from a point to a triangle. Distance is in Cartesian space, whereas barycentric coordinates are not.

In order to determine the distance of a point to a triangle that is outside the triangle, you need to determine which feature of the triangle the point is closest to (line segment, or corner), then the distance to that feature. Clamping barycentric coordinates in any way that does not take into account the transformation back to Cartesian space will simply not work.

u , v and w need to be clamped between 0..1 . That's it.

So for example

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

on the triangle would be

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

尝试将uv钳位到0..1 ,然后设置w = 1 - u - v以保持归一化约束。

In case anyone want to know, I solved it by first clamping u and v and w = 1 - u - v than clamping u and w and v = 1 - u - w than clamping v and w and u = 1 - v - w

the other 2 suggested solutions gave me weird outputs and dident seem to clamp correctly.

there is probably better/faster ways of doing it but for now this work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM