2D-Grafik Shapes auf Zeichenfläche gleichmäßig verschieben

Sascha_S

Mitglied
Hallo, ich hoffe, dass ich mit meiner Frage hier an der richtigen Stelle bin. Ich habe schon tagelang gegoogelt und rumprobiert, aber irgendwie steh ich auf dem Schlauch.

Ich möchte gern ein bzw. mehrere Shape-Objekte von einer Position auf meiner Zeichenfläche zu einer anderen (diese wird per Mausklick bestimmt) verschieben. Die Verschiebung soll mit einer konstanten Geschwindigkeit entlang einer Geraden von Start- zu Zielpunk geschehen. Eigentlich sollte das doch nicht so schwer sein, oder? ???:L

Mein derzeitiger Ansatz ist, dass ich zunächst die Differenz der X- und X-Werte der aktuellen Position und der neuen Zielposition bestimme. Dann berechne ich mit Hilfe dieser Werte die Distanz, die mein Shape Objekt zurücklegen wird (Hypotenuse des Dreiecks, Länge des Vektors, wie auch immer man es nennen will). Jetzt teile ich diese Länge durch einen festen Wert, dieser Wert representiert die Geschwindigkeit mit der sich das Objekt bewegen soll. Dadurch erhalte ich einen Wert der mir angibt, wieviel der Strecke mein Objekt pro Zeiteinheit zurück legt. Jetzt dividiere ich die relativen X- und Y-Werte durch diesen neuen Wert, um mit deren Hilfe die neue Position des Shape-Objekts nach der aktuellen Zeiteinheit berechnen zu können. Die einzelnen Zeiteinheiten durchlaufe ich in einem Thread und nähere mich so immer weiter der Zielposition. (Oh man, ich hoffe ich konnte das halbwegs vernünftig ausdrücken.)

Soweit die Idee. Das funktioniert auch mehr oder weniger gut. Das Problem ist aber, dass das Objekt von seiner Linie (teilweise recht stark) abweicht. Dadurch wird irgendwann der Kurs korrigiert und das Objekt "schlägt einen Hacken". So kommt das Objekt zwar am Ende an seiner Position an, aber halt nicht ganz so, wie ich mit das vorgestellt hatte.

So sieht das dann aus:
movingsquare.png

Bild

Hier noch mal die Implementierung("rot" ist die Hauptklasse in der gezeichnet wird usw.):
Java:
class RefreshThread extends Thread {
	Rotating rot;

	public RefreshThread(Rotating rot) {
		this.rot = rot;
	}

	public void run() {
		
		double distanceX;
		double distanceY;
		double distance;
		int speed = 2;

		while (true) {
			try {
				sleep(15);
				if (rot.currentX != rot.targetX || rot.currentY != rot.targetY) {
					distanceX = rot.targetX - rot.currentX;
					distanceY = rot.targetY - rot.currentY;
					System.out.println("a = " + distanceX);
					System.out.println("b = " + distanceY);
					distance = Math.sqrt(distanceX*distanceX + distanceY*distanceY);
					System.out.println("c = " + distance);
					double factor = distance/speed;
					System.out.println("factor = " + factor);
					rot.currentX =  rot.currentX + new Double(distanceX / factor).intValue();
					rot.currentY =  rot.currentY + new Double(distanceY / factor).intValue();
					System.out.println(rot.currentX + ";" + rot.currentY);
				}				
			} catch (InterruptedException e) {
			}
			rot.doRepaint();
		}
	}
}


Woran könnte das liegen? Was mache ich falsch? Sind das nur Rundungsfehler? Wie kann ich das vermeiden? Fragen über Fragen :p

Danke schonmal für die Hilfe :)
 
G

Gast2

Gast
1. Double.valueOf benutzen
2. while(true) ist nie gut und birgt die Gefahr einer endloschleife
3. solltest du rot.repaint() aufrufen und diesen zum EDT synchronisieren
4. deine Rechnung hab mir ejtzt nicht angeschaut aber einmal hantierst du mit int rum und einmal mit double da kann es schon zu rundungsfehler kimmen
 

Sascha_S

Mitglied
Zu 1. und 4.) Okay, vielen Dank für die schnelle Hilfe! Problem gelöst, funktioniert jetzt super :D. Es lag offensichtlich wirklich nur an meinem Integer-Double-Mix und den daraus resultierenden Rundungsfehlern.

Zu 2.) Ich hab das while==true rausgenommen und durch ein Boolean ersetzt, welches die Schleife stopt, sobald das Objekt am Ziel angekommen ist. Ich starte jetzt immer einen neuen Thread sobald wieder ein neues Ziel angegeben wird.

Frage: Ist das auch besser so, wenn ich noch andere sich bewegende Objekte habe? Dann würde ich bei, sagen wir mal 5, sich bewegenden Objekten 5 Threads starten, anstatt einen Thread zu haben, der immer läuft. Gibt es noch andere Lösungsmöglichkeiten? ???:L

