Rotation function not working correctly

edited March 2016 in Questions about Code

So I have this rotation function, rotate2D(horizontal, vertical) that you can see and play with in the below sketch.

I am using it to try to correctly simulate simultaneous rotation of a cube in multiple dimensions at once. (processing's standard rotation functions make this tricky)

It works okay, but it is a little bit off, which causes it to be glitchy sometimes. For example, if you do rotate2D(90,90); I want it to look just like it does if you do rotate2D(0,0);(disregarding the position of the axes) but it seems like X and Y don't quite get rotated enough. For example if youare doing a 90 90 rotation and you change the test condition on line 51 to i<=abs(rotations[0])+37 you get what you expect.

please feel free to ask me to clarify further. Can anyone help me out?

float y=0;
float x=0;
float box_size=50.0;
float rotation_scale=(90.0/50.0);
void setup()
{
  size(1000,1000,P3D);
}    

void draw()
{

   background(255);
   translate(500,500);
   translate(x*rotation_scale,-y*rotation_scale);
   rotate2D(x,y);
   x++;
   y++;      
  draw_axes();
  box(box_size);
}

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 horizontal, float vertical)
{  
  float[] rotations ={horizontal, vertical};
  if(rotations[0]>rotations[1])
  {
    float tmp = rotations[1];
    rotations[1]=rotations[0];
    rotations[0]=tmp;
  } 

  if(rotations[1]==vertical) rotateX(radians(rotations[1]-rotations[0]));
  else rotateY(radians(rotations[1]-rotations[0]));

  float hIncr= (horizontal<0) ? -0.1 : 0.1;
  float vIncr= (vertical<0) ? -0.1 : 0.1;
  for(float i=0; i<=abs(rotations[0]);i+=0.1)
  {    
    rotateY(radians(hIncr));
    rotateX(radians(vIncr));
  }   
}

Edit for clarity

The point of this function is to try to create semi-realistic, visually appealing rotation of a box given movement in a particular direction. Although, in this case, I am deciding the rotations first and then translating accordingly, just for simplicity.

Explanation of horizonal andvertical parameters and their meaning:

To get an idea of the exact significance of these parameters and their meanings, try calling the function with one of the values set to zero.

calling rotate2D(45,0) causes the box to rotate to the right but not upwards.

calling rotate2D(0,45) causes the box to rotate upwards but not to the right.

These results can be achieved by simply calling rotateY(45) and rotateX(45) respectively, however, if you want to rotate in 2 directions simultaneously, simply calling these functions will likely not yield a desirable result because once you rotate about the Y axis, the X axis itself has been rotated. I am trying to simulate the rotation about a fixed set of axis, by slowly rotating in each direction until the bounds are reached. And it does yield a desirable rotation but It seems like the box is just not rotating enough given each parameter. I'm looking for a way to correct this while still yielding the same general rotational pattern.

In response to quark: I am aware that the box just rolls off of the screen, I was just providing a template for people to play around with the increments to see the way the rotation was affected.

The reason I have it at x++; y++; is because, (because of the problem I am trying to solve here) this increment pattern gives the best results currently, but even this is not perfect as you can see it glitch sometimes.

Answers

  • edited January 2015

    I am using it to try to correctly simulate simultaneous rotation of a cube in multiple dimensions at once. (processing's standard rotation functions make this tricky)

    What do you mean by correct?

    Your rotate2D method has no comments so although the syntax is perfectly understandable the semantics (i.e. the meaning is not) I suggest you add comments explaining HOW or WHY the code should make the rotations 'correct'.

    Also I think there is a mistake in line 15 it just makes the cube move off the top right of the screen.


    So the Y axis is red, the X axis is green and the Z axis is blue. Are you expecting the rotations horizontal and vertical to be about the red and green axis and to be able to specify these values independently? If so its not going to work. The rotate methods apply to the world view axises, and you need them to apply to the model view axis (i.e. the cube's local axises) there is no mapping between world and model view axis that does this. This was explained in your other discussion

  • edited January 2015

    quark I still do not see why this would not be possible, To me it seems like there must be some sort of mathematical relationship that can be defined, I just don't have a closed form formula to use, so I'm simulating it as best as I can imagine with a for loop. Unless you are simply saying that processing does not have a built in function for it. In which case I am painfully aware.

    I mean clearly someone has to have run into this problem before and worked around it.

    Also, i edited my question to address your points and hopefully make my dilemma more clear in general

    edit: perhaps the best way to see the point of my code is to replace the call to rotate2D with calls directly to rotateXY and note the difference, you should see that mine looks much more realistic, as if there are 2 force simultaneously pushing the box to the right and upwards

    also note that when I say that I want the box to look the same with rotate(90,90) and rotate(0,0) I am not talking about the position of the axes, I am aware that there is no way to literally keep the axes fixed, I simply want to simulate movement about a fixed set of axes under the presumption that the user will have no idea which axes is which and will not be able to see them or care at all.

  • I mean clearly someone has to have run into this problem before and worked around it.

    The solution is to rotate the model coordinates about the model's local axis.

  • what do you mean by that? are you saying rather than use box(), make my own shape and apply a rotation function to the coordinates?

    How sure are you that it is impossible to achieve what I am doing here? I really am having a hard time understanding how it is impossible. My current solution is actually fairly close

  • what do you mean by that? are you saying rather than use box(), make my own shape and apply a rotation function to the coordinates?

    Yes :)

  • edited January 2015

    Hey check that link. I came up with a solution to the question as I stated it and someone else also presented a more precise solution using quaternions!

  • There is a rotation function that is not in the basic documentation that allows you to specify axis and angle. The axis is a normalized vector that points perpendicular to the direction of roll. In the following example the cube rolls towards the direction of the mouse position.

    void setup() {
      size(800,800,P3D);
    }
    
    void draw() {
      background(204);
      translate(width*.5, height*.5);
    
      float heading = 
        atan2(mouseY-height*.5, mouseX-width*.5);
      heading += HALF_PI;
    
      pushMatrix();
      rotate(
        frameCount*.01, cos(heading), sin(heading), 0);  
      box(200);
      popMatrix();
    
      line(0, 0, cos(heading)*300, sin(heading)*300);
      heading -= HALF_PI;
      line(0, 0, cos(heading)*300, sin(heading)*300);
    }
    
  • edited January 2015

    @rbrauer <3 do you have any experience using this with processing.js? this is ultimately how I plan on implementing my sketch, but the processing.js reference guide doesn't show that as a syntax option like processing does.

  • I haven't used processingjs much, but I dropped the code in sketchpad.cc and it seems to work. http://sketchpad.cc/e5bVrhgP5m

Sign In or Register to comment.