# Subtracting Vectors and quaternion

• On 11/06/2013 at 11:59, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R13-R14
Platform:   Windows  ;
Language(s) :     C++  ;

---------
Hi,
I have this

``````Vector a = foo->GetAbsRot();
Vector b = bar->GetAbsRot();
Vector result = b - a;

superFoo->SetRelRot(result);
``````

This works fine, until the result is tipping around 360 and 0. I then get what probably is called a "gimbal" rotation or the like, because then things behave funny.
I guess this is a case for some quaternion (?).
But I have no idea how to do this, can anyone point me in the right direction?
And yes, I have searched the docs.. but I cannot figer out how to use the Quaternion class here.
Ingvar

• On 11/06/2013 at 14:25, xxxxxxxx wrote:

Ok, I realize I have some stuff to learn.. sorry to bother you with these questions about rotation. I need to read me up on rotation, axis and the like. Because I ask silly questions I think..

• On 12/06/2013 at 02:39, xxxxxxxx wrote:

Try looking this up in the SDK docs...

``````Vector GetOptimalAngle(const Vector& hpb_old, const Vector& hpb_new, ROTATIONORDER order)
``````

EDIT: You might also be interested in a few more utility functions on that same page...

``````void MatrixToRotAxis(const Matrix& m, Vector* v, Real* w)
Matrix RotAxisToMatrix(const Vector& v, Real w)
``````

etc.

Cheers.

• On 12/06/2013 at 03:04, xxxxxxxx wrote:

BTW, this is slightly off-topic, but...

There is (or at least was - see below) a 'bug' in the supplied "MatrixToRotAxis()" routine.  The axis + angle returned could _not_ be passed to the complimentary "RotAxisToMatrix()" routine to reproduce the original matrix.

I cobbled together this 'fix'...

``````//-----------------------------------------------------------------------------
// MyMatrixToRotAxis()
//-----------------------------------------------------------------------------
void MyMatrixToRotAxis(const Matrix &mm, Vector *v, Real *w)
{
Matrix m = mm;
// MatrixVectoren MUESSEN normiert sein!!!
m.v1=!m.v1;
m.v2=!m.v2;
m.v3=!m.v3;

// Winkel berechnen
*w = ACos((m.v1.x+m.v2.y+m.v3.z-1.0)/2.0);

// NOTE: subtraction order reversed (original Maxon code did not produce a
//       axis  \+ angle that could be used to reproduce the starting Matrix
//       using RotAxisToMatrix())
//    v->x= m.v2.z-m.v3.y;
//    v->y= m.v3.x-m.v1.z;
//    v->z= m.v1.y-m.v2.x;

v->x= m.v3.y-m.v2.z;
v->y= m.v1.z-m.v3.x;
v->z= m.v2.x-m.v1.y;

*v = !(*v);

if (*v==0.0)
{
*v = Vector(0.0,1.0,0.0);
*w = 0.0;
}
}
``````

...now, I see that the code for "RotAxisToMatrix()" has since changed, so/but I have not yet validated what it returns - it may make my 'fix' above obsolete/invalid - I'm personally still calling the older version of that routine from an earlier SDK (included below for completeness) :

``````//-----------------------------------------------------------------------------
// MyRotAxisToMatrix()
//-----------------------------------------------------------------------------
Matrix MyRotAxisToMatrix(const Vector &v, Real w)
{
Matrix m;

if ((Abs(v.x)+Abs(v.y)+Abs(v.z))!=0.0 )
{
// zuerst mal den Vector normieren ...
m.v2 = !v;

// jetzt ein rechtes KS basteln
m.v1 = m.v2%Vector(0.0,0.0,1.0);
#ifdef _R12_SDK_
if (Len(m.v1)>MIN_EPSILON)
#else
if (Len(m.v1)>MINSIZE)
#endif
{
m.v3 = m.v1%m.v2;
}
else
{
m.v3 = Vector(1.0,0.0,0.0)%m.v2;
m.v1 = m.v2%m.v3;
}

// Rotationsmatrix im Pleft- und Rechtssystem um Y ist gleich
m = (m*MatrixRotY(w)) * !m;
}
return m;
}
``````

...the latest version of the SDK code may now work correctly (? the only new comment just says that it's a "faster version", so the resulting values may be the same as before), but if not, then the above two routines should allow you to start with a matrix, extract an axis + angle using MyMatrixToRotAngle() and then feed those back into MyRotAxisToMatrix() to reproduce the original matrix.  This fixed a major export -> import headache for me, many, many moons ago :).

• On 12/06/2013 at 03:21, xxxxxxxx wrote:

Giblet, thanks  a LOT for this!
It  is very much appreciated.
I am trying to learn it, and at the same time make progress with my plugins.

I will study your posts later, I just want, now, to explain, what my current task is:

I have object_A and  object_B.
These two objects are children of other, separate objects. You can think of it as a handle on two separate machines. When one handle moves, I want the other machine's handle also to move.

This works perfect when the two object groups are identical. The problem arises when one of the handles has a different axis rotation than the other.
So basically what I want:

When object_A rotates, I want to capture the rotation taking into account object_A's proprietary rotation axis, and apply this to object_B, taking into account object_B's proprietary rotation axis. With the end result that they both make the same move, seen from the outside.
The difference between object_A and object_B is of course  mapped and stored as a value, before the animation begins. (If that is required)

I am struggling with this. I either will have to come up with a solution by accident, or find a solution on thew internet, or get help here in this forum or roll up my sleeves and try to get to grips with all this. I see a combination of the two latter as the best..

• On 12/06/2013 at 03:23, xxxxxxxx wrote:

Yes, I've seen your other posts on the subject, but don't have the solution for you - I just thought the above may help.

BTW, that:

#ifdef _R12_SDK_

...is my own #define... you should probably replace that with:

#if API_VERSION >= 12000

Cheers.

• On 12/06/2013 at 03:36, xxxxxxxx wrote:

Yes, and it does help.

But basically - this goes on behind the scenes inside Cinema 4D every time you press W, right? Then you rotate in world coordinates. That is what I want to do, translate the rotation of object_A into world angles, then use these world angles by translating them into "object_B angles", if I may use that expression.

What I really want, is maybe called "rotate a vector (or matrix)". The same happens when you apply a constraint tag and offset the rotation. But I do not have the C4D source code..

• On 12/06/2013 at 03:53, xxxxxxxx wrote:

Was ist ein "KS" das Du gebastelt hast? Was bedeutet die Abkürzung?

• On 12/06/2013 at 08:45, xxxxxxxx wrote:

Sorry - the comments are from the original source (c4d_tools.cpp) - I don't speak German and do not know what the author was trying to say.

• On 12/06/2013 at 10:36, xxxxxxxx wrote:

Oh, sorry I thought you had written it.
I think it translates to "an now I will tinker (assemble/build/throw together) a real KS"