Search code examples
javarotationbufferedimagecut

Java rotated buffered image gets cut off


Firstly, I am trying to make a simple game in Java. I have a viewport that shows a tile map and I have a tank in the middle that moves by controlling the JScrollBars of the scrollpane in which the viewport resides in. So far everything has been going well, until I needed to rotate an image. Here is a picture of the game: Note: the tank body and tilemap are on seperate panels and do not share the same graphics.

Picture of non rotated tank body:

https://i.sstatic.net/IqeEA.png

Essentially, I want to rotate a buffered image around its center (rotating in place) using arrow keys. I already have the code for the keys, and I also have a method to try and rotate the buffered image given a buffered image and angle in degrees (the angle is changed to radians in the method). This method will return a buffered image that is rotated correctly. Here is the code:

public static BufferedImage rotateImage(BufferedImage image, double angle) {
        if(angle == 0)
            return image;
        else {
            
            angle = Math.toRadians(angle);
            double x = Math.abs(Math.cos(angle));
            double y = Math.abs(Math.sin(angle));
            int newWidth = (int) Math.floor(image.getWidth()*x + image.getHeight()*y);
            int newHeight = (int) Math.floor(image.getHeight()*x + image.getWidth()*y);
            
            BufferedImage rotated = new BufferedImage(newWidth, newHeight, image.getType());
            Graphics2D tool = rotated.createGraphics();
            
            AffineTransform transformer = new AffineTransform();
            transformer.rotate(angle, image.getWidth()/2, image.getHeight()/2);
            tool.drawImage(image, transformer, null);
            tool.dispose();
            
            return rotated;
        }   
    }

However, as the title suggests, the image gets cut off at the top and left sides of the image when rotated as shown:

Picture of rotated tank body:

https://i.sstatic.net/HUpyL.png

So I have looked at many different forums but I could not solve my problem. I could add whitespace around the image, but that interferes a lot with collision detection which I plan to do later on. I know that it has to do something with the original display being smaller than the display of the rotated image, and I have tried to translate accordingly in many ways. If I translate with this line of code specifically,

transformer.translate((newWidth - image.getWidth())/2, (newHeight - image.getHeight())/2);

Then the image (tank body) rotates without cutting, but bounces out of place as shown (I drew a rectangle to show where it was):

Picture of rotated tank with translation:

https://i.sstatic.net/ZJ4UC.png

I also have tried negating the translations too but it only avails to funky movements.

So, I really have no clue how to solve this, and I have been spending too much time on this problem. I would really appreciate a helpful answer that directly edits my method if possible.


Solution

  • Answer

    So here is the opening idea that I needed to realize to answer this problem. The method to translate and rotate is meant so that the image is not cut off. However, it won't be around the center as intended as seen in the 3rd picture. But again, the method is not intended to recenter it. The painting code itself needs to account for this shift. I simply added variables to account for this:

    xOffset = (newWidth - image.getWidth())/2;

    yOffset = (newHeight - image.getHeight())/2

    And simply subtracted these from where I was painting the tank's body.

    Thanks to @camickr for the solution