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"