Monday, May 1, 2017

What's the most efficient way to find barycentric coordinates?



In my profiler, finding barycentric coordinates is apparently somewhat of a bottleneck. I am looking to make it more efficient.


It follows the method in shirley, where you compute the area of the triangles formed by embedding the point P inside the triangle.


bary


Code:


Vector Triangle::getBarycentricCoordinatesAt( const Vector & P ) const
{
Vector bary ;

// The area of a triangle is
real areaABC = DOT( normal, CROSS( (b - a), (c - a) ) ) ;

real areaPBC = DOT( normal, CROSS( (b - P), (c - P) ) ) ;
real areaPCA = DOT( normal, CROSS( (c - P), (a - P) ) ) ;

bary.x = areaPBC / areaABC ; // alpha
bary.y = areaPCA / areaABC ; // beta
bary.z = 1.0f - bary.x - bary.y ; // gamma

return bary ;
}


This method works, but I'm looking for a more efficient one!



Answer



Transcribed from Christer Ericson's Real-Time Collision Detection (which, incidentally, is an excellent book):


// Compute barycentric coordinates (u, v, w) for
// point p with respect to triangle (a, b, c)
void Barycentric(Point p, Point a, Point b, Point c, float &u, float &v, float &w)
{
Vector v0 = b - a, v1 = c - a, v2 = p - a;
float d00 = Dot(v0, v0);
float d01 = Dot(v0, v1);

float d11 = Dot(v1, v1);
float d20 = Dot(v2, v0);
float d21 = Dot(v2, v1);
float denom = d00 * d11 - d01 * d01;
v = (d11 * d20 - d01 * d21) / denom;
w = (d00 * d21 - d01 * d20) / denom;
u = 1.0f - v - w;
}

This is effectively Cramer's rule for solving a linear system. You will not get much more efficient than this—if this is still a bottleneck (and it might be: it doesn't look like it's much different computation-wise than your current algorithm), you'll probably need to find some other place to gain a speedup.



Note that a decent number of values here are independent of p—they can be cached with the triangle if necessary.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...