Zu 3.) Ich rufe jetzt repaint direkt auf (keine Ahnung, warum ich das vorher über eine extra Methode gemacht habe). Aber was genau meinst du mit synchronisieren? Irgendwie habe ich das mit dem Event Dispatcher Thread anscheinend noch nicht so recht verstanden :(

Hier nochmal der neue Code des Threads:
Java:
class RefreshThread extends Thread{
	Rotating rot;
	private boolean flag;

	public RefreshThread(Rotating rot) {
		this.rot = rot;
		flag = true;
	}

	public void hold() {
		flag = false;
	}

	public void run() {
		double distanceX;
		double distanceY;
		double distance;
		int speed = 2;
		while (flag == true) {
			System.out.println("running");
			try {
				sleep(15);

				if (rot.rect.getX() < rot.targetX - 1
						|| rot.rect.getX() > rot.targetX + 1
						|| rot.rect.getY() < rot.targetY - 1
						|| rot.rect.getY() > rot.targetY + 1) {
					distanceX = rot.targetX - rot.rect.getX();
					distanceY = rot.targetY - rot.rect.getY();
					System.out.println("a = " + distanceX);
					System.out.println("b = " + distanceY);
					distance = Math.sqrt(distanceX * distanceX + distanceY
							* distanceY);
					System.out.println("c = " + distance);
					double factor = distance / speed;
					System.out.println("factor = " + factor);
					rot.rect.setRect(rot.rect.getX() + distanceX / factor,
							rot.rect.getY() + distanceY / factor,
							rot.objectSize.getWidth(),
							rot.objectSize.getHeight());
					System.out.println(rot.rect.getX() + ";" + rot.rect.getY());
				} else {
					flag = false;
				}

			} catch (InterruptedException e) {
			}
			rot.repaint();
		}
	}
}
 
G

Gast2

Gast
Über ein flag ist besser.
kann übrigens auch einfach nur
Code:
while (flag)
schreiben.

Mit synchroniseren mein, dass Zeichenoprtationen nur im EDT laufen dürfen.
Es gibt einige Methoden die sind von Haus aus synchronisert wenn man diese aufruft steht manchmal in der API ;) bei repaint weiß ich es nicht musst mal n der API schauen
Ansonsten synchronisieren.

SwingUtilities#invokeLater ist das Stichwort ;)
 

Sascha_S

Mitglied
ahja, danke euch beiden. ich hatte leider noch keine zeit weiter rumzuprobieren, aber prinzipiell funktionierts jetzt schon so wie's soll. vielleicht meld ich mich nochmal, wenn es noch probleme gibt, aber danke für die schnelle und professionelle hilfe :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 Buttons und Shapes sehen ja nach Screengröße klein oder zu groß aus, jemand eine Idee, was man tun kann? AWT, Swing, JavaFX & SWT 1
M Java FX größe der shapes anpassen AWT, Swing, JavaFX & SWT 0
J JavaFX Shapes (Line) erweitern AWT, Swing, JavaFX & SWT 11
J JavaFX Intersect Problem mit Shapes AWT, Swing, JavaFX & SWT 10
S Irgendwie verstehe ich die Winding-Rules bei Shapes nicht :( AWT, Swing, JavaFX & SWT 4
M Swing Shapes setzen AWT, Swing, JavaFX & SWT 4
M 3D-Grafik Denkfehler bei Verschieben von Shapes AWT, Swing, JavaFX & SWT 0
P Swing Shapes in der richtien reihen folge ? AWT, Swing, JavaFX & SWT 3
P Swing Dynamisch zeichnen mit Shapes wie Rectangle2D.Float ? AWT, Swing, JavaFX & SWT 6
4 Shapes Informationen wie Breite usw. mitgeben AWT, Swing, JavaFX & SWT 5
N Zusammenfügen von Shapes AWT, Swing, JavaFX & SWT 8
S Wie detektiere ich am schnellsten ob sich 2 Shapes ueberlappen oder nicht? AWT, Swing, JavaFX & SWT 3
L JFreeChart - Line Shapes AWT, Swing, JavaFX & SWT 15
F [Java 1.5] Shapes auf einem JPanel zoomen AWT, Swing, JavaFX & SWT 11
J Swing Zeichenfläche im JPanel des Haupfenster anzeigen lassen AWT, Swing, JavaFX & SWT 4
O 2D-Grafik Zeichenfläche auf JPanel AWT, Swing, JavaFX & SWT 4
S JavaFX Canvas - nur eine Figur auf der Zeichenfläche färben? AWT, Swing, JavaFX & SWT 1
propra Objekte auf Zeichenfläche verschieben AWT, Swing, JavaFX & SWT 2
propra 2D-Grafik Beliebig viele Objekte auf einer Zeichenfläche zeichnen AWT, Swing, JavaFX & SWT 15
data89 Verbindungslinien zwischen Formen auf einer "Zeichenfläche" AWT, Swing, JavaFX & SWT 2
K keine Zeichenfläche sichtbar AWT, Swing, JavaFX & SWT 2
E Komponenten auf Zeichenfläche gruppieren u. verschieben AWT, Swing, JavaFX & SWT 3
G Zeichenfläche, Probleme AWT, Swing, JavaFX & SWT 4
G Runde Zeichenfläche AWT, Swing, JavaFX & SWT 4
K Zeichenfläche in einem JPanel? AWT, Swing, JavaFX & SWT 4
M Canvas, JPane bzw. JFrame als Zeichenfläche AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben