Rotation eines Rechtecks - Problem mit Rotationsursprung

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Pokoyo

Betreff: Rotation eines Rechtecks - Problem mit Rotationsursprung

BeitragFr, März 05, 2010 21:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen,
beim programmieren meiner Singlesurface 3D/2D Lib bin ich mal wieder auf ein warscheinlich ganz simpel zu lösesndes Problem gestossen.
Ich möchte ein Rechteck rotieren - rotation um den Mittelpunkt hab ich nach einigem rumexperimentieren folgendermassen hinbekommen - Codeschnipsel:
Code: [AUSKLAPPEN]
Graphics 1024,768,32,1
SetBuffer BackBuffer()

Global winkel#   =   0
Global breite#   =   200
Global hoehe#   =   100
Global x#      =   1000
Global y#      =   500

While Not KeyHit(1)
   Cls
   x   =   MouseX()
   y   =   MouseY()

   Local b#   =   breite/2
   Local h#   =   hoehe/2
   Local sw#   =   Sin(winkel)
   Local cw#   =   Cos(winkel)

   ax = x   +   (   cw *-b   ) - (   sw *-h   )
   ay = y   +   (   sw *-b   ) + (   cw *-h   )
   bx = x   +   (   cw *b   ) - (   sw *-h   )
   by = y   +   (   sw *b   ) + (   cw *-h   )
   cx = x   +   (   cw *-b   ) - (   sw *h   )
   cy = y   +   (   sw *-b   ) + (   cw *h   )
   dx = x   +   (   cw *b   ) - (   sw *h   )
   dy = y   +   (   sw *b   ) + (   cw *h   )

   Color 255,255,255
   Line ax,ay,bx,by
   Line bx,by,dx,dy
   Line cx,cy,dx,dy
   Line ax,ay,cx,cy
   Plot x,y

   Color 255,0,0
   Text ax,ay,"A"
   Text bx,by,"B"
   Text cx,cy,"C"
   Text dx,dy,"D"

   Text 10,10,Str(winkel)

   winkel =(winkel+1) Mod 359
   Flip
Wend


Nun möchte ich aber einen anderen Ursprungspunkt für die Rotation haben. Quasi ein 2d pivot um den ich drehen kann Laughing

Hat jemand ne Idee ?
danke im vorraus - Pokoyo
|Win10 64bit|FX 8350@4,5 GHz|Asrock 990FX Killer Fatality|16GB HyperX|R9 290X|Blitz3D|BlitzMax|

BladeRunner

Moderator

BeitragFr, März 05, 2010 22:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Berechne per Pythagoras den Abstand der Eckpunkte zum Pivot. Anhand dieser vier Distanzen kannst Du per Sin und Cos * Distanz die Position nach Rotation bestimmen.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

mpmxyz

BeitragFr, März 05, 2010 22:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde dieses System nehmen:
Code: [AUSKLAPPEN]
-Die Punkte vom Rechteck berechnen.
-Von diesen Punkten die Drehpunktposition abziehen, sodass dieser auf (0|0) liegen würde.
-Jeden Punkt um den Mittelpunkt drehen.
-Die Drehpunktposition zu den Punkten wieder hinaufaddieren.

Das Drehen der einzelnen Punkte läuft dann so ab:
Code: [AUSKLAPPEN]
Sinus=Sin(r)
Cosinus=Cos(r)

XAlt=X
X=X*Cosinus+Y*Sinus
Y=Y*Cosinus+XAlt*Sinus

Je, nachdem, wie deine Rotation definiert ist, muss vielleicht aus einem "+" ein "-" werden.

mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Pokoyo

BeitragSa, März 06, 2010 0:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Jo dankeschön euch Beiden, es funktioniert Very Happy hab mich für die 2. Variante entschieden. Bladerunners Vorschlag scheint mir zu rechenintensiv.
|Win10 64bit|FX 8350@4,5 GHz|Asrock 990FX Killer Fatality|16GB HyperX|R9 290X|Blitz3D|BlitzMax|

darth

BeitragSa, März 06, 2010 0:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

das Rotieren ist im Prinzip ganz einfach. Wenn man weiss wie man mit Matrizen und Vektoren rechnet that is.
Bestimme den Vektor von deinem Rotationszentrum zum Eckpunkt, Vektoren sind prinzipiell Ziel-Start.

Code: [AUSKLAPPEN]
Vx = EckeX - RotationCenterX
Vy = EckeY - RotationCenterY


Nun braucht man etwas, das sich Drehmatrix (oder Rotationsmatrix) nennt, im 2D Raum ist die ziemlich einfach:

