Punkt weiterrotieren - wie?
-
Hi,
einen Kreis mit einem gegebenen Radius r und einem Mittelpunkt cx,cy zu berechnen ist relativ simpel:
x=cx+r*cos(winkel); y=cy+r*sin(winkel);
Wenn "winkel" einfach immer ein Stückchen vergrößert wird, ergibt das einen Punkt x,y, der um cx,cy rotiert.
Jetzt habe ich aber das Problem, dass ich einen Mittelpunkt cx,cy habe und einen Punkt x,y, welcher sich schon in einem Abstand zum Mittelpunkt befindet, und einfach um einen gewissen Winkel weitergedreht werden soll.
Wie geht das? Der Radius ist dann einfach der Abstand zwischen den beiden Punkten. Aber wie berechne ich, an welcher Position (welchem Winkel) sich der Punkt x,y befindet und wie drehe ich diesen dann weiter?
-
Schau dich mal um nach Polarkoordinaten - den Winkel kannst du über den Arcus-Tangens ausrechnen.
-
Mit ein bisschen Matrix-Vektor-Zauberrei geht das ganz einfach:
Punkt (x0, y0), Mittelpunkt (xc,yc) und Winkel ω um den weitergedreht werden soll.
Erstmal beide Punkt verschieben, so dass der Mittelpunkt zu (0,0) wird, also von beiden (xc,yc) abziehen.
Der neue Punkt ist dann (x0-xc, y0-yc)
Jetzt Matrixmultipilakation mit
(cos [e]omega[/e] sin [e]omega[/e] ) * (x0-xc) = (x1) (-sin [e]omega[/e] cos [e]omega[/e] ) (y0-yc) = (y1)
Oder etwas umständlich hingeschrieben:
x1 = (x0-xc) cos ω + (y0-yc) * sin ω
y1 = - (x0-xc) sin ω - (y0-yc) * cos ω(x1,y1) ist der neue Punkt, aber im verschobenen Koordinatensystem.
Also wieder (xc,yc) dazu addieren
(x1+xc, y1+xc) ist der neue Punkt
Für sehr kleine Winkel kannst du auch rechnen, dass sin(x)=x und cos(x)=1
-
Mups schrieb:
Mit ein bisschen Matrix-Vektor-Zauberrei geht das ganz einfach
Gibt's auch einen Weg nur auf Basis von sin() und cos()? Mir wäre es recht, wenn es möglichst wenig Rechenzeitintensiv ist, was bei dem Umweg über eine Matrix ja leider der Fall ist...
-
Das ist doch nur sin und cos. Naja, Multiplikation und Addition noch, aber die kosten ja nichts.
-
Die Formel von Mups verwendet doch nur Sinus und Cosinus (und wenn du immer um den selben Winkel rotieren willst, kannst du die Werte auch vorher berechnen und speichern). Und die Arbeit mit 2x2-Matrizen ist nun wirklich nicht rechenintensiv (jedenfalls verglichen mit trigonometrischen Funktionen).
-
Mups schrieb:
x1 = (x0-xc) cos ω + (y0-yc) * sin ω
y1 = - (x0-xc) sin ω - (y0-yc) * cos ω(x1+xc, y1+xc) ist der neue Punkt
So, ich baue seit Tagen daran rum, kriege es aber nicht gebacken. Den Winkel gebe ich in Radians an, das sollte ja stimmen?
Trotzdem dreht mir dieser Code die Punkte nach sonstwo hin, mit dem eigentlich gewünschten Winkel hat das nix zu tun. Was könnte da schief gehen?
-
Darf ich annehmen, dass du mitgedacht hast und Mups Schreibfehler nicht mit übernommen hast? Falls nicht: Da stimmt was nicht in der letzten Zeile.
Übrigens: Sinus und Cosinus des gleichen Winkels kann man effizient berechnen. Guck dich mal in dein Lieblingsnumerikbuch oder in die Doku deiner Lieblingsnumerikbibliothek, da findest du gewiss etwas dafür.
-
Hast du denn den richtigen Bezugspunkt verwendet? Wenn du mehrere Punkte gemeinsam rotierst, solltest du eigentlich irgendein Muster erkennen.
-
SeppJ schrieb:
Darf ich annehmen, dass du mitgedacht hast und Mups Schreibfehler nicht mit übernommen hast?
Nein, ich rechne nicht
y1+xc
sondern
y1+yc
das passt bei mir schon.
-
CStoll schrieb:
Hast du denn den richtigen Bezugspunkt verwendet? Wenn du mehrere Punkte gemeinsam rotierst, solltest du eigentlich irgendein Muster erkennen.
Ich habe einfach mal ein Bild fabriziert: http://img268.imageshack.us/img268/7641/clipboard01lw.png
Ganz oben sind meine Ausgangsdaten zu sehen, eine gerade Linie (z.B. die Oberseite vom "T") besteht dabei aus vielen kleinen Einzellinien.
Dann gibt es einen Rotationsmodus (der Text darunter), in dem jeder Koordinatenpunkt einzeln rotiert wird - um so weiter er sich vom Mittelpunkt des Textes weg befindet, um so weiter wird rotiert. Das funktioniert prima, verzerrt mir aber die Buchstaben.
Also habe ich diesen anderen Algorithmus eingesetzt: es wird der mittlere Abstand jedes Buchtaben vom Mittelpunkt des Textes ermittelt, daraus ergibt sich der Rotationswinkel. Dann wird jeder Buchtsabe einzeln in die Mitte verschoben und von dort aus jede seiner Koordinaten um den zuvor ermittelten Winkel weiterrotiert. Der Unterschied zum ersten Verfahren: alle Koordinatenpunkte eines Buchstaben werden um den gleichen Winkel weitergedreht, damit der Buchstabe nicht verzerrt wird.
Das mache ich mit dem Algorithmus von oben, das Ergebnis ist der lustig verzerrte Text ganz unten im Bild.
-
Panamakanal schrieb:
Mups schrieb:
x1 = (x0-xc) cos ω + (y0-yc) * sin ω
y1 = - (x0-xc) sin ω - (y0-yc) * cos ω(x1+xc, y1+xc) ist der neue Punkt
In dem hier zitierten Beitrag hat sich noch ein weiterer Fehler eingeschlichen (vergleich mal die Formeln mit der Matrix-Schreibweise, dann fällt der Vorzeichenfehler vielleicht auf).
-
Und wo sieht man in dem Bild dies:
Trotzdem dreht mir dieser Code die Punkte nach sonstwo hin, mit dem eigentlich gewünschten Winkel hat das nix zu tun.
?
-
SeppJ schrieb:
Und wo sieht man in dem Bild dies:
Trotzdem dreht mir dieser Code die Punkte nach sonstwo hin, mit dem eigentlich gewünschten Winkel hat das nix zu tun.
?
Ganz unten im Bild - das in der Mitte ist NICHT das Ergebnis der Formel von oben...
-
Ach, da war ich ja fleißig. Ich hab gleich zwei kleine Aufgaben zum Mitdenken in das Posting eingebaut
Die Matrix-Formel war richtig, alles andere ist zum denken. Wurde ja eigentlich auch schon geschrieben.
Für Leute, die nicht denken wollen:
x1 = (x0-xc) cos [e]omega[/e] + (y0-yc) * sin [e]omega[/e] y1 = - (x0-xc) sin [e]omega[/e] [b]+[/b] (y0-yc) * cos [e]omega[/e]
und
(x1+xc, y1+yc) ist der neue Punkt.
Dein Bild verstehe ich übrigens auch nicht.
-
Mups schrieb:
Dein Bild verstehe ich übrigens auch nicht.
Das entsteht tatsächlich so, wenn das Vorzeichen falsch ist - jetzt passt es
-
Panamakanal schrieb:
Gibt's auch einen Weg nur auf Basis von sin() und cos()? Mir wäre es recht, wenn es möglichst wenig Rechenzeitintensiv ist, was bei dem Umweg über eine Matrix ja leider der Fall ist...
wie kommst du auf den Müll?
-
otze schrieb:
Panamakanal schrieb:
Gibt's auch einen Weg nur auf Basis von sin() und cos()? Mir wäre es recht, wenn es möglichst wenig Rechenzeitintensiv ist, was bei dem Umweg über eine Matrix ja leider der Fall ist...
wie kommst du auf den Müll?
danke für diesen wichtigen Beitrag; SG1 hats vor 10 Tagen etwas freundlicher ausgedrückt...