Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-07-13 13:19:05 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-07-13 13:19:05 +0400
commit73c2abe83d4e9636c4d00dc714dcba88374d9e34 (patch)
treea91fdd6052a966be35974017a6f28ad4e84a8b01
parent6ee2e0b145bdd4e936f58a05ac24d90533824e77 (diff)
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.
-rw-r--r--source/blender/blenlib/BLI_math_geom.h2
-rw-r--r--source/blender/blenlib/intern/math_geom.c40
2 files changed, 42 insertions, 0 deletions
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 */