Math Lib: add angle_on_axis_v3v3_v3
authorCampbell Barton <ideasman42@gmail.com>
Thu, 15 Jun 2017 15:25:08 +0000 (01:25 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 15 Jun 2017 15:27:58 +0000 (01:27 +1000)
Use for calculating the angle between 2 directions on an axis.

Also signed version and normalized plane projection,
use when input is normalized.

source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/math_geom.c
source/blender/blenlib/intern/math_vector.c
source/blender/bmesh/operators/bmo_connect_pair.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/transform/transform.c

index 8e0884ba34794c469327342c1a2067e38a3f84c4..43f414f376a3b546ca18ec7a3b4ae51f6ee2e610 100644 (file)
@@ -286,6 +286,8 @@ float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT;
 float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT;
 float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) ATTR_WARN_UNUSED_RESULT;
 float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT;
+float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
+float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
 float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT;
 float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
 float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
@@ -299,6 +301,8 @@ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]);
 void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]);
 void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]);
 void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2]);
+void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]);
+void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2]);
 void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]);
 void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3]);
 void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]);
index 58699a0593b632c631322a7569a7ec5478eb5491..e28f4902c140ec726a27f894c21774ebf93b46d9 100644 (file)
@@ -1828,7 +1828,7 @@ bool isect_tri_tri_epsilon_v3(
                     (range[0].max < range[1].min)) == 0)
                {
                        if (r_i1 && r_i2) {
-                               project_plane_v3_v3v3(plane_co, plane_co, plane_no);
+                               project_plane_normalized_v3_v3v3(plane_co, plane_co, plane_no);
                                madd_v3_v3v3fl(r_i1, plane_co, plane_no, max_ff(range[0].min, range[1].min));
                                madd_v3_v3v3fl(r_i2, plane_co, plane_no, min_ff(range[0].max, range[1].max));
                        }
index 37897e2cd32ac63c8851539c434d95a1629b0159..c6e9b8229ba3fc8b0fe172ab75c06198fb4c57ac 100644 (file)
@@ -518,38 +518,27 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2])
 }
 
 /**
- * angle between 2 vectors defined by 3 coords, about an axis. */
-float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+ * Angle between 2 vectors, about an axis (axis can be considered a plane).
+ */
+float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
 {
-       float v1_proj[3], v2_proj[3], tproj[3];
-
-       sub_v3_v3v3(v1_proj, v1, v2);
-       sub_v3_v3v3(v2_proj, v3, v2);
+       float v1_proj[3], v2_proj[3];
 
        /* project the vectors onto the axis */
-       project_v3_v3v3(tproj, v1_proj, axis);
-       sub_v3_v3(v1_proj, tproj);
-
-       project_v3_v3v3(tproj, v2_proj, axis);
-       sub_v3_v3(v2_proj, tproj);
+       project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+       project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
 
        return angle_v3v3(v1_proj, v2_proj);
 }
 
-float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
 {
        float v1_proj[3], v2_proj[3], tproj[3];
        float angle;
 
-       sub_v3_v3v3(v1_proj, v1, v2);
-       sub_v3_v3v3(v2_proj, v3, v2);
-
        /* project the vectors onto the axis */
-       project_v3_v3v3(tproj, v1_proj, axis);
-       sub_v3_v3(v1_proj, tproj);
-
-       project_v3_v3v3(tproj, v2_proj, axis);
-       sub_v3_v3(v2_proj, tproj);
+       project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+       project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
 
        angle = angle_v3v3(v1_proj, v2_proj);
 
@@ -562,6 +551,29 @@ float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const
        return angle;
 }
 
+/**
+ * Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane).
+ */
+float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+{
+       float vec1[3], vec2[3];
+
+       sub_v3_v3v3(vec1, v1, v2);
+       sub_v3_v3v3(vec2, v3, v2);
+
+       return angle_on_axis_v3v3_v3(vec1, vec2, axis);
+}
+
+float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+{
+       float vec1[3], vec2[3];
+
+       sub_v3_v3v3(vec1, v1, v2);
+       sub_v3_v3v3(vec2, v3, v2);
+
+       return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis);
+}
+
 void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3])
 {
        float ed1[3], ed2[3], ed3[3];
@@ -669,6 +681,25 @@ void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2
        out[1] = p[1] - (mul * v_plane[1]);
 }
 
+void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
+{
+       BLI_ASSERT_UNIT_V3(v_plane);
+       const float mul = dot_v3v3(p, v_plane);
+
+       out[0] = p[0] - (mul * v_plane[0]);
+       out[1] = p[1] - (mul * v_plane[1]);
+       out[2] = p[2] - (mul * v_plane[2]);
+}
+
+void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2])
+{
+       BLI_ASSERT_UNIT_V2(v_plane);
+       const float mul = dot_v2v2(p, v_plane);
+
+       out[0] = p[0] - (mul * v_plane[0]);
+       out[1] = p[1] - (mul * v_plane[1]);
+}
+
 /* project a vector on a plane defined by normal and a plane point p */
 void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
 {
index a73c86fd122a1b20c0098932050e954b6e56c351..b474ad9fc7bab1b98a2597635c148af8d583a7e0 100644 (file)
@@ -530,8 +530,8 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
                float basis_nor_b[3];
 
                /* align normal to direction */
-               project_plane_v3_v3v3(basis_nor_a, v_pair[0]->no, basis_dir);
-               project_plane_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir);
+               project_plane_normalized_v3_v3v3(basis_nor_a, v_pair[0]->no, basis_dir);
+               project_plane_normalized_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir);
 
                /* don't normalize before combining so as normals approach the direction, they have less effect (T46784). */
 
@@ -569,7 +569,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
                                float angle_cos_test;
 
                                /* project basis dir onto the normal to find its closest angle */
-                               project_plane_v3_v3v3(basis_dir_proj, basis_dir, l->f->no);
+                               project_plane_normalized_v3_v3v3(basis_dir_proj, basis_dir, l->f->no);
 
                                if (normalize_v3(basis_dir_proj) > eps) {
                                        angle_cos_test = dot_v3v3(basis_dir_proj, basis_dir);
@@ -586,7 +586,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
                 * note: we could add the directions,
                 * but this more often gives 45d rotated matrix, so just use the best one. */
                copy_v3_v3(basis_nor, axis_pair[axis_pair[0].angle_cos < axis_pair[1].angle_cos].nor);
-               project_plane_v3_v3v3(basis_nor, basis_nor, basis_dir);
+               project_plane_normalized_v3_v3v3(basis_nor, basis_nor, basis_dir);
 
                cross_v3_v3v3(basis_tmp, basis_dir, basis_nor);
 
index bf59693b85655fbaf4d08efd1418d9378f8645bf..5e44509e10a6f9fd36ab8e9bb01cadf16b3d47f2 100644 (file)
@@ -1472,7 +1472,7 @@ static void clip_to_ortho_planes(float v1[3], float v2[3], const float center[3]
 
        /* could be v1 or v2 */
        sub_v3_v3(v1, center);
-       project_plane_v3_v3v3(closest, v1, dir);
+       project_plane_normalized_v3_v3v3(closest, v1, dir);
        add_v3_v3(closest, center);
 
        madd_v3_v3v3fl(v1, closest, dir,  d);
index bf3daf6cffbf925d8023fc869b29b4d6619847c9..4686ff0523eb412482930b3c158379181d40b794 100644 (file)
@@ -5559,7 +5559,7 @@ static void slide_origdata_interp_data_vert(
        float v_proj[3][3];
 
        if (do_loop_weight || do_loop_mdisps) {
-               project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
+               project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
        }
 
        // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
@@ -5593,19 +5593,19 @@ static void slide_origdata_interp_data_vert(
                        /* In the unlikely case that we're next to a zero length edge - walk around the to the next.
                         * Since we only need to check if the vertex is in this corner,
                         * its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */
-                       project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+                       project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
                        while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
                                        ((l_prev = l_prev->prev) != l->next)))
                        {
                                co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
-                               project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+                               project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
                        }
-                       project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+                       project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
                        while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
                                        ((l_next = l_next->next) != l->prev)))
                        {
                                co_next = slide_origdata_orig_vert_co(sod, l_next->v);
-                               project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+                               project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
                        }
 
                        if (co_prev_ok && co_next_ok) {