I have two vectors in 3D-space, S
(Start) and T
(Target), and I want to find the Rotation Matrix (RM) that allows such transformation.
I know that by computing the cross product S × T
I get the rotation axis. The angle between S
and T
is given by tan⁻¹(||S × T||, S·T)
, where S·T
is the dot product between S and T.
This gives me the rotation vector rotvec = [S x T; angle]
(the cross product is normalized). Then by using function vrrotvec2mat (in MATLAB) or transforms3d.axangles.axangle2mat (in Python) I can obtain the rotation matrix that corresponds to the transformation from S
to T
.
In my application T
is given by the dot product RM·D
, where is D
is a 3x1
vector. My goal is to find RM. I know S
, T
and D
, but I am having trouble to understand the math behind this.
In practice I want to find a RM between S
and T'
, where T'
is the target vector before D
(the direction) has been applied.
A little more context: I want to obtain body joint angles from 3D points in the camera coordinate system.
In order to make this work you also need the center of rotation (point that stays the same after rotation)... Now we need two transform matrices one representing coordinate system before and one after the transform.
To construct your 3D transform matrix you need 3 perpendicular basis vectors and origin position see:
now rotation axis will be one of the basis vectors and we can use
S,T
as second one so the third we can compute with cross product and the origin will be the center of rotation:So construct 4x4 transform matrix
A
from those. And do the same forB
but useT
instead ofS
. Now we want to compute the difference transform so ifp=(x,y,z,1)
is any point to transform then:So your transform matrix
M
is:Beware this will work with standard OpenGL conventions if you use different one (multiplication order, matrix orientation, etc) the equation might change.
You can also use full pseudo inverse matrix to compute the
Inverse(A)
more effectively and accurately.As you can see you do not need any goniometrics nor angle to do this (vector math is nice in this)
[Edit1] C++ example
Its using VCL (AnsiString and mm_log which you can ignore) and my vector math (used functions are in the first link).
Here the result:
As you can see if I transform unit
S
byM
I got the unitT
vector. PS. mymatrix_mul_vector
andvector_mul
assumesw=1.0
but asO=(0.0,0.0,0.0)
the vectors and points are the same.