简体   繁体   中英

How to rotate a bitmap with AffineTransform

I'm trying to create a simple program that displays a bitmap zombie picture and then rotates it around using AffineTransform and Thread. I followed the example I had to accomplish this, but whenever I run the program the zombie bitmap just rotates once and stops. Also, for some reason when I painted the zombie bitmap, the image is partially off the screen along the y-axis.

So my questions are: why is the bitmap not rotating and why is the bitmap off the screen.

Code is as follows:

import java.awt.*;// Graphics class
import java.awt.geom.*;
import java.net.*;//URL navigation
import javax.swing.*;//JFrame
import java.util.*;//Toolkit

public class BitMapZombies2 extends JFrame implements Runnable
{
    private Image zombieOneRight;
    Thread zombieRun;


    public static void main (String[] args)
    {
        new BitMapZombies2();
    }

    public BitMapZombies2()
    {
        super("Bit Map Zombies..RUN FOR YOUR LIFE!!!");
        setSize(800,600);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Toolkit Zkit = Toolkit.getDefaultToolkit();

        zombieOneLeft = Zkit.getImage(getURL("_images/_production_images/zombie_1_left_75h.png"));
        zombieOneRight = Zkit.getImage(getURL("_images/_production_images/zombie_1_right_75h.png"));

        zombieRun = new Thread(this);
        zombieRun.start();

    }

    AffineTransform zombieIdentity = new AffineTransform();

    private URL getURL(String filename)
    {
        URL url = null;
        try
        {
            url = this.getClass().getResource(filename);
        }
        catch (Exception e) {}
        return url;
    }

    public void paint(Graphics z)
    {
        Graphics2D z2d = (Graphics2D) z;
        AffineTransform ZombiePowered = new AffineTransform();

        z2d.setColor(Color.BLACK);
        z2d.fillRect(0,0, 800, 600);

        ZombiePowered.setTransform(zombieIdentity);
        ZombiePowered.rotate(2,37.5,37.5);
        z2d.drawImage(zombieOneRight,ZombiePowered,this);
    }

    public void run()
    {
        Thread zT = Thread.currentThread();
        while (zT == zombieRun)
        {
            try
            {

                Thread.sleep(500);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }

            repaint();
        }
    }


        }

Appreciate any help I can get on this.

Once you've created your transformation, you need to apply it to the graphics context...

public void paint(Graphics z)
{
    //...
    z2d.setTransform(ZombiePowered);
    //...
}

Once you apply a transformation, it will effect everything painted to the Graphics context after it so you need to reset it or referse it. There's lots of ways to do this, but the simplest would be to create a copy of the Graphics context and simply dispose of it when you no longer need it...

public void paint(Graphics z)
{
    Graphics2D z2d = (Graphics2D) z.create();
    //...
    z2d.dispose();
}

Also, this is just me, but I'd be creating a new instance of the AffineTransform , these things are to easy to completely screw up...

Commenting your code:

    AffineTransform ZombiePowered = new AffineTransform();//Create an Id. transform
    ZombiePowered.setTransform(zombieIdentity);//Set it as a copy of an Id. transform
    ZombiePowered.rotate(2, 37.5, 37.5);//Concatenate the rotation with the Id. transform
    z2d.drawImage(zombieOneRight, ZombiePowered, this);//Apply the rotation

So your always rotating 2rads your image. If you do this assignment at the end of the paint method:

            zombieIdentity = ZombiePowered; 

the next time you paint the image it will be rotate 2rads more. About the issues with the position, take a look at rotate javadoc:

Concatenates this transform with a transform that rotates coordinates around an anchor point. This operation is equivalent to translating the coordinates so that the anchor point is at the origin (S1), then rotating them about the new origin (S2), and finally translating so that the intermediate origin is restored to the coordinates of the original anchor point (S3).

This operation is equivalent to the following sequence of calls:

  translate(anchorx, anchory); // S3: final translation rotate(theta); // S2: rotate around anchor translate(-anchorx, -anchory); // S1: translate anchor to origin 

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM