diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_geom.c')
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 113 |
1 files changed, 104 insertions, 9 deletions
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 8f7ecdcfde8..173c6d06861 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -106,12 +106,12 @@ float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], cons sub_v3_v3v3(vec1, v2, v1); sub_v3_v3v3(vec2, v4, v1); cross_v3_v3v3(n, vec1, vec2); - len = normalize_v3(n); + len = len_v3(n); sub_v3_v3v3(vec1, v4, v3); sub_v3_v3v3(vec2, v2, v3); cross_v3_v3v3(n, vec1, vec2); - len += normalize_v3(n); + len += len_v3(n); return (len / 2.0f); } @@ -119,14 +119,13 @@ float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], cons /* Triangles */ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]) { - float len, vec1[3], vec2[3], n[3]; + float vec1[3], vec2[3], n[3]; sub_v3_v3v3(vec1, v3, v2); sub_v3_v3v3(vec2, v1, v2); cross_v3_v3v3(n, vec1, vec2); - len = normalize_v3(n); - return (len / 2.0f); + return len_v3(n) / 2.0f; } float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]) @@ -729,6 +728,86 @@ static short IsectLLPt2Df(const float x0, const float y0, const float x1, const return 1; } +/* point in polygon (keep float and int versions in sync) */ +bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr) +{ + /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */ + float angletot = 0.0; + float fp1[2], fp2[2]; + int i; + const float *p1, *p2; + + p1 = verts[nr - 1]; + p2 = verts[0]; + + /* first vector */ + fp1[0] = (float)(p1[0] - pt[0]); + fp1[1] = (float)(p1[1] - pt[1]); + normalize_v2(fp1); + + for (i = 0; i < nr; i++) { + float dot, ang, cross; + /* second vector */ + fp2[0] = (float)(p2[0] - pt[0]); + fp2[1] = (float)(p2[1] - pt[1]); + normalize_v2(fp2); + + /* dot and angle and cross */ + dot = dot_v2v2(fp1, fp2); + ang = fabsf(saacos(dot)); + cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1])); + + if (cross < 0.0f) angletot -= ang; + else angletot += ang; + + /* circulate */ + copy_v2_v2(fp1, fp2); + p1 = p2; + p2 = verts[i + 1]; + } + + return (fabsf(angletot) > 4.0f); +} +bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const int nr) +{ + /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */ + float angletot = 0.0; + float fp1[2], fp2[2]; + int i; + const int *p1, *p2; + + p1 = verts[nr - 1]; + p2 = verts[0]; + + /* first vector */ + fp1[0] = (float)(p1[0] - pt[0]); + fp1[1] = (float)(p1[1] - pt[1]); + normalize_v2(fp1); + + for (i = 0; i < nr; i++) { + float dot, ang, cross; + /* second vector */ + fp2[0] = (float)(p2[0] - pt[0]); + fp2[1] = (float)(p2[1] - pt[1]); + normalize_v2(fp2); + + /* dot and angle and cross */ + dot = dot_v2v2(fp1, fp2); + ang = fabsf(saacos(dot)); + cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1])); + + if (cross < 0.0f) angletot -= ang; + else angletot += ang; + + /* circulate */ + copy_v2_v2(fp1, fp2); + p1 = p2; + p2 = verts[i + 1]; + } + + return (fabsf(angletot) > 4.0f); +} + /* point in tri */ /* only single direction */ @@ -2219,6 +2298,13 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo len_v2(dirs[3]), }; + /* variable 'area' is just for storage, + * the order its initialized doesn't matter */ +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunsequenced" +#endif + /* inline mean_value_half_tan four times here */ float t[4] = { MEAN_VALUE_HALF_TAN_V2(area, 0, 1), @@ -2227,6 +2313,10 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo MEAN_VALUE_HALF_TAN_V2(area, 3, 0), }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + #undef MEAN_VALUE_HALF_TAN_V2 w[0] = (t[3] + t[0]) / lens[0]; @@ -2564,7 +2654,9 @@ void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const r_uv[0] = (float)((d * x[0] - b * x[1]) / det); r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det); } - else zero_v2(r_uv); + else { + zero_v2(r_uv); + } } /* bilinear reverse */ @@ -3063,7 +3155,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl add_v3_v3(accu_com, v); accu_weight += weight[a]; } - else add_v3_v3(accu_com, pos[a]); + else { + add_v3_v3(accu_com, pos[a]); + } if (rweight) { float v[3]; @@ -3072,8 +3166,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl add_v3_v3(accu_rcom, v); accu_rweight += rweight[a]; } - else add_v3_v3(accu_rcom, rpos[a]); - + else { + add_v3_v3(accu_rcom, rpos[a]); + } } if (!weight || !rweight) { accu_weight = accu_rweight = list_size; |