Applet Image Rotation Blues

Hello all!
I've managed to get my images rotating, but I've run into some trouble.
I am currently making a game involving a space ship. What I am working on is so that you can turn the ship and steer the ship, by rotating the image. However, I've run into a problem. When rotating an image, it rotates on an axis point located in the top left corner. In order to make it look like my ship is turning, I need the axis point to be in the middle of my ships image. I have no idea how to move this axis point. This is where I need help.


Here is my code, it's not long:

//////////////////////////////////////////////////////////////////////////////////////////////////////////
import java.awt.image.*;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.Random;
import java.lang.Thread;
import java.awt.geom.*;

public class SpaceBlast extends Applet implements Runnable, KeyListener, ActionListener, MouseListener
{
      
    Thread t;
    Graphics bufferg; //for future use with double buffering
    Image offscreen;
    double theta=0;      
    double x = 500;
    double y = 500;
    double scalex = .2;
    double scaley = .2;
    double shiftx = 0;
    double shifty = 0;
    double radians = -Math.PI/4;
    double rd=.17;
    boolean otherway;
      
      public void init()
      {   this.setLayout(null);
                     t=new Thread(this);
                     addKeyListener(this);
           t.start();            
           repaint();
                 }
      
      public void actionPerformed(ActionEvent e)
                {}
               public void keyPressed(KeyEvent e)
      {  
         if(e.getKeyChar()=='s')
          { rd-=.0001; }
         if(e.getKeyChar()=='a')
          { rd+=.0001; }
                 }
      public void keyReleased(KeyEvent e)
      {}
      public void keyTyped(KeyEvent e)
      {}
      public void mouseClicked(MouseEvent e)
                {}
                public void mouseReleased(MouseEvent e)
                {}
                public void mousePressed(MouseEvent e)
                {}
               public void mouseExited(MouseEvent e)
                {}
               public void mouseEntered(MouseEvent e)
               {}

      public void paint(Graphics g)
      {   Graphics2D g2d = (Graphics2D) g;
                     Image pic= getImage(getCodeBase(), "SD.gif");
                     AffineTransform tx = new AffineTransform();
   
                      tx.scale(scalex, scaley);
                      tx.shear(shiftx, shifty);
                      tx.translate(x, y);
       
                      radians = -Math.PI/rd;
       
                      tx.rotate(radians);
   
                      g2d.drawImage(pic, tx, this);
                      g.drawString(rd+"",10,10);

          
      }
      //public void update(Graphics g) //for later use with Double buffering
      //{ paint(g); }
      

      public void run()
      {  
          while(rd<2000){
          repaint();
                    try{t.sleep(150);}catch(Exception exc){}
            } ;
    }
}
/////////////////////////////////////////////////////////////

Thank you for your help!
I'm also kinda new to java, so please explain it the best you can.
Thanks!
PunkmanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

objectsCommented:
you need to translate by the image centre offset.
0
objectsCommented:
>  Image pic= getImage(getCodeBase(), "SD.gif");

no need to get image everytime you paint
do thisd instead in init().
0
objectsCommented:
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

CEHJCommented:
Try

tx.translate((int)(pic.getWidth() / 2 * scalex), (int)(pic.getHeight() / 2 * scaley));
0
objectsCommented:
Thought u didn't need to use AffineTransform :D
0
CEHJCommented:
You don't
0
objectsCommented:
But still u suggest using it, anyways that code won't work.

try using:

 tx.rotate(radians, xcentre, ycentre);

where xcentre and ycentre are the centre of the required rotation.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CEHJCommented:
>>But still u suggest using it

Only because it's already there
0
PunkmanAuthor Commented:
>>tx.rotate(radians, xcentre, ycentre);

Thanks objects, this works great!
How would I go about getting the center of the image though?

I tried using
(int)(pic.getWidth() / 2 * scalex), (int)(pic.getHeight() / 2 * scaley))

This should work.... but instead it rotates the picture by that top left corner again.
However, the >>tx.rotate(radians, xcentre, ycentre); does work with other, much higher numbers.

How do I go about making xcenter and ycenter the center of my image?
(the coord system for them seems off or something)
0
PunkmanAuthor Commented:
Ok, fixed it : )
It turns out that you don't need to take scalex and scaley into account, as it does that for you.
So the code is:
(int)(pic.getWidth() / 2), (int)(pic.getHeight() / 2)

Thanks!!

Ok, I've raised the points up a bit, as I have one final question.
I can now rotate my image around it's center point. But how would I go about moving my image in the direction it's facing?
0
PunkmanAuthor Commented:
Oh, and more importantly, How do I apply double buffering to this now that I am using:
Graphics2D g2d = (Graphics2D) g;    ?

I need to use both g and g2d in the game.

Thanks again : )
0
PunkmanAuthor Commented:
If the points are too low, I'll up them a bit if you want.
0
CEHJCommented:
Here's a working an example that spins an image round and moves it rightwards from the center having it reappear at the centre when it's moved out of view. Obviously you can use your own image to test it:

import java.awt.*;
import java.awt.image.*;
import javax.swing.*;

public class F extends JFrame implements Runnable {
  Image image;
  double theta, rotationFactor, delta;
  JPanel rotatorPanel;

  int deltaX, paintCount;

  private void setGui() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            // Choose image here
    ImageIcon icon = new ImageIcon("next.gif");
    image = icon.getImage();
    delta = 0.2f;
    rotatorPanel = new JPanel() {

      public void paintComponent(Graphics g) {
        g.clearRect(0, 0, getWidth(), getHeight());
        theta = Math.PI * rotationFactor;
        Graphics2D g2d = (Graphics2D)g;
        g2d.translate((int)(getWidth() / 2) + deltaX, (int)(getHeight() / 2));
        g2d.rotate(theta);
        g2d.drawImage(image, -(int)(image.getWidth(null) / 2), -(int)(image.getHeight(null) / 2), null);
      }

      public Dimension getPreferredSize() {
        return new Dimension(image.getWidth(null), image.getHeight(null));
      }
    };
    getContentPane().add(rotatorPanel);
  }

  public void run() {
    deltaX = -(int)(image.getWidth(null) / 2);
    for(;;) {
      rotationFactor -= delta;
      try {
        Thread.sleep(50);
        repaint();
        deltaX = (deltaX + 1) % getWidth();
      }
      catch(InterruptedException e) {
        /* ignore */
      }
    }
  }


  public static void main(String[] args) {
    F f = new F();
    f.setGui();
    f.pack();
    f.setVisible(true);
    new Thread(f).start();
  }
}


0
objectsCommented:
> It turns out that you don't need to take scalex and scaley into account

That is correct

> I can now rotate my image around it's center point.
> But how would I go about moving my image in the direction it's facing?

Maintain its x,y position and just translate transform matrix by that amount.
Use the current direction to change the x,y position.
 
> Oh, and more importantly, How do I apply double buffering to this now that I am using:
> Graphics2D g2d = (Graphics2D) g;    ?

Do all your painting of ship etc to the Graphics context of the image. bufferg can also be declared as a Gaphics2D.
And then paint that offscreen image to the screen in your paint method.

0
PunkmanAuthor Commented:
Thanks guys! The program now works and looks GREAT!! Thank you both!
0
CEHJCommented:
8-)
0
objectsCommented:
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.