'How would I get the angle between 2 3D vectors A & B on the plane normal to a 3rd vector C (preferably but not necessarily in Python)?
Something I pieced together with stuff I found online already is:
import cmath
import math
import numpy
# from mathutils import Vector
class Vector(list):
pass # Im actually using "Vector" from mathutils as above, where mathutils is a library provided by Blender Bpy. But as thats not available as a Python package we can substitute this class by a list.
class fastVectorMath():
"provides tools for when working with vectors. Do not instanciate me"
def vectorSubtract(v1,v2):
try:
return ([v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2],])
except:
return ([v1[0]-v2[0], v1[1]-v2[1]])
def radiansToDegrees(radians: float) -> float:
return radians*180/cmath.pi
def normalizeVector(vector):
""" Returns the normalized (unit vector) of the vector. """
return vector / numpy.linalg.norm(vector)
def getAngleBetweenV1andV2AroundOriginInDegrees(v1: Vector, v2: Vector, origin: Vector): # Tested and works
""" Returns the angle in degrees between vectors 'v1' and 'v2 in the range of 0 to 360'::
>>> angle_between((1, 0, 0), (0, 1, 0))
90,00000000022325
>>> angle_between((1, 0, 0), (1, 0, 0))
0.0
>>> angle_between((1, 0, 0), (-1, 0, 0))
180,0000000004465
"""
v1 = fastVectorMath.vectorSubtract(v1, origin)
v2 = fastVectorMath.vectorSubtract(v2, origin)
v1_u = fastVectorMath.nNormalizeVector(v1)
v2_u = fastVectorMath.normalizeVector(v2)
# v1_u = unit_vector(v1 - origin)
# v2_u = unit_vector(v2 - origin)
# print()
angleInDegreesUnsigned = fastVectorMath.radiansToDegrees(numpy.arccos(numpy.clip(numpy.dot(v1_u, v2_u), -1.0, 1.0)))
# print(f"CROOOOSSSS {numpy.cross(v1_u, v2_u)}")
angleInDegreesSigned = angleInDegreesUnsigned + 180 if (float((numpy.cross(v1_u, v2_u)[-1] > 0)-0.5)*2) else 0
return angleInDegreesSigned
Where I have my method def getAngleBetweenV1andV2AroundOriginInDegrees(v1: Vector, v2: Vector, origin: Vector), which takes 2 vectors and an origin point. Now I would like to basically add a 3rd input to it, namely a 3rd vector to get the rotation about.
To make it more clear what I want, my question is essentially the same as https://math.stackexchange.com/questions/511370/how-to-rotate-one-vector-about-another , except Im not actually looking for the final vector, but instead get the angle based on the 3 vectors.
Thanks!
Solution 1:[1]
The orthogonal projection of A parallelly to C can be obtained from A' = A + k C and A'.C = A.C + k C² = 0, giving A' = A - (A.C / C²) C. Repeat for B' and take the cosine by cos ? = A'.B'/|A'||B'|.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Yves Daoust |
