Rotation um Bildmittelpunkt ohne Affine Transform!!!!!

Eichelhäer

Bekanntes Mitglied
Hallo zusammen,

seit längerem beschäftige ich mich mit der Strategiespielbewegung. Ich habe vor ein 2D Strategiespiel zu programmieren. Das ganze soll erstmal 2D aus der Vogelperspektive sein.

Im Moment habe ich schon die Bewegung ausgerechnet, d.h. es wird ein Panzer per JButton erzeugt, man kann diesen anklicken und ihn dann beliebig rumschicken.

Nur ist das etwas langweilig wenn dieser dabei ständig in die gleiche Richtung schaut. Deshalb habe ich mich mich Rotationen beschäftigt.

Fast überall wird auf "AffineTransform" verwiesen. Es ist unter anderem generell eines meiner Probleme, dass ich bei den meisten Funktionen oder anderen vorgefertigten Klassen keine Ahnung habe wie diese arbeiten und deshalb meistens nur durch rumprobieren und Quellcode umstellen oder Werte einsetzen dann zu einem Ergebnis komme.

So auch geschehen bei AffineTransform. Ich hatte schon ein beinahe zufriedenstellendes Ergebnis, aber mir fiel auf, dass was ich da geschrieben habe wirklich "Banane" war, also alles andere als guter Programmierstil.

Deshalb bin ich zur Mathematik gewechselt und siehe da habe auch gleich was gefunden.

Nun zu dem was ich machen will.

Also mein Panzer 20 auf 20 erscheint in einem Fenster. Man klickt ihn an und will ihn bewegen, d.h. man klickt irgendwo ins Fenster und er fährt los. Ich möchte aber, dass sich der Panzer zuerst in Bewegungsrichtung dreht und dann erst losfährt. Ich hoffe soweit klar!?!

Schließlich noch zu dem was ich bisher habe:

1. den Winkel Theta der von dem Panzer und der Maus eingeschlossen wird und
2. die neuen Koordinaten nach einer Drehung um den Winkel Theta. (Drehmatrix)
3. die Additionstheoreme (Formeln)

So blöd wie es klingt, aber ich habe ein Problem mit dem Anfangswinkel, also wenn das Bild das erste Mal gezeichnet wird. Ich weiß zwar, dass der 0 ist, aber dennoch muss ich ja nach meiner Vorstellung den ursprünglichen Bildvektor zu den neuen Koordinaten drehen. Ach ja, im Uhrzeigersinn und gegen den Uhrzeigersinn drehen, erreicht man durch invertieren der Vorzeichen in der Drehmatrix soweit ich noch weiß... .

Wäre schön, wenn mir jemand, der an dem Problem Interesse hat ein paar Tipps geben könnte.

Gruß Eichelhäer
 

Eichelhäer

Bekanntes Mitglied
Hallo,

danke für dein Interesse.

Ich rechne den Winkel zwischen Maus und Sprite mit dem einfachen atan aus.Es reicht schließlich erstmal der normale Arcustangens(Wie man es eben in der Schule gelernt hat). Ich habe deshalb einen anderen Ansatz:

mit der Formel bzw. Matrixformel:

x' = x * cos(angle) - y * sin(angle)
y' = x * sin(angle) + y * cos(angle)

Rechnet man die neuen Koordinaten nach der Rotation aus. Normalerweise dachte ich jetzt, dass man das x' bzw y' zu dem angle dazuaddieren müsste und dann die Additionstheoreme anwendet.

Also:

angle += x';
angle += y';

Und:

rx = Math.cos(startangle) * Math.cos(angle) + Math.sin(startangle) * Math.sin(angle);
ry
= Math.sin(startangle) * Math.cos(angle) + Math.cos(startangle) * Math.sin(angle);

Aber:

Was aber mach ich dann. Leider muss ich zu meiner Schande gestehen, dass ich vorher noch nie mit den Additionstheoremen gearbeitet habe und deshalb nicht genau weiß, was diese bewirken sollen für die Rotation.

Ich hoffe es ist jetzt etwas verständlicher.
 

InfectedBytes

Top Contributor
nope, der einfache atan reicht nicht, da dieser nur einen Wert erhält und somit nicht zwischen den verschiedenen Quadranten unterscheiden kann.
atan2 betrachtet hingegen die vorzeichen der einzelnen Werte und kann somit den quadranten angeben.
Beispiel: für atan2 ist die Eingabe (4, -2) eine andere als (-4, 2)
Für atan ist es die gleiche Eingabe, da 4/-2 = -2 = -4/2
 

Eichelhäer

Bekanntes Mitglied
Ja schon klar,

ich mach halt noch eine Fallunterscheidung, indem ich Deltax, also nur Deltax, auf negatives Vorzeichen teste. Ist halt mehr Arbeit, ist für mich aber logischer nachvollziehbar. Und die Bewegung in jeden Quadranten einschließlich 0,90 180 270 Grad funktioniert.
Genau so wie ich es mir überlegt habe.
 

InfectedBytes

Top Contributor
wo ist dann dein problem?
Wenn du den korrekten winkel hast. brauchst du nur noch die bewegung berechnen:
Java:
float speed = 10f;
float newX = oldX + cos(angle) * speed;
float newY = oldY + sin(angle) * speed;
 

Eichelhäer

Bekanntes Mitglied
Noch ein Nachtrag:

Wie heißt denn die korrekte mathematisch Bezeichnung für atan2?

Ich kenn nämlich neben dem Tangens nur noch den Arcustangens.

Mfg Eichelhäer
 

DrZoidberg

Top Contributor
Du musst nicht unbedingt mit Drehmatrizen und dem Additionstheorem arbeiten.
Du kannst auch die Winkel als double Werte speichern und dann einfach diese Werte addieren.
Aber ich versuch mal Drehmatrizen etwas näher zu erklären.
Eine solche Matrix representiert ein rotiertes Koordinatensystem.
Die linke Spalte stellt dabei die x-Achse und die rechte Spalte die y-Achse des Koordinatensystems dar.
Die beiden Spalten kann man also als Vektoren betrachten. Beide Vektoren haben eine Länge von genau 1, d.h. sie sind beide Einheitsvektoren.
Die linke Spalte (die x-Achse) ist gleich (cos(winkel), sin(winkel)) und die rechte (die y-Achse) ist (-sin(winkel), cos(winkel)).

Man kann nun einen Punkt drehen indem man ihn in dieses neue rotierte Koordinatensystem einträgt.
Wenn der Punkt die Koordinaten (px, py) hat, dann ist der rotierte Punkt gleich (px * x-Achse + py * y-Achse).
Mit anderen Worten: wir bewegen uns um px Einheiten in Richtung der x-Achse und um py Einheiten in Richtung der y-Achse.

Willst du eine Drehmatrix m1 mittels einer anderen Matrix m2 rotieren, drehst du einfach beide Vektoren aus denen m1 besteht jeweils mittels m2.
 

Eichelhäer

Bekanntes Mitglied
Hallo nochmal,

zunächst Mal ich habe es nicht hingebracht ohne AffineTransform, d.h. aber nicht, dass ich aufgeben werde. Danke für die Erklärung der Drehmatrix aber bei mir dreht sich nach zwei Tagen intensiver Beschäftigung alles aber nicht das PanzerSprite. :(

Nun möchte ich es doch erstmal mit der AffineTransform probieren. Zu meiner Schande muss ich gestehen, dass ich selbst das nicht ordnungsgemäß hinbekomme. Hier mal etwas Code:

public double directionradian(){
deltax = (MouseInput.mousx-tank.getWidth()/2) - centerX;
deltay = (MouseInput.mousy-tank.getHeight()/2) - centerY;

directionradian = Math.atan2(deltay,deltax);

return directionradian;
}

public double directiondegree(){
return directiondegree = Math.toDegrees(directionradian());
}

public double distance(){
distance = Math.sqrt(((deltax)*(deltax))+((deltay)*(deltay)));
return distance;
}

public void update(long delta){

tankbounding.x = (int) centerX;
tankbounding.y = (int) centerY;

if(distance()>speed){
centerX += Math.cos(directionradian())*speed;
centerY += Math.sin(directionradian())*speed;

}


}

public BufferedImage rotate(double angle){
AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(angle),tank.getWidth()/2,tank.getHeight()/2);
BufferedImage rotatedImage = new BufferedImage(tank.getWidth(),tank.getHeight(),tank.getType());
Graphics2D g2 = (Graphics2D) rotatedImage.getGraphics();
g2.setTransform(at);
g2.drawImage(tank,0,0,null);
return rotatedImage;
}

public double dreh(){

if(Display.clicked){


if(directiondegree()>0){
i++;
if(i>=directiondegree()){
i--;
Display.canmove = true;

}
}

else if(directiondegree()<0){
i--;
if(i<=directiondegree()){
i++;
Display.canmove = true;
}
else{
Display.canmove = false;
}
}
return i;
}

public void renderTank(Graphics g){

g.drawImage(rotate(dreh()),tankbounding.x,tankbounding.y, null);

}

Tut mir übrigens Leid der schlechte Programmierstil. Bin etwas überarbeitet.
Zum Problem:

Es würde mich interessieren, warum der erste Aufruf von directiondegree() einen Winkel von - 153.345... angibt und nicht 0 wie ich es eingestellt habe.

Erste Frage: Wie kann ich diesen Winkel von Anfang an auf 0 setzen?

Weitere Fragen folgen... .

Gruß Eichelhäer

PS: Falls DrZoidberg etwas Zeit hat, könnte er mir ein bisschen Code für die Rotation ohne Affine Transform folgen lassen. Wäre sehr hilfreich.:D
 

Eichelhäer

Bekanntes Mitglied
Hallo,

ich habe es nun endlich geschafft eine funktionierende Applikation zu bauen, in der eine Rotation eines aus einzelnen Linien bestehen Körpers um einen beliebigen Punkt mithilfe von Additiostheoremen und Drehmatrizen dargestellt wird.

Dazu muss man nur die einzelnen Eckpunkte des gewünschten Körpers berechnen und anschließend aus diesen Positionen die neuen Positionen mit der Drehmatrixformel jeweils für x und y berechnen.

In der paint-Methode dann führt man zuerst eine Tranlation mit g.translate durch dann malt man die gewünschten Linien und schließlich macht man die Tranlation wieder rückgängig. Damit sich auch auf dem Bildschirm was tut kann man z.B. den Drehwinkel um 1 erhöhen und die Rotation animiert darzustellen.

Wenn dieses Thema noch jemanden interessieren sollte poste ich auch noch den Code.

Wie das ganze bei Bildern z.B. PNG´s geht weiss ich noch nicht werde ich aber schon noch herausfinden.

Gruß


Eichelhäer
 

Tobse

Top Contributor
Ich muss hier aucnoch was loswerden:

@TE: du hast keine Ahnung, wie die Standard-Java-Klassen arbeiten? Schau doch einfach nach! AffineTransform
Du kannst mir nicht erzählen, dass ein Googlen nach "java AffineTransform" dich nicht auf diese Seite gebracht hätte.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
BraunBerry Rotation mit Radiusänderung Spiele- und Multimedia-Programmierung 0
BraunBerry Rotation von Objekten um ein Raumschiff Spiele- und Multimedia-Programmierung 6
RalleYTN LWJGL Rotation Spiele- und Multimedia-Programmierung 1
P Rotation von Sprite klappt nicht Spiele- und Multimedia-Programmierung 4
J Java 3d Rotation Spiele- und Multimedia-Programmierung 6
B j3d Rotation um mehr als eine Achse Spiele- und Multimedia-Programmierung 9
B j3d Kamera Rotation durch Tastendruck Spiele- und Multimedia-Programmierung 12
H Rotation auf Knopfdruck Spiele- und Multimedia-Programmierung 20
T [gelöst] Java3D: Unerwünschte Rotation um die 3.Achse vermeiden? Spiele- und Multimedia-Programmierung 3
W Rotation aller Objekte einer 3D-Szene Spiele- und Multimedia-Programmierung 8
V Jogl: Objekt trotz Rotation immer in gleiche Richtung bewegen Spiele- und Multimedia-Programmierung 5
E Tetris: Rotation der Tetrominos Spiele- und Multimedia-Programmierung 4
C Java3D Rotation um einen Punkt (y-achse) Spiele- und Multimedia-Programmierung 2
aze Transform3D - dauerhafte Rotation Spiele- und Multimedia-Programmierung 3
J Hilfe: Rotation X und Y Achse (Java3d) Spiele- und Multimedia-Programmierung 12
C JAVA3D Rotation um einen bestimmten Punkt Spiele- und Multimedia-Programmierung 20
"Er" Kamera rotation in Java3D Spiele- und Multimedia-Programmierung 2
R Tetris Rotation? Spiele- und Multimedia-Programmierung 7
P Figur Rotation Spiele- und Multimedia-Programmierung 14
G rotation eines würfels Spiele- und Multimedia-Programmierung 9
T Java3D: Rotation und Translation Spiele- und Multimedia-Programmierung 2
S Rotation relativ zur Rotation einer anderen Transform Group Spiele- und Multimedia-Programmierung 3
S Rotation um verschobene Achse Spiele- und Multimedia-Programmierung 7
Quaxli Java 3D - Rotation mit Alpha Spiele- und Multimedia-Programmierung 2
H Probleme bei Rotation Spiele- und Multimedia-Programmierung 9
P Rotation von BufferedImage (Affine Transformation) Spiele- und Multimedia-Programmierung 7
J Problem mit Rotation (Sprite3D) Spiele- und Multimedia-Programmierung 4
S Punkt berechnen, nach Rotation Spiele- und Multimedia-Programmierung 2
W Rotation eines Objektes Spiele- und Multimedia-Programmierung 2
W 3d-rotation Spiele- und Multimedia-Programmierung 4
A 2-Achsen Rotation eines Würfels Spiele- und Multimedia-Programmierung 4
E Programmierung eines 2.5D Point&Click Adventures ohne Spieleengine machbar? Spiele- und Multimedia-Programmierung 14
J Bild ohne Quallitätsverlust skalieren Spiele- und Multimedia-Programmierung 11
A 2D Spiel ohne Tiles Spiele- und Multimedia-Programmierung 10
S Mausklicks innerhalb eines JFrames/SWTBrowser ohne richtige Maus simulieren Spiele- und Multimedia-Programmierung 6
B Bild ohne Image auf die Festplatte streamen Spiele- und Multimedia-Programmierung 4
Devil0s 2D Stadt Generator/2D Welt speichern OHNE Tiles Spiele- und Multimedia-Programmierung 5
H zwei ints als key in map (ohne long) Spiele- und Multimedia-Programmierung 16
M Multiplayer Game mit Frontend auf HTML5 - ohne ständigen Client Request - Möglich?! Spiele- und Multimedia-Programmierung 12
S Sounds abspielen, ohne sie jedesmal neu zu laden Spiele- und Multimedia-Programmierung 8
B Bilder in GUI ändern ohne repaint() Spiele- und Multimedia-Programmierung 6
C java 3d ohne Java3d Spiele- und Multimedia-Programmierung 28
H Skalierung eines Polygons ohne das es verschoben wird Spiele- und Multimedia-Programmierung 3
K Java3D als Applet ohne Installation von Java3d Spiele- und Multimedia-Programmierung 6
M Eigene Renderengine ohne Java3D,etc. Spiele- und Multimedia-Programmierung 19
M Aktien-Spiel ohne GUI Spiele- und Multimedia-Programmierung 28
aze Java3D: Gegenstände aufeinander zubewegen ohne Kollision Spiele- und Multimedia-Programmierung 4
A JMF ohne Installation Spiele- und Multimedia-Programmierung 4
Developer_X Sound Lautstärke ohne spezifische API regulieren Spiele- und Multimedia-Programmierung 3
L JMF Player spielt mp3 nur ohne Ton Spiele- und Multimedia-Programmierung 14
M Binärbaum ohne Überlappung zeichnen Spiele- und Multimedia-Programmierung 3
T 3D-Tetris Feld neuzeichnen ohne neue Branchgroup Spiele- und Multimedia-Programmierung 18
O Java3D-Applet ohne Java3D-Runtime ausführen Spiele- und Multimedia-Programmierung 2
L klick auf ComboBox ohne ActionListener --> CPU ausgelaste Spiele- und Multimedia-Programmierung 13
H Tic Tac Toe / 3 Gewinnt OHNE Applet Spiele- und Multimedia-Programmierung 9
S 3D Objekte ohne Java3D darstellen? Spiele- und Multimedia-Programmierung 10
B Sudoku Generator ohne Solerver möglich? Spiele- und Multimedia-Programmierung 20
G Farbig zeichnen ohne java.awt.Color? Spiele- und Multimedia-Programmierung 5

Ähnliche Java Themen

Neue Themen


Oben