Cant get AffineTransform to do what i want

Ok well i was playing around with images and attempted to create an isometric tile basically by rotating the image 45 degrees and scaling it’s y by 50%, sadly the original image would scale by half instead of when it is rotated, here is the code


package isometrictest;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.File;
import javax.imageio.ImageIO;
public class GUI extends JFrame{
    Image tile;
    JPanel pane;
    public GUI(){
        super("Isometric Test");
        try{
        tile = ImageIO.read(new File("C:/Users/Yosef/Documents/NetBeansProjects/isometricTest/grasstxt2.png"));
        }catch(Exception ae){
            ae.printStackTrace();
        }

        pane = new JPanel();
        getContentPane().add(pane);



    }
    @Override
    public void paint(Graphics g){
        Graphics2D g2 = (Graphics2D)g;
        AffineTransform tf = new AffineTransform();
        //AffineTransform tx = new AffineTransform();
        tf.translate(300, 0);
        tf.rotate(Math.toRadians(45));
        tf.scale(1d, 0.5d);
        g2.drawImage(tile, tf, pane);

    }
}

And this is what is happening:

Try reversing the order of your scale and rotate.

You sir or ma’am, ARE A GOD

When concatenating AffineTransforms, just remember that they are applied to the object in the opposite order as you put them together. If you want to rotate the sprite, scale it, then translate it, you want to construct it by AffineTransform.translate().scale().rotate().

ahh thanks, also im having a bit of an issue with the AffineTransform.scale() method…it seems to push the image up for no real reason. i know you can use the graphics2D class to scale but is there another way. Or maybe a way to get these displacments to be predictable?


package isometrictest;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.File;
import javax.imageio.ImageIO;
public class GUI extends JFrame{
    Image tile;
    JPanel pane;
    int width, height;
    int imgX = 200;
    int imgY = 200;
    int imgX2 = 500; //This is just for displacment of the second image to show you what i mean
    public GUI(){
        super("Isometric Test");
        try{
        tile = ImageIO.read(new File("C:/Users/Yosef/Documents/NetBeansProjects/isometricTest/grasstxt2.png"));
        width = tile.getWidth(pane);
        height = tile.getHeight(pane);
        System.out.println("Image Width: "+width + "\n"+"Image Height: " + height);

        }catch(Exception ae){
            ae.printStackTrace();
        }

        pane = new JPanel();
        getContentPane().add(pane);

    }
    @Override
    public void paint(Graphics g){
        Graphics2D g2 = (Graphics2D)g;
        AffineTransform tf = new AffineTransform(); //First image's AffineTransform
        AffineTransform tx = new AffineTransform(); //Second image's AffineTransform

        tf.scale(1, 1);
        tf.rotate(Math.toRadians(45), imgX+width/2, imgY+height/2);
        tf.translate(imgX, imgY);

        g2.drawImage(tile, tf, pane);

        tx.scale(1, 0.5);
        tx.rotate(Math.toRadians(45), imgX2+width/2, imgY+height/2);
        tx.translate(imgX2, imgY);
        g2.drawImage(tile, tx, pane);
    }
}

Here is a visual picture of what is happening, the left one is without a scale and the second one has a 0.5 scale on the Y axis

This will do what you want (assuming you want the center of the scaled, rotated image at imgX,imgY)


        tx.translate(imgX-width/2, imgY-height/2+height/4);
       	tx.scale(1,0.5);
        tx.rotate(Math.toRadians(45),width/2, height/2);
        g2.drawImage(tile, tx, pane);

This is a fiddle which will only work in this case, ie: if you want isometric.
Read up on AffineTransform if you need to do more!

Scaling moves all points closer to the origin, the 0,0 point. So if the image is not centered the way you want, it will also “move” it closer to 0,0