Python API: add Vector.orthogonal() method
This commit is contained in:
		@@ -800,6 +800,36 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
 | 
				
			|||||||
	return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
 | 
						return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyDoc_STRVAR(Vector_orthogonal_doc,
 | 
				
			||||||
 | 
					".. method:: orthogonal()\n"
 | 
				
			||||||
 | 
					"\n"
 | 
				
			||||||
 | 
					"   Return a perpendicular vector.\n"
 | 
				
			||||||
 | 
					"\n"
 | 
				
			||||||
 | 
					"   :return: a new vector 90 degrees from this vector.\n"
 | 
				
			||||||
 | 
					"   :rtype: :class:`Vector`\n"
 | 
				
			||||||
 | 
					"\n"
 | 
				
			||||||
 | 
					"   .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n"
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					static PyObject *Vector_orthogonal(VectorObject *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						float vec[3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (self->size != 3) {
 | 
				
			||||||
 | 
							PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
 | 
							                "Vector.orthogonal(): "
 | 
				
			||||||
 | 
							                "Vector must be 3D");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (BaseMath_ReadCallback(self) == -1)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ortho_v3_v3(vec, self->vec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Vector_CreatePyObject(vec, self->size, Py_NEW, Py_TYPE(self));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Vector.reflect(mirror): return a reflected vector on the mirror normal
 | 
					 * Vector.reflect(mirror): return a reflected vector on the mirror normal
 | 
				
			||||||
 *  vec - ((2 * DotVecs(vec, mirror)) * mirror)
 | 
					 *  vec - ((2 * DotVecs(vec, mirror)) * mirror)
 | 
				
			||||||
@@ -2768,6 +2798,7 @@ static struct PyMethodDef Vector_methods[] = {
 | 
				
			|||||||
	{"resize_4d", (PyCFunction) Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
 | 
						{"resize_4d", (PyCFunction) Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
 | 
				
			||||||
	{"to_tuple", (PyCFunction) Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
 | 
						{"to_tuple", (PyCFunction) Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
 | 
				
			||||||
	{"to_track_quat", (PyCFunction) Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc},
 | 
						{"to_track_quat", (PyCFunction) Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc},
 | 
				
			||||||
 | 
						{"orthogonal", (PyCFunction) Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* operation between 2 or more types  */
 | 
						/* operation between 2 or more types  */
 | 
				
			||||||
	{"reflect", (PyCFunction) Vector_reflect, METH_O, Vector_reflect_doc},
 | 
						{"reflect", (PyCFunction) Vector_reflect, METH_O, Vector_reflect_doc},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,32 @@ import unittest
 | 
				
			|||||||
from test import support
 | 
					from test import support
 | 
				
			||||||
from mathutils import Matrix, Vector
 | 
					from mathutils import Matrix, Vector
 | 
				
			||||||
from mathutils import kdtree
 | 
					from mathutils import kdtree
 | 
				
			||||||
 | 
					import math
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# keep globals immutable
 | 
				
			||||||
 | 
					vector_data = (
 | 
				
			||||||
 | 
					    (1.0, 0.0, 0.0),
 | 
				
			||||||
 | 
					    (0.0, 1.0, 0.0),
 | 
				
			||||||
 | 
					    (0.0, 0.0, 1.0),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (1.0, 1.0, 1.0),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (0.33783, 0.715698, -0.611206),
 | 
				
			||||||
 | 
					    (-0.944031, -0.326599, -0.045624),
 | 
				
			||||||
 | 
					    (-0.101074, -0.416443, -0.903503),
 | 
				
			||||||
 | 
					    (0.799286, 0.49411, -0.341949),
 | 
				
			||||||
 | 
					    (-0.854645, 0.518036, 0.033936),
 | 
				
			||||||
 | 
					    (0.42514, -0.437866, -0.792114),
 | 
				
			||||||
 | 
					    (-0.358948, 0.597046, 0.717377),
 | 
				
			||||||
 | 
					    (-0.985413,0.144714, 0.089294),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# get data at different scales
 | 
				
			||||||
 | 
					vector_data = sum(
 | 
				
			||||||
 | 
					    (tuple(tuple(a * scale for a in v) for v in vector_data)
 | 
				
			||||||
 | 
					    for scale in (s * sign for s in (0.0001, 0.1, -1.0, 10.0, 1000.0, 100000.0)
 | 
				
			||||||
 | 
					                           for sign in (1.0, -1.0))), ()) + ((0.0, 0.0, 0.0),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MatrixTesting(unittest.TestCase):
 | 
					class MatrixTesting(unittest.TestCase):
 | 
				
			||||||
    def test_matrix_column_access(self):
 | 
					    def test_matrix_column_access(self):
 | 
				
			||||||
@@ -149,6 +175,17 @@ class MatrixTesting(unittest.TestCase):
 | 
				
			|||||||
        self.assertEqual(mat * mat, prod_mat)
 | 
					        self.assertEqual(mat * mat, prod_mat)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VectorTesting(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_orthogonal(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        angle_90d = math.pi / 2.0
 | 
				
			||||||
 | 
					        for v in vector_data:
 | 
				
			||||||
 | 
					            v = Vector(v)
 | 
				
			||||||
 | 
					            if v.length_squared != 0.0:
 | 
				
			||||||
 | 
					                self.assertAlmostEqual(v.angle(v.orthogonal()), angle_90d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class KDTreeTesting(unittest.TestCase):
 | 
					class KDTreeTesting(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
@@ -256,6 +293,7 @@ class KDTreeTesting(unittest.TestCase):
 | 
				
			|||||||
def test_main():
 | 
					def test_main():
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        support.run_unittest(MatrixTesting)
 | 
					        support.run_unittest(MatrixTesting)
 | 
				
			||||||
 | 
					        support.run_unittest(VectorTesting)
 | 
				
			||||||
        support.run_unittest(KDTreeTesting)
 | 
					        support.run_unittest(KDTreeTesting)
 | 
				
			||||||
    except:
 | 
					    except:
 | 
				
			||||||
        import traceback
 | 
					        import traceback
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user