Shapes rotieren

junior0007

Grünschnabel
Hallo!

Ich versuche mich gerade an einem kleinen Tetris. Soweit läuft alles ganz gut - nur die Rotation klappt nicht. Ich würde gern die Shapes an sich nicht verändern, deshalb wird ein Shape über ein Polygon definiert, und dann mittels AffineTransform an die entsprechende Stelle geschoben. Die Rotation soll über die selbe Transformationsmatrix gemacht werden.
Das verschieben klappt, aber die Rotation geht leider überhaupt nicht.
Hier mal die wesentlichen Teile:

Das hier geht scheinbar:
Code:
AffineTransform trans = new AffineTransform();

/* Teil nach rechts verschieben */
public void moveRight(int steps)
{      
         //breite des Polygons
	double breite = getBounds().getWidth(); 
         // wohin soll verschoben werden
	double posX = trans.getTranslateX() + breite;
	
        double dx; 
        
        // falls zu Nah am Rand...
	if(posX+steps > GameController.WIDTH)
	{
                 // verschiebe bis zum Rand
		dx = GameController.WIDTH - posX;
	}
	else
	{
                 // verschiebe mit Std_wert
		dx = steps;
	}
        // translation auf Matrix schreiben
	trans.translate(dx, 0);
}

Das hier nicht:
Code:
/* rotation um Mittelpunkt */
public void rotate(int angle_deg)
{
	double angle_rad = Math.toRadians(angle_deg);
	Rectangle2D r = getBounds();
	trans.rotate(angle_rad, r.getCenterX(), r.getCenterY());
}

und gezeichnet wird das ganze dann so:
Code:
public void paint(Graphics2D g)
{
	super.paint(g);
	Shape s = trans.createTransformedShape(shape);
	g.fill(s);
}

Ist das überhaupt der richtige (od. ein sinnvoller) Ansatz? Warum geht die Translation aber nicht die Rotation?

Gruß
Junior0007
 
Danke ich weiß schon wo ich Mist gebaut habe. Durch die Rotation wird die danachfolgende translation auch beeinträchtigt. Hätte man auch selbst draufkommen können :-(
Warum gar nichts mehr ging weiß ich zwar immernoch nicht, aber jetzt gehts.

Wenn mir jetzt noch jemand sagt, ob das sehr ungeschickt ist mit 3 Matrizen zu arbeiten bzw. welche besser Idee es gibt bin ich schon glücklich. Ich verwende jetzt erst mal eine für die Translation, eine für die Rotation und eine, die die beiden zum Zeichnen mixed...

Da muss es doch eine schönere Lsg geben... :confused:

Vlt weiht mich ja noch mal jemand ein :-)

Gruß
Junior0007
 
Hallo!

Schau doch mal hier:
Code:
  /**
   * 
   */
  package de.tutorials;
  
  import java.awt.Graphics2D;
  import java.awt.Image;
  import java.awt.event.KeyAdapter;
  import java.awt.event.KeyEvent;
  import java.awt.geom.AffineTransform;
  import java.awt.image.BufferStrategy;
  import java.io.File;
  import java.io.IOException;
  
  import javax.imageio.ImageIO;
  import javax.swing.JFrame;
  
  /**
   * @author Tom
   * 
   */
  public class SimpleRotationExample extends JFrame {
  
  	final static int SCREEN_WIDTH = 640;
  
  	final static int SCREEN_HEIGHT = 480;
  
  	BufferStrategy bufferStrategy;
  
  	boolean leftPressed;
  
  	boolean rightPressed;
  
  	boolean upPressed;
  
  	boolean downPressed;
  
  	Image image;
  
  	int x = 320 - 21, y = 240 - 21;
  
  	double theta;
  
  	AffineTransform transform;
  
  	Thread runner = new Thread() {
  		public void run() {
  
  			while (true) {
  
  				if (upPressed) {
  					y -= 4;
  				}
  				if (downPressed) {
  					y += 4;
  				}
  
  				if (leftPressed) {
  					x -= 4;
  				}
  
  				if (rightPressed) {
  					x += 4;
  				}
  
  				theta = theta + 0.25D;
  
 		 	transform = AffineTransform.getRotateInstance(theta, x + 21, y);
  
 		 	Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
  				g.setTransform(transform);
 				g.clearRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
 				g.drawImage(image, x, y - 21, null);
  				g.dispose();
  				bufferStrategy.show();
  				try {
 					sleep(25L);
 				} catch (InterruptedException e) {
 					e.printStackTrace();
  				}
  			}
  		}
  	};
  
  	public SimpleRotationExample() {
  		super("SimpleRotationExample");
  		setDefaultCloseOperation(EXIT_ON_CLOSE);
  
  		setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
  		setVisible(true);
  
  		try {
  			image = ImageIO.read(new File("c:/arrow.png"));
  		} catch (IOException e) {
  			e.printStackTrace();
  			System.exit(-1);
  		}
  
  		addKeyListener(new KeyAdapter() {
  			public void keyPressed(KeyEvent e) {
 				if (e.getKeyCode() == KeyEvent.VK_LEFT) {
 					leftPressed = true;
  				}
 				if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
 					rightPressed = true;
  				}
 				if (e.getKeyCode() == KeyEvent.VK_UP) {
 					upPressed = true;
  				}
 				if (e.getKeyCode() == KeyEvent.VK_DOWN) {
 					downPressed = true;
  				}
  
 				if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
 					System.exit(0);
  				}
  			}
  
  			public void keyReleased(KeyEvent e) {
 				if (e.getKeyCode() == KeyEvent.VK_LEFT) {
 					leftPressed = false;
  				}
 				if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
 					rightPressed = false;
  				}
 				if (e.getKeyCode() == KeyEvent.VK_UP) {
 					upPressed = false;
  				}
 				if (e.getKeyCode() == KeyEvent.VK_DOWN) {
 					downPressed = false;
  				}
  			}
  		});
  
  		createBufferStrategy(2);
  		bufferStrategy = getBufferStrategy();
  		runner.start();
  	}
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) {
  		new SimpleRotationExample();
  	}
  
  }

Gruß Tom
 

Anhänge

  • arrow.png
    arrow.png
    2,2 KB · Aufrufe: 144
Hallo Tom!

Danke erst mal! Es scheint also auch, wie vermutet, mit nur einer Tranformationsmatrix zu gehen.

Leider ist die Lsg so nicht für Shapes anwendbar, weil es eine Methode wie
Code:
	g.drawImage(image, x, y - 21, null);

für Shapes nicht gibt :( zumindest nicht laut meiner IDE...
Gibt es noch ne weitere Möglichkeit das Polygon "anständig" zu zeichen?

Danke
Gruss
Junior0007
 
Zurück