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"


Log in to reply