Java 2D Rotation Question

Hi, I currently use g.rotate to rotate the main player (currently a square), my problem is that g.rotate rotates everything drawn.

For example: g.rotate(myCharector.getRoation(mouseX, mouseY),
(int) myCharector.getXCoordinate() + 10,
(int) myCharector.getYCoordinate() + 10); //Rotation works as intended

              g.fillRect((int) myCharector.getXCoordinate(),
		(int) myCharector.getYCoordinate(), 20, 20);
		
          if (characterMenu == true) {
                    //draws a characterMenu 
              }

I want the characterMenu to be drawn above the character but I don’t want the characterMenu to be rotated along with the square. To fix the problem I had to call g.rotate with the opposite value so the rotation would cancel out. I feel as if this isn’t the most efficient way of handling the problem though. Does anyone have any suggestions?

Thanks in advance for any help you provide, I really appreciate it!

You can rotate back, or you can get the current transform, create a new AffineTransform, rotate that, set the current transform to that, draw, then set it back to the original transform. You can keep the rotation transform around so doing that is actually cheaper.

I’d show you code, but I don’t do enough Java2D to actually translate it in my head.

Rotating the negative the value is the correct and most efficient way to do it.

You could go with creating a new temporary AffineTransform, but that requires the creation of an object.

Rotating back introduces rounding errors in your matrix. If Java2D is in software rendering mode (or any mode, if you believe the rumors) then that tiny rotation will cause a huge drop in performance, for everything else you’re going to render after that.

Oh silly me, you can just grab the transform once, no need to explicitly create one. Or just rotate back, though that does get annoying if you start stacking multiple transforms.


+ AffineTransform t = g.getTransform()
g.rotate(myCharector.getRoation(mouseX, mouseY),
            (int) myCharector.getXCoordinate() + 10,
            (int) myCharector.getYCoordinate() + 10); //Rotation works as intended

g.fillRect((int) myCharector.getXCoordinate(), (int) myCharector.getYCoordinate(), 20, 20);
+ g.setTransform(t);
             if (characterMenu == true) {
                        //draws a characterMenu
                  }

Oh right, rounding errors! :o

A little modification :wink:

Once again the lack of push/pop in Graphics becomes obvious.


private LinkedList<Graphics> stack = new LinkedList<Graphics>();

public Graphics push(Graphics g) {
   this.stack.addFirst(g); // save it for later
   return g.create(); // copies the Graphic object
}

public Graphics pop() {
   return this.stack.removeFirst(); // restore it
}


public void paint(Graphics g) {
   ...
   g = this.push(g);
   ...
   g = this.pop();
   ...
}

Ehhhh that’s just overkill…

Infinitely better than juggling with setting/unsetting nested AffineTransforms.

Thanks everyone, AffineTransform works wonders!

Riven I’ll start studying push/pop thanks for bringing it up.

There’s no need to create and set a new transform, getTransform() returns a copy.

Yeah I had already gotten rid of that, thank you though for noticing that, I now feel 100% justified in my deletion of it.

O_o since when did getTransform() return a copy?! I have never known it did :o

Well I was referring to this.

AffineTransform t = g.getTransform()

  • g.setTransform(new AffineTransform());

I was actually getting errors with the above two lines of code so I changed it to

AffineTransform t = g.getTransform();

Everything worked as intended then.

See if getTransform() == getTransform(). If it doesn’t, then it’s a copy. Otherwise, Graphics2D is implementing transforms by creating a new transform and setting it. I don’t think getTransform() is abstract so the easiest answer is to just ctrl-click and check the source.

getTransform() is actually implemented in SunGraphics2D, but the fact that it returns a copy is stated in the Javadoc for the method as well.

Nah I checked the javadoc and it says it returns a copy. Wow I never saw that before. :persecutioncomplex:

EDIT: LOL beaten by BoBear by 8 seconds :stuck_out_tongue: