ShapeRenderer Rotate Question

Anything libgdx related goes here!

ShapeRenderer Rotate Question

Postby dayrinni » Sun Mar 10, 2013 9:17 pm

Hello,

I just started playing around with LibGDX. Right now, I'm looking into the ShapeRenderer class. I'm trying to draw some shapes that are rotated around their center point. I have not been very successful unfortunately. The Javadoc for the class does not seem to have much to go from, and googling hasn't really been useful to me. So I have decided to post. I'm 99.99% sure I'm just using the API wrong.

Here is my code snippet:
Code: Select all
      shapeRenderer.begin(ShapeType.Rectangle);
      shapeRenderer.setColor(Color.BLUE);
      shapeRenderer.identity();
      
      shapeRenderer.rotate(0.f, 0.f, 1.f, 45f);
      shapeRenderer.rect(300, 100, 50, 50);
      
      shapeRenderer.identity();
      shapeRenderer.setColor(Color.RED);
      shapeRenderer.rotate(300+50/2, 100+50/2, 0, 45f);
      shapeRenderer.rect(300, 100, 50, 50);
      
      shapeRenderer.identity();
      shapeRenderer.setColor(Color.YELLOW);
      shapeRenderer.rect(300, 100, 50, 50);
      shapeRenderer.end();


I'm drawing 3 rectangles (blue, red and yellow). Blue and red are supposed to be rotated while yellow is not.
For blue, I'm not really sure why I'm rotating in the z direction but I found many examples of this on the internet so I decided to try it. It does not do what I want. It seems to move the rectangle far away from where it was really drawn.
For red, this seems to work a lot better, however, it only draws half of the rotated rectangle. I'm not really sure why this is.

Here is an image showing my end result:
Image

I've tried a few other things but most times, the shape doesn't even draw on the screen (ie: changing rotate to: shapeRenderer.rotate(300+50/2, 100+50/2, 1.f, 45f);).

Thanks for your help.
dayrinni
 
Posts: 17
Joined: Sun Mar 10, 2013 9:04 pm

Re: ShapeRenderer Rotate Question

Postby davedes » Sun Mar 10, 2013 10:00 pm

Hey dayrinni,

We need to rotate around the Z axis for 2D rotation. Keep in mind that X, Y, Z coordinates are, respectively, left/right, up/down, forward/backward. A common way to remember this:
Image

Imagine if we tried rotating around the thumb; this would lead to our index finger pointing away or toward us. Rotating around the index finger would lead to our thumb pointing away or toward us. To rotate our 2D shapes, and keep the X and Y fingers pointing the same way, we need to rotate around our middle finger (Z axis).

Keep in mind that LibGDX uses a lower-left origin (same with OpenGL and most other 3D rendering APIs). When we call "rotate", it rotates the entire context AKA "transformation matrix" from the lower-left origin. So we need to actually translate to the desired (x, y) location first, then rotate. This will render the blue rectangle at (300, 100), rotated around its lower-left corner by 45 degrees.

Code: Select all
      shapeRenderer.translate(300, 100, 0f);
      shapeRenderer.rotate(0.f, 0.f, 1.f, 45f);
      shapeRenderer.rect(0, 0, 50, 50);


The problem with the red square is that you are rotating it along the X and Y axis, instead of the Z axis. Since it is no longer aligned to the view, part of it is getting clipped by our 2D projection.
davedes
 
Posts: 433
Joined: Thu Oct 11, 2012 7:51 pm

Re: ShapeRenderer Rotate Question

Postby dayrinni » Tue Mar 12, 2013 1:25 am

Hi Dave,

Your explanation made a lot of sense - the picture sealed the deal for me.

I took your suggestion and put it in my test program and gave it a whirl. It worked. It seemed to rotate around the bottom left corner.
Here's an image:
Image

I still would like it to be rotated around it's center, which would be 325, 125 in this particular example.

So after thinking I understood this, the solution is now translate like before but include half of the width and height. Like this:
Code: Select all
      shapeRenderer.identity();
      shapeRenderer.setColor(Color.RED);
      shapeRenderer.translate(325, 125, 0f);
      shapeRenderer.rotate(0.f, 0.f, 1.f, 45f);
      shapeRenderer.rect(0, 0, 50, 50);


Well, this didn't work out:
Image

Most likely due to the origin still being at the bottom left.

Then I decided to use my brain and what you've taught me so far. The solution is to translate, rotate, and then translate again:
Code: Select all
      shapeRenderer.identity();
      shapeRenderer.setColor(Color.RED);
      shapeRenderer.translate(325, 125, 0f);
      shapeRenderer.rotate(0.f, 0.f, 1.f, 45f);
      shapeRenderer.translate(-25, -25, 0f);
      shapeRenderer.rect(0, 0, 50, 50);


And this gives the desired result up above. Now I can now progammatically determine the center rotate. Maybe there is an easier way to achieve the above but it works for me.

Thanks for your help!
dayrinni
 
Posts: 17
Joined: Sun Mar 10, 2013 9:04 pm


Return to Libgdx

Who is online

Users browsing this forum: cryo75, Google [Bot], Semtiko and 6 guests