Code: [AUSKLAPPEN]
 cos(a)   sin(a)
-sin(a)   cos(a)


Wobei a der Winkel ist, um den man drehen möchte. (ANM: bei a=0 ist dies eine Identitätsmatrix, es wird also gar keine Drehung ausgeführt.)
Anschliessend muss man die Matrix mit dem Vektor multiplizieren, das gibt dann den gedrehten Vektor, Matrizenmultiplikationen sind eigentlich auch keine Hexerei. Das Ergebnis sieht dann so aus, Zeile * Spalte.

Code: [AUSKLAPPEN]
VxNeu = Vx*cos(a) + Vy*sin(a)
VyNeu = Vx*(-sin(a)) + Vy*cos(a)


Bei der Multiplikation muss man aufpassen, dass man die alten Werte nicht überschreibt, weil sie in beiden Rechnungen vorkommen. In VyNeu braucht man noch das alte Vx, deshalb kann man die Werte nicht einfach überschreiben.
Hier zeigt sich der Punkt mit der Identitätsmatrix wieder, bei a=0 ist VxNeu = Vx und VyNeu = Vy, da cos(0)=1 und sin(0)=0. Mit den neuen Vektoren kann man dann den neuen Punkt bestimmen, Ende = Anfang + Vektor.

Code: [AUSKLAPPEN]
XNeu = RotationCenterX + VxNeu
YNeu = RotationCentreY + VyNeu


Und somit wäre die ganze Hexerei abgeschlossen. Es ist eigentlich wirklich nicht kompliziert, wenn man weiss was man macht. Das einzige was ich immer wieder mal ausprobieren muss, weil ich es mir nie merken kann ist die Richtung der Drehung. Vor allem weil die Y-Achse ja von oben nach unten verläuft und so.
ANM: Wenn man die Drehrichtung ändern will, setzt man statt a einfach -a ein.

Das wäre alles was mir zu dem Thema einfällt.
MfG,
Darth
Diese Signatur ist leer.

Pokoyo

BeitragSa, März 06, 2010 1:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmmm, es scheint als ginge das ganze noch einfacher - es soll ja auch einigermassen schnell sein. Bei dieser Variante muss man etwas umdenken und aufpassen da die position auch gleich das Rotationszentrum darstellt :

Code: [AUSKLAPPEN]
Graphics 1024,768,32,1
SetBuffer BackBuffer()

Global winkel#   =   0
Global breite#   =   200
Global hoehe#   =   100
Global x#      =   1000
Global y#      =   500

While Not KeyHit(1)
   Cls
   x   =   MouseX()
   y   =   MouseY()


   pivx#=190
   pivy#=0

   pivx#=pivx#/2
   pivy#=pivy#/2

   Local b#   =   breite/2
   Local h#   =   hoehe/2
   Local sw#   =   Sin(winkel)
   Local cw#   =   Cos(winkel)

   ax = x   +   (   cw   *   -   (b-pivx))-(sw *-(h-pivy))
   ay = y   +   (   sw   *   -   (b-pivx))+(cw *-(h-pivy))
   bx = x   +   (   cw   *      (b+pivx))-(sw *-(h-pivy))
   by = y   +   (   sw   *      (b+pivx))+(cw *-(h-pivy))
   cx = x   +   (   cw   *   -   (b-pivx))-(sw *(h+pivy))
   cy = y   +   (   sw   *   -   (b-pivx))+(cw *(h+pivy))
   dx = x   +   (   cw   *      (b+pivx))-(sw *(h+pivy))
   dy = y   +   (   sw   *      (b+pivx))+(cw *(h+pivy))

   Color 255,255,255
   Line ax,ay,bx,by
   Line bx,by,dx,dy
   Line cx,cy,dx,dy
   Line ax,ay,cx,cy
   Plot x,y
   Text x,y,"pivot"
   Color 255,0,0
   Plot x-pivx,y-pivy
   Text ax,ay,"A"
   Text bx,by,"B"
   Text cx,cy,"C"
   Text dx,dy,"D"
   Text 10,10,Str(winkel)
   winkel =(winkel+1) Mod 359
   Flip
Wend
|Win10 64bit|FX 8350@4,5 GHz|Asrock 990FX Killer Fatality|16GB HyperX|R9 290X|Blitz3D|BlitzMax|

BladeRunner

Moderator

BeitragSa, März 06, 2010 8:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Mein Vorschlag entspricht im Prinzip genau dem was mpmxyz vorschlug Wink Die Rechenarbeit bleibt im Wesentlichen die Gleiche.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group