From 73c2abe83d4e9636c4d00dc714dcba88374d9e34 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Jul 2012 09:19:05 +0000 Subject: new function barycentric_weights_v2_quad(), like barycentric_weights_v2 but for quads. takes vecs and a point and assigns 4 weights, needed for nice quad interpolation for mask feathering. --- source/blender/blenlib/BLI_math_geom.h | 2 ++ source/blender/blenlib/intern/math_geom.c | 40 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 8ccc3159f78..50345237a9f 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -200,6 +200,8 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3], void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2], + const float co[2], float w[4]); int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); int barycentric_inside_triangle_v2(const float w[3]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index a7ffb95172e..f9acb6ae1dd 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1942,6 +1942,46 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3 } } +/* same as #barycentric_weights_v2 but works with a quad, + * note: untested for values outside the quad's bounds. + * note: there may be a more efficient method to do this, just figured it out - campbell */ +void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2], + const float co[2], float w[4]) +{ + float wtot; + + const float areas_co[4] = { + area_tri_signed_v2(v1, v2, co), + area_tri_signed_v2(v2, v3, co), + area_tri_signed_v2(v3, v4, co), + area_tri_signed_v2(v4, v1, co), + }; + + const float areas_diag[4] = { + area_tri_signed_v2(v4, v1, v2), + area_tri_signed_v2(v1, v2, v3), + area_tri_signed_v2(v2, v3, v4), + area_tri_signed_v2(v3, v4, v1), + }; + + const float u = areas_co[3] / (areas_co[1] + areas_co[3]); + const float v = areas_co[0] / (areas_co[0] + areas_co[2]); + + w[0] = ((1.0f - u) * (1.0f - v)) * sqrtf(areas_diag[0] / areas_diag[2]); + w[1] = (( u) * (1.0f - v)) * sqrtf(areas_diag[1] / areas_diag[3]); + w[2] = (( u) * ( v)) * sqrtf(areas_diag[2] / areas_diag[0]); + w[3] = ((1.0f - u) * ( v)) * sqrtf(areas_diag[3] / areas_diag[1]); + + wtot = w[0] + w[1] + w[2] + w[3]; + + if (wtot != 0.0f) { + mul_v4_fl(w, 1.0f / wtot); + } + else { /* dummy values for zero area face */ + copy_v4_fl(w, 1.0f / 4.0f); + } +} + /* given 2 triangles in 3D space, and a point in relation to the first triangle. * calculate the location of a point in relation to the second triangle. * Useful for finding relative positions with geometry */ -- cgit v1.2.3