lasvig
lasvig

Reputation: 191

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?

Upvotes: 7

Views: 5754

Answers (5)

DJohn
DJohn

Reputation: 111

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.

Upvotes: 11

MSN
MSN

Reputation: 54584

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.

Upvotes: 4

lasvig
lasvig

Reputation: 191

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.

Upvotes: 0

Coincoin
Coincoin

Reputation: 28596

Try clamping u and v to 0..1 and then set w = 1 - u - v to keep the normalization constraint.

Upvotes: 1

John Alexiou
John Alexiou

Reputation: 29244

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]

Upvotes: 0

Related Questions