About Store Forum Documentation Contact



Post Reply 
[EXPLAINED] Strange Matrix angles behavior.
Author Message
Mardok Offline
Bronze Supporter

Post: #1
[EXPLAINED] Strange Matrix angles behavior.
Hello friends,

Plz run this sample code and try rotate Matrix via X axis, by pressing X or Z button.

If you exceed ~1.57 rad (~90 degree) look at values for Z and Y angle. They changed from zero to 180. Are these angles shoudnt be always 0.0?

Now RESET matrix by pressing SPACE and do the same rotation but via Z axis by pressing C or V button. As you can see, you can rotate matrix 360 and XY angles are alawys 0.0.

Code:
/******************************************************************************/
Actor ground,
      box;
    
flt   angle_full_x,
      angle_full_y,
      angle_full_z;

/******************************************************************************/
void InitPre()
{
   EE_INIT();
   Ms.hide();
   Ms.clip(null, 1);
}
bool Init()
{
   Cam.dist=4;

   // create physics
   Physics.create(EE_PHYSX_DLL_PATH); // create physics by specifying the path to physx dll's

   // create actors
   ground.create(Box (15, 1, 15, Vec(0.0, -2, 0)), 0); // create ground actor from Box and density=0 (which means it's a static actor - will not move)
   box   .create(Box (0.5      , Vec(0.0,  0.0, 0.0)));

   box.gravity(false);
   box.kinematic(true);
  

   return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   Cam.transformByMouse(0.1, 10, CAMH_ZOOM|CAMH_ROT);

   {
      Physics.startSimulation();
      Physics.stopSimulation();
   }

   // X rotation
   if(Kb.b(KB_Z))box.orn(box.orn().rotateXL( Time.d() * 0.5));
   if(Kb.b(KB_X))box.orn(box.orn().rotateXL(-Time.d() * 0.5));

   // Y rotation
   if(Kb.b(KB_A))box.orn(box.orn().rotateYL( Time.d() * 0.5));
   if(Kb.b(KB_S))box.orn(box.orn().rotateYL(-Time.d() * 0.5));

   // Z rotation
   if(Kb.b(KB_C))box.orn(box.orn().rotateZL( Time.d() * 0.5));
   if(Kb.b(KB_V))box.orn(box.orn().rotateZL(-Time.d() * 0.5));
  
   // get full angles
   angle_full_x = AngleFull(box.orn().angles().x);
   angle_full_y = AngleFull(box.orn().angles().y);
   angle_full_z = AngleFull(box.orn().angles().z);
        
   if(Kb.bp(KB_SPACE))
   {
      Vec pos = box.pos();
      
      box.matrix(box.matrix().setRotate(Vec(1, 1, 1), 0.0));
   }  
  
   return true;
}
/******************************************************************************/

void Draw()
{
   D.clear     ();  
   Physics.draw();

   {
      SetMatrix();

      box.matrix().pos.draw(WHITE, 0.02);                  
      D.line(RED  , box.pos(), box.pos() + box.matrix().x);
      D.line(GREEN, box.pos(), box.pos() + box.matrix().y);
      D.line(BLUE , box.pos(), box.pos() + box.matrix().z);
   }

   TextStyle ts;
  
   ts.align   = Vec2(   1,   -1);
   ts.size    = Vec2(0.06, 0.06);
            
   Flt y      = D.h();  
  
   D.text(ts, -D.w() + 0.03, y,  S + "[Z, X] - Rot X   [C, V] - Rot Z   [A, S] - Rot Y   [SPACE] - RESET" ); y -= 0.06; y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "box.pos                = " + box.pos()             ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "box.matrix.angles     = "  + box.matrix().angles() ); y -= 0.06; y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "RED    - box.angle.x = " + angle_full_x + " rad | " + RadToDeg(angle_full_x) + " deg"); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "GREEN - box.angle.y = "  + angle_full_y + " rad | " + RadToDeg(angle_full_y) + " deg"); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "BLUE   - box.angle.z = " + angle_full_z + " rad | " + RadToDeg(angle_full_z) + " deg"); y -= 0.06;y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "angle_full_x = " + angle_full_x ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "angle_full_y = " + angle_full_y ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "angle_full_z = " + angle_full_z ); y -= 0.06;
}
/******************************************************************************/
(This post was last modified: 05-18-2016 11:50 AM by Mardok.)
05-16-2016 01:25 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
RE: [BUG ?] Strange Matrix angles behavior.
Hi,

This is OK.

Since there are 2 combinations of angles to represent an orientation.

There isn't just 1.

This means that with 2 combinations of angles, you can get the same kind of orientation.

It's something like:
"x*x = 4"
and what's the value of x?
it can be both 2 and -2,
there are 2 solutions.
05-17-2016 12:51 AM
Find all posts by this user Quote this message in a reply
Mardok Offline
Bronze Supporter

Post: #3
RE: [BUG ?] Strange Matrix angles behavior.
Ok, Greg i understand what you want to say.

I was wondering how to show you my problem... and i did another example which should better describe this situation. I know the code is bad and ugly but is just example... I cannot understand why rotation via Z and Y axis working correct but rotation via X axis isnt correct (the tube actor is reseting when rotation angle exceed some value).

Imo this code shoud work correct (the same) for all axis?

Just run code and wait 3 steps, the 4th step is the clue of my question.

Next you can press Z for change rotation axis and as you can see all working fine.

Code:
/******************************************************************************/
Actor ground,
      box,      
      gun;
        
flt   angle_full_x,
      angle_full_y,
      angle_full_z,
      
      angle_base;          
flt   angle_counter = 0.0;
flt   angle_max     = 0.785;    

flt   pause_counter = 0.0;
bool  paused        = false;

VecI  rot_axis      = VecI(1, 0, 0);
/******************************************************************************/



void reset()
{
   paused        = true;
   pause_counter = 0.0;      
   angle_counter = 0.0;    
   box.matrix(box.matrix().setPos(Vec(0.0, 0.0, 0.0)));
  
   angle_base = (rot_axis * box.orn().angles()).sum();
}



/******************************************************************************/
void InitPre()
{
   EE_INIT();
   Ms.hide();
   Ms.clip(null, 1);
}
bool Init()
{
   Cam.dist=4;

   // create physics
   Physics.create(EE_PHYSX_DLL_PATH); // create physics by specifying the path to physx dll's

   // create actors
   ground.create(Box ( 15, 1, 15, Vec(0.0,  -2,   0)), 0); // create ground actor from Box and density=0 (which means it's a static actor - will not move)
      box.create(Box (0.5,        Vec(0.0, 0.0, 0.0)));
      gun.create(Tube(0.1, 3.0));

   box.kinematic(true).collision(false);
   gun.kinematic(true).collision(false);
  
  
   // get angle startup value
   angle_base = box.orn().angles().x;
  


   return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   Cam.transformByMouse(0.1, 10, CAMH_ZOOM|CAMH_ROT);

   {
      Physics.startSimulation();
      Physics.stopSimulation();
   }
  
   if(Kb.bp(KB_X)){ rot_axis = VecI(1, 0, 0); reset(); }  
   if(Kb.bp(KB_Y)){ rot_axis = VecI(0, 1, 0); reset(); }
   if(Kb.bp(KB_Z)){ rot_axis = VecI(0, 0, 1); reset(); }
  
   if(paused)  // pause
   {
      pause_counter += Time.d();
      
      if(pause_counter >= 1.0)
      {
         paused        = false;
         pause_counter = 0.0;
      }      
   }else       // rotation
   {
      angle_counter += Time.d();
  
      box.orn(box.orn().setRotate(rot_axis, angle_base + angle_counter));
  
      if(angle_counter >= angle_max)
      {        
         box.orn(box.orn().setRotate(rot_axis, angle_base + angle_max));
        
         angle_base = (rot_axis * box.orn().angles()).sum();
        
         paused        = true;
         angle_counter = 0.0;
      }
   }
  
   // gun matrix
   gun.matrix(box.matrix()        );
   gun.pos   (box.matrix().y * 2.0);      

  
   // get full angles
   angle_full_x = AngleFull(box.orn().angles().x);
   angle_full_y = AngleFull(box.orn().angles().y);
   angle_full_z = AngleFull(box.orn().angles().z);
  
   return true;
}
/******************************************************************************/

