Correctly rotate an object in multiple dimensions simultaneously

edited January 2015 in Using Processing

So, let say I have this box. There are forces operating on said box simultaneously, that are coming from the X Y and Z dimensions.

box

For the sake of simplicity we can assume that, were it not for the other forces each force would result in exactly a 30 degree rotation in the direction it is moving. So, for example, were it not for the forces in the z or the Y direction, the force in the x direction would cause a rotateY(radians(30))

However, the order in which the rotations are performed affects the end result:

rotateY(radians(30));
rotateX(radians(30));

and

rotateX(radians(30));
rotateY(radians(30));

each yield different results.

There must be some established technique for doing this sort of thing. How do you go about it? Trig is not my strong suit.

Edit: For now, we can ignore the Z dimension. Its rotational force is just going to be added to the desired rotateX(). So, in the above example, I would technically want to do rotateX(radians(0)); and rotateY(radians(30)); but this is only by coincidence.


solution in progress:

I know there is a trigonometric relationship that can be derived to get the correct simulation by utilizing the Z axis as a way of correcting the rotation, I just can't find it yet.

Here is what I have so far. Right now I just want it to look right when simultaneous forces are pushing to the right and upwards.

float y=0;
float x=0;
void setup()
{
  size(500,500,P3D);
}

void draw()
{
    translate(250,250);
    background(255);
    x+=1;
    y+=1;
    rotate2D(x,y);
    draw_axes(); 
    box(50);   
}
void draw_axes()
{
    stroke(255,0,0);
    line(0,-250,0,250);
    stroke(0,250,0);
    line(-250,0,250,0);
    stroke(0,0,255);
    line(0,0,-250,0,0,250);
    stroke(0);
}

void rotate2D(float x, float y)
{
  if(x>=90) x%=90;
  if(y>=90) y%=90;


  float xDir = radians(x);
  float yDir = radians(y);
  if (y<45)
  {
      rotateZ(xDir);
      rotateY(xDir);
      rotateX(yDir);
  }
  else
  {
      rotateZ(xDir);
      rotateY(xDir);
      rotateX(radians(45));      
      rotateX(radians(y-45));
      rotateZ(radians(2*(x-45)));
  }
}

anyone wanna take a stab? You can see that it is close, but you can also see that the 45 degree conditional isn't precise enough(you see the box start to dip before it hits 45 degrees) perhaps there should be different methods of rotation for 0<30<45<60<90?

In the end, the box should rotate the same way it does currently, but it should all look like it is one continuous rotation

I am hoping you can see what I'm getting at here.

Answers

  • edited January 2015

    Unless you're calculating each vertex' position manually (without using rotate() functions), I'm afraid it's not possible to achieve what you want.

    But of course, I'd like to see a solution if someone has one.

  • Could you either explain why it's not possible. Or explain how to do it by calculating the vertex positions manually? (Why wouldn't it be possibly to calculate the vertex positions and then write a function that takes two (x,y,z) and (x',y',z') and returns the necessary rotateXYZ parameters?)

  • edited January 2015

    I feel like this has to be possible, I've had people suggest that I look into quaternion rotation and rotation matrices, but they confused me and I was hoping to get some supplemental information here.

  • edited January 2015

    In the below sketch, I demonstrate that rotating z first can yield results that are close to one another, perhaps there is a definable relationship here?

    void setup()
    {
      size(500,500,P3D);
      translate(100,100,0);
      box(50);
      translate(100,0,0);
      rotateY(radians(30));
      box(50);
      rotateY(radians(-30));
      translate(100,50,0);
      rotateY(radians(30));
      rotateX(radians(30));
      box(50);
      rotateX(radians(-30));
      rotateY(radians(-30));
      translate(-200,50,0);
      box(50);
      translate(100,0,0);
      rotateX(radians(30));
      box(50);
      rotateX(radians(-30));
      translate(100,-50,0);
      rotateZ(radians(-15));
      rotateX(radians(30));
      rotateY(radians(30));
      box(50);
    }
    
  • The rotate methods define rotations about the world axis, so a rotation also rotates the objects axises. Rotation about any two world axises effectively rotates the object about all three of the object axis. AFAIK the only way to rotate about the object axises is to recalculate the vertex coordinates as suggested by Patakk.

Sign In or Register to comment.