Graphics2D - Bild bewegen (ev. mehr mathematisches Problem)
-
Das erklärt so einiges oO
Aber ich glaub ich habe noch immer ein gewaltiges Brett vorm Kopf, denn
folgendes ergibt noch immer nicht 3 oOprivate void CalcStdSinCos() { System.out.println("3 * cos(90) = " + 3*Math.cos(Math.toRadians(90))); System.out.println("3 * cos(270) = " + 3*Math.cos(Math.toRadians(270))); System.out.println("3 * sin(0) = " + 3*Math.sin(Math.toRadians(0))); System.out.println("3 * sin(180) = " + 3*Math.sin(Math.toRadians(180))); }
Sondern folgendes:
3 * cos(90) = 1.8369701987210297E-16 3 * cos(270) = -5.51091059616309E-16 3 * sin(0) = 0.0 3 * sin(180) = 3.6739403974420594E-16
Edit:
Bzw. 3 und -3
Denn bei φ 90° müsste die Y-Koordinate bei 0 liegen und X bei 3
Bei 270° hingegen müsste X = -3 seinBei φ 0° müsste X-Koordinate bei 0 liegen und Y bei 3 und eben umgekehrt
bei 180° müsste X-Koordinate ebenfalls 0 und Y bei -3 liegen.Oder hab ich das Grundprinzip missverstanden?
-
Die Werte sind schon richtig, denn sie sollen alle 0 ergeben - und nicht 3.
Dank Floating-Point-Arithmetik kommt es bei deinen Testwerten zu Ungenauigkeiten. Der erste Wert 1.8369701987210297E-16 ist nämlich z. B. 0.00000000000000018369701987210297.
Da du die Zahlen am Ende sowieso in ganze Pixel umrechnest, sollte das aber vernachlässigbar sein.
-
Interessant...
Ich stellte mir das so vor, dass wenn ein Winkel von 90° herrscht, r = Y sei
Aber dem wäre ja nicht so, wenn Y = 0 wäre...Ich gehe nämlich noch immer von der Umrechnung der polarkoord. in kartesische
aus.Und da steht (ja, habe eine Schulmitschrift hervorgekramt) folgendes:
In allen 4 Quadranten gilt:
x = r * cosφ
y = r * sinφDa r = Abstand zum Pol ist, sollte das doch eigentlich heißen, dass Y = r ist,
wenn φ = 90° - folglich müsste sin 90° = 1 ergeben oder?Nehmen wir mal an ich denke hier komplett daneben und mein Matheprof. war ein
Schwachkopf (sorry, falls er das lesen sollte ^^) - Wie mache ich es dann richtig?Edit:
Um fair zu bleiben, veränder ich die Aussage:
Entweder denke ich komplett daneben und bin ein mathematischer Schwachkopf, oder mein Matheprof war ein Schwachkopf xD
Fairness muss schon gelten, wenn schon der Rest der Welt nicht fair ist
-
x und y sind relativ zu einem Ursprung, z. B. (0, 0). Genauso sind es r und φ.
Das heißt, deine Formel rotiert einen Punkt (x, y) um den Ursprung (0, 0) mit dem Radius r und dem Winkel φ. Wenn du um einen anderen Punkt rotieren willst, musst du x und y als Offset zu diesem Punkt nehmen.
Folgendes Beispiel rotiert einen Punkt um den Ursprung mit dem Radius r=3 in 90°-Schritten:
public static void main (String[] args) { double r = 3; for (double a = 0; a <= 360; a += 90) System.out.format("%.0f deg: x=%.2f y=%.2f\n", a, x(r, a), y(r, a)); } static double x(double r, double a) { return r*Math.cos(Math.toRadians(a)); } static double y(double r, double a) { return r*Math.sin(Math.toRadians(a)); }
Ausgabe:
0 deg: x=3.00 y=0.00 90 deg: x=0.00 y=3.00 180 deg: x=-3.00 y=0.00 270 deg: x=-0.00 y=-3.00 360 deg: x=3.00 y=-0.00
-
Sorry, ich glaube, meine letzte Antwort geht etwas am Problem vorbei, denn du willst ja nicht rotieren, sondern dein Bild in die Richtung bewegen.
Muss ich nochmal genauer gucken...
-
Danke, ein Licht ist aufgegangen...
Am besten ich such mir die Adresse des Matheprofs raus und bring ihm nen guten
Wein - Ich frage mich wie er mich ausgehalten hatDanke noch mals *virtuellen Wein überreich*
Edit
Dein Rotationsbeispiel hat bei mir ein Licht aufgehen lassen ^^ Sozusagen alte,
verstaubte Erinnerungen hervorgeholt ^^Ich musste lediglich bei CalcY() den Returnwert invertieren. Ob dies jedoch
notwendig ist, auf Grund von Folgefehlern in meinem weiteren Programm, oder ob
es so korrekt ist, müsst ich mir noch ausrechnen. Aber jetzt weiß ich immerhin
wieder wie
-
Ja, passt doch:
x' = x + r * cos(φ)
y' = y + r * sin(φ)Mit (x, y) = Alte Position, (x', y') = Neue Position, r = Schrittweite und φ = Guckrichtung.
Achte darauf, dass du die aktuellen Koordinaten intern als float oder double speicherst und erst beim Rendern in ganzzahlige Pixelkoordinaten umrechnest/rundest. Sonst kommst du bei kleinen r-Werten nicht vom Fleck, bzw. läufst nicht in die exakte Richtung.
-
Danke, werd ich mir gleich in die Notizen schreiben.
Ich fang nämlich erst grad mit Graphics2D an, in Hinblick auf ein geplantes,
nächstes Projekt.Aber bevor ich mir überhaupt großartig Gedanken über ein Projekt mache (bis auf
die Fragen: Was? Und mit was setze ich es um?) muss ich in Graphics2D und wie
ich merke vorallem auch Trigonometrie meine Kenntnisse auffrischen.Aber ich habe ja Zeit, mein derzeitiges Projekt ist erst in der Betaphase und
da is noch einiges an Arbeit vor mir.Danke noch mals für die Hilfe.
-
Dazu ein Beispiel:
Angenommen, du befindest dich bei (x, y) = (3, 2) und willst (mehrfach hintereinander) 1px in Richtung 30° gehen. Dann bekommst du für (dx, dy) die Werte (0.87, 0.50).
Wenn du nun nach int castest, kommst du nicht vom Fleck, da die Nachkommastellen abgeschnitten werden und du dich um (0, 0) bewegst. Wenn du hingegen rundest kommt (1, 1) raus und du bewegst dich in 45°-Richtung.
Rechne stattdessen mit float-Koordinaten, sodass sich Nachkommastellen akkumulieren und beim Rendern die Pixel-Koordinaten im richtigen "Rhythmus" weiterschalten.
-
Das hab ich so gar nicht bedacht, aber wenn ich dass so lese is es nicht nur
einleuchtend, sondern einfach nur logisch.Das werd ich mir wohl rot und mit dicker Schrift hinterlegen