void Draw()
{
   D.clear     ();  
   Physics.draw();

   {
      SetMatrix();

      box.matrix().pos.draw(WHITE, 0.02);                  
      D.line(RED  , box.pos(), box.pos() + box.matrix().x);
      D.line(GREEN, box.pos(), box.pos() + box.matrix().y);
      D.line(BLUE , box.pos(), box.pos() + box.matrix().z);
   }

   TextStyle ts;
  
   ts.align   = Vec2(   1,   -1);
   ts.size    = Vec2(0.06, 0.06);
            
   Flt y      = D.h();  
  
   D.text(ts, -D.w() + 0.03, y,  S + "Current box rot axis (X,Y,Z): " + rot_axis + "   Press [X], [Y], [Z] - to select rotation axis."); y -= 0.06; y -= 0.06;
  
   //D.text(ts, -D.w() + 0.03, y,  S + "box.pos                = " + box.pos()             ); y -= 0.06;
   //D.text(ts, -D.w() + 0.03, y,  S + "box.matrix.angles     = "  + box.matrix().angles() ); y -= 0.06; y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "RED    - box.angle.x = " + angle_full_x + " rad | " + RadToDeg(angle_full_x) + " deg"); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "GREEN - box.angle.y = "  + angle_full_y + " rad | " + RadToDeg(angle_full_y) + " deg"); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "BLUE   - box.angle.z = " + angle_full_z + " rad | " + RadToDeg(angle_full_z) + " deg"); y -= 0.06;y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "box angle_full_x = " + angle_full_x ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "box angle_full_y = " + angle_full_y ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "box angle_full_z = " + angle_full_z ); y -= 0.06;
}
/******************************************************************************/
(This post was last modified: 05-17-2016 11:48 PM by Mardok.)
05-17-2016 04:43 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #4
RE: [BUG ?] Strange Matrix angles behavior.
Sorry but I don't understand this part:
Code:
angle_base = (rot_axis * box.orn().angles()).sum();
I think your problem is in the line above.

In short:
You shouldn't be working with angles in a way like you are doing right now.
You need a different approach.
05-18-2016 02:38 AM
Find all posts by this user Quote this message in a reply
Mardok Offline
Bronze Supporter

Post: #5
RE: [BUG ?] Strange Matrix angles behavior.
Code:
angle_base = (* rot_axis box.orn (.) angles ().) sum ();

I know its ugly but its simple: angle_base remember last value from orn.angles for currently selected rotation axis. This code can be Replaced for example:
Code:
if(rot_axis.x)angle_base = box.orn.angles.x;else if(rot_axis.y)angle_base = box.orn.angles.y;else angle_base = box.orn.angles.z;
// Or it can be:
angle_base = box.orn.angles.sum; // (Without multiply, because  only rotate by X axis orn.angles.y and .z == 0.0, this give me value only for actual angle X)
angle_base remember last angle which i need to continue rotation calling setRotate in every frame. The whole code and rotation working well when the rotation axis is Z or Y but for X setRotate func doing something strange, the values ​​in orn.angles.y and .z jumping from 0 to -3.14, something like change dir for all matrix. This code should work Universally, its not elegant but is simple.

begin> incrase angle counter to desired limit> setRotate> remember angle for selected axis-> reset angle counter> go to begin

The most important question for me is:
Is this correct if we call setRotate (Vec (1,0,0), angle) the values ​​in orn.angles Y and Z are non zeros? I always thought there should be zeros.

The code is bad but theoretically should work correct xD
05-18-2016 04:05 AM
Find all posts by this user Quote this message in a reply
Tottel Offline
Member

Post: #6
RE: [BUG ?] Strange Matrix angles behavior.
Hi Mardok,

Long time no see!

This code works:

Code:
/******************************************************************************/
Actor ground,
      box,      
      gun;
        
flt   angle_full_x,
      angle_full_y,
      angle_full_z,
      
      angle_base;          
flt   angle_counter = 0.0;
flt   angle_max     = 0.785;    

flt   pause_counter = 0.0;
bool  paused        = false;

VecI  rot_axis      = VecI(1, 0, 0);
/******************************************************************************/



void reset()
{
   paused        = true;
   pause_counter = 0.0;      
   angle_counter = 0.0;    
   box.matrix(box.matrix().setPos(Vec(0.0, 0.0, 0.0)));
  
   //angle_base = (rot_axis * box.orn().angles()).sum();
}



/******************************************************************************/
void InitPre()
{
   EE_INIT();
   Ms.hide();
   Ms.clip(null, 1);
}
bool Init()
{
   Cam.dist=4;

   // create physics
   Physics.create(EE_PHYSX_DLL_PATH); // create physics by specifying the path to physx dll's

   // create actors
   ground.create(Box ( 15, 1, 15, Vec(0.0,  -2,   0)), 0); // create ground actor from Box and density=0 (which means it's a static actor - will not move)
      box.create(Box (0.5,        Vec(0.0, 0.0, 0.0)));
      gun.create(Tube(0.1, 3.0));

   box.kinematic(true).collision(false);
   gun.kinematic(true).collision(false);
  
  
   // get angle startup value
   //angle_base = box.orn().angles().x;
  


   return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   Cam.transformByMouse(0.1, 10, CAMH_ZOOM|CAMH_ROT);

   {
      Physics.startSimulation();
      Physics.stopSimulation();
   }
  
   if(Kb.bp(KB_X)){ rot_axis = VecI(1, 0, 0); reset(); }  
   if(Kb.bp(KB_Y)){ rot_axis = VecI(0, 1, 0); reset(); }
   if(Kb.bp(KB_Z)){ rot_axis = VecI(0, 0, 1); reset(); }
  
   if(paused)  // pause
   {
      pause_counter += Time.d();
      
      if(pause_counter >= 1.0)
      {
         paused        = false;
         pause_counter = 0.0;
      }      
   }else       // rotation
   {
      angle_counter += Time.d();
      box.orn(box.orn().setRotate(rot_axis, angle_base + angle_counter));
  
      if(angle_counter >= angle_max)
      {        
         //box.orn(box.orn().setRotate(rot_axis, angle_base + angle_max));
        
         angle_base += angle_max;  //(rot_axis * box.orn().angles()).sum();
        
         paused        = true;
         angle_counter = 0.0;
      }
   }
  
   // gun matrix
   gun.matrix(box.matrix()        );
   gun.pos   (box.matrix().y * 2.0);      

  
   // get full angles
   angle_full_x = AngleFull(box.orn().angles().x);
   angle_full_y = AngleFull(box.orn().angles().y);
   angle_full_z = AngleFull(box.orn().angles().z);
  
   return true;
}
/******************************************************************************/

void Draw()
{
   D.clear     ();  
   Physics.draw();

   {
      SetMatrix();

      box.matrix().pos.draw(WHITE, 0.02);                  
      D.line(RED  , box.pos(), box.pos() + box.matrix().x);
      D.line(GREEN, box.pos(), box.pos() + box.matrix().y);
      D.line(BLUE , box.pos(), box.pos() + box.matrix().z);
   }

   TextStyle ts;
  
   ts.align   = Vec2(   1,   -1);
   ts.size    = Vec2(0.06, 0.06);
            
   Flt y      = D.h();  
  
   D.text(ts, -D.w() + 0.03, y,  S + "Current box rot axis (X,Y,Z): " + rot_axis + "   Press [X], [Y], [Z] - to select rotation axis."); y -= 0.06; y -= 0.06;
  
   //D.text(ts, -D.w() + 0.03, y,  S + "box.pos                = " + box.pos()             ); y -= 0.06;
   //D.text(ts, -D.w() + 0.03, y,  S + "box.matrix.angles     = "  + box.matrix().angles() ); y -= 0.06; y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "RED    - box.angle.x = " + angle_full_x + " rad | " + RadToDeg(angle_full_x) + " deg"); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "GREEN - box.angle.y = "  + angle_full_y + " rad | " + RadToDeg(angle_full_y) + " deg"); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "BLUE   - box.angle.z = " + angle_full_z + " rad | " + RadToDeg(angle_full_z) + " deg"); y -= 0.06;y -= 0.06;
  
   D.text(ts, -D.w() + 0.03, y,  S + "box angle_full_x = " + angle_full_x ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "box angle_full_y = " + angle_full_y ); y -= 0.06;
   D.text(ts, -D.w() + 0.03, y,  S + "box angle_full_z = " + angle_full_z ); y -= 0.06;
}
/******************************************************************************/
05-18-2016 08:42 AM
Find all posts by this user Quote this message in a reply
Mardok Offline
Bronze Supporter

Post: #7
RE: [EXPLAINED] Strange Matrix angles behavior.
hello Tottel my friend,
yes you're right xD

sorry guys for waste your time :] i just block my brain on that setRotate func xD
05-18-2016 11:44 AM
Find all posts by this user Quote this message in a reply
Post Reply