Seite 1 von 2
Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 17.05.2018 23:39
von Syntacks_Error
Hier gleich noch eine Frage:
Ich habe Rechtecke, die rotieren, und zwar praktischerweise nur um 90, 180 und 270 Grad.
ALso: Rechteck z.B. 10 * 6 (Immer gerade Werte). Die Eckpunkte (x/y) sind dann links 0/0, 0/6 (yAchse von unten nach oben) und rechts 10/0 und 10/6.
Zentrum wäre x = 5, y = 3.
Rotieren tut das Mistteil aber nicht um den Mittelpunkt 5 und 3, sondern z.B. um x = 6 und y = 2 (auch immer gerade Werte), wobei das natürlich unterschiedlich ist. Manche Rechtecke sind auch nur in einer Rotationsaxe exzentrisch.
Was ich brauche, sind die Eckpunkte des Rechtecks nach einer Rotation. Herauskommen müssen dabei gleichfalls grade Werte, grobe Näherung genügt, vieleicht geht das auch ohne Winkelfunktion?
Meine Versuchsrechtecke aus Papier haben mir da beim Verständnis leider nicht weitergeholfen. Millimeterpapier wäre vielleicht hilfreich gewesen.
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 18.05.2018 01:47
von NicTheQuick
Konzentrier dich mal auf eine Ecke und schau in welchem Quadrat diese sich bei 90° Drehungen bewegt.
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 18.05.2018 07:39
von helpy
NicTheQuick hat geschrieben:Konzentrier dich mal auf eine Ecke und schau in welchem Quadrat diese sich bei 90° Drehungen bewegt.

Da muss man nur noch addieren/subtrahieren, um die neuen Eckpunkte zu bekommen!
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 18.05.2018 17:34
von Syntacks_Error
Sooo trivial ist das nun auch nicht. Addieren und substrahieren bei nur einer exzentrischen Achse kriege ich auch hin. Aber die Exzentriken können auf beiden Achsen links, rechts, oberhalb oder unterhalb des Mittelpunktes liegen. Insgsamt gibt es wohl acht Möglichkeiten. Das verwirrt mich. Was addiere oder substrahiere ich da so, dass eine Formel herauskommt?
Und was mache ich, wenn einer den Rechtecken von einer Welt außerhalb der rechten Winkel erzählt und die dann doch damit ankommen? Gibt es dafür etwas Griffiges?
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 18.05.2018 19:54
von ccode_new
Hallo!
Kann das mal jemand überprüfen.
Ist das so korrekt ?
Code: Alles auswählen
If InitSprite() = 0 Or InitKeyboard() = 0
MessageRequester("Error", "Geht nicht!", 0)
End
EndIf
;Rechtecke rotieren ( oder das Leben in einem Kreis ;) )
Structure TKoord
x.i
y.i
EndStructure
Structure TEckpunkte
A.TKoord
B.TKoord
C.TKoord
D.TKoord
EndStructure
Global *Points.TEckpunkte
Global Grad = 0
;x = X-Position im Koordinatensystem
;y = Y-Position im Koordinatensystem
;b = Breite des Rechtecks
;h = Höhe des Rechtecks
;a = Drehwinkel in Grad (also: 0, 45, 90, ...)
;rx = Rotationspunkt X
;ry = Rotationspunkt Y
;A-------C
;| |
;| |
;B-------D
Procedure RotateRect(x, y, l, b, a, rx=0, ry=0)
Protected pa.TKoord, pb.TKoord, pc.TKoord, pd.TKoord
Protected *RectPoints.TEckpunkte
*RectPoints = AllocateMemory(SizeOf(TEckpunkte))
If (rx < 0) Or (rx > l) Or (ry < 0) Or (ry > b)
Debug "Der Rotationspunkt muss im Rechteck liegen."
ProcedureReturn -1
EndIf
;Die Eckpunkte berechnen
pa\x = (rx+(0-rx)*Cos(Radian(a))-(0-ry)*Sin(Radian(a)))+x
pa\y = (ry+(0-rx)*Sin(Radian(a))+(0-ry)*Cos(Radian(a)))+y
pb\x = (rx+(0-rx)*Cos(Radian(a))-(b-ry)*Sin(Radian(a)))+x
pb\y = (ry+(0-rx)*Sin(Radian(a))+(b-ry)*Cos(Radian(a)))+y
pc\x = (rx+(l-rx)*Cos(Radian(a))-(0-ry)*Sin(Radian(a)))+x
pc\y = (ry+(l-rx)*Sin(Radian(a))+(0-ry)*Cos(Radian(a)))+y
pd\x = (rx+(l-rx)*Cos(Radian(a))-(b-ry)*Sin(Radian(a)))+x
pd\y = (ry+(l-rx)*Sin(Radian(a))+(b-ry)*Cos(Radian(a)))+y
*RectPoints\A = pa : *RectPoints\B = pb
*RectPoints\C = pc : *RectPoints\D = pd
ProcedureReturn *RectPoints
EndProcedure
;Rechteck rotieren
*Points = RotateRect(0, 0, 10, 6, 90, 5, 3)
Debug "Punkt A: (" + Str(*Points\A\x) + "," + Str(*Points\A\y) + ")"
Debug "Punkt B: (" + Str(*Points\B\x) + "," + Str(*Points\B\y) + ")"
Debug "Punkt C: (" + Str(*Points\C\x) + "," + Str(*Points\C\y) + ")"
Debug "Punkt D: (" + Str(*Points\D\x) + "," + Str(*Points\D\y) + ")"
Procedure DrawBox(*P.TEckpunkte)
If StartDrawing(ScreenOutput())
LineXY((*P\A\x), (*P\A\y), (*P\B\x), (*P\B\y), RGB(255, 0, 155))
LineXY((*P\B\x), (*P\B\y), (*P\D\x), (*P\D\y), RGB(255, 0, 155))
LineXY((*P\C\x), (*P\C\y), (*P\D\x), (*P\D\y), RGB(255, 0, 155))
LineXY((*P\C\x), (*P\C\y), (*P\A\x), (*P\A\y), RGB(255, 0, 155))
StopDrawing()
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 300, 300, "Rechteck-Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, 300, 300)
AddWindowTimer(0, 123, 16)
Else
MessageRequester("Fehler", "Geht nicht!", 0)
End
EndIf
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
Case #PB_Event_Timer
If EventTimer() = 123
ExamineKeyboard()
If Not KeyboardPushed(#PB_Key_P)
If Grad < 360
Grad + 1
ElseIf Grad = 360
Grad = 0
EndIf
FlipBuffers()
ClearScreen(RGB(0, 0, 0))
*Points = RotateRect(WindowWidth(0)/2-50, WindowHeight(0)/2-30, 100, 60, Grad, 50, 30)
Debug "Aktueller Winkel: "+Str(Grad)
Debug "Punkt A: (" + Str(*Points\A\x) + "," + Str(*Points\A\y) + ")"
Debug "Punkt B: (" + Str(*Points\B\x) + "," + Str(*Points\B\y) + ")"
Debug "Punkt C: (" + Str(*Points\C\x) + "," + Str(*Points\C\y) + ")"
Debug "Punkt D: (" + Str(*Points\D\x) + "," + Str(*Points\D\y) + ")"
DrawBox(*Points)
EndIf
EndIf
EndSelect
Until Event = 0
Delay(10)
ForEver
EndIf
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 18.05.2018 22:19
von helpy
Wenn es nur um 90°, 180° und 270° Drehung geht, dann reicht addieren/subtrahieren.
Hier das Rotieren eines Punktes p um den Dreh-/Rotationspunkt r:
Code: Alles auswählen
EnableExplicit
Enumeration enuRotate
; clockwise
#ROTATE_090_cw
#ROTATE_180_cw
#ROTATE_270_cw
; counter-clockwise
#ROTATE_090_ccw = #ROTATE_270_cw
#ROTATE_180_ccw = #ROTATE_180_cw
#ROTATE_270_ccw = #ROTATE_090_cw
EndEnumeration
Procedure RotatePoint(*p.Point, *r.Point, Rotation)
Protected pNew.Point, dx, dy
dx = *p\x - *r\x
dy = *p\y - *r\y
Select Rotation
Case #ROTATE_090_cw
pNew\x = *r\x + dy
pNew\y = *r\y - dx
Case #ROTATE_180_cw
pNew\x = *r\x - dx
pNew\y = *r\y - dy
Case #ROTATE_270_cw
pNew\x = *r\x - dy
pNew\y = *r\y + dx
Default : ProcedureReturn
EndSelect
CopyStructure(@pNew, *p, Point)
EndProcedure
Define p.Point
p\x = 0
p\y = 0
Define r.Point
r\x = 5
r\y = 3
Debug Str(p\x) + " / " + Str(p\y)
RotatePoint(p, r, #ROTATE_090_cw)
Debug Str(p\x) + " / " + Str(p\y)
RotatePoint(p, r, #ROTATE_090_cw)
Debug Str(p\x) + " / " + Str(p\y)
RotatePoint(p, r, #ROTATE_090_cw)
Debug Str(p\x) + " / " + Str(p\y)
RotatePoint(p, r, #ROTATE_090_cw)
Debug Str(p\x) + " / " + Str(p\y)
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 18.05.2018 22:31
von Syntacks_Error
Werden da wirklich die Eckpunkte ausgegeben? Bei der Eingabe
RotateRect(0, 0, 10, 6, 0,4,3) (x-Roatationspunkt 1 links vom Zentrum, aber keine Rotation) wird ausgeben:
Punkt A: (1,0)
Punkt B: (9,0)
Punkt C: (1,6)
Punkt D: (9,6)
Ich hätte erwartet, dass gar nichts passiert, es gab ja noch keine Rotation. Auch ist das Rechteck jetzt nur noch 8 lang statt 10
Bei RotateRect(0, 0, 10, 6, 90,5,3) - 90 Grad rechts um das Zentrum - wird ausgegeben:
Punkt A: (8,-2)
Punkt B: (8,8)
Punkt C: (2,-2)
Punkt D: (2,8)
Ich hätte erwartet, das A bei 5,2 liegt und B (vormals rechte untere Ecke) entsprechend bei 2,-5. Der Punkt geht ja unter die y-Nulllinie.
Oder verstehe ich die Ausgabe falsch?
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 19.05.2018 09:26
von Muttonhead
Code: Alles auswählen
y
^
|
|
|
o -2,3 -
|
|
- o 3,2
|
|
-
|
|
------|------|------|------|------+------|------|------|------|------|------|------> x
|
|
-
|
|
o -3,-2 -
|
|
- o 2,-3
|
|
Drehrichtung gegen Uhrzeiger
90 grd:
Xgedreht= Y * -1
Ygedreht= X
180 grd:
Xgedreht= Y * -1
Ygedreht= X * -1
270 oder -90 grd:
Xgedreht= Y
Ygedreht= X * -1
Jeder dieser vier Punkte im Koordinatensystem ist das um 90 grad gedrehte Abbild seines Nachbarn
...vielleicht bin ich aber auch am Thema total vorbei
Muttonhead
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 19.05.2018 12:16
von helpy
Dieser Ansatz gilt nur für die Drehung um den Nullpunkt!
Das ist falsch:
Muttonhead hat geschrieben:180 grd:
Xgedreht= Y * -1
Ygedreht= X * -1
Richtig wäre:
180 grd:
Xgedreht= X * -1
Ygedreht= Y * -1
Drehung eines Punktes P um einen beliebigen Punkt R:
- Nullpunkt des Koordinatensystems in Punkt R verschieben:
- Punkt P0 drehen:
Code: Alles auswählen
Drehung um 90° im Uhrzeigersinn bzw. 270° gegen Uhrzeigersinn:
PXnull_gedreht = PYnull
PYnull_gedreht = -PXnull
Drehung um 90° gegen Uhrzeigersinn bzw. 270° im Uhrzeigersinn:
PXnull_gedreht = -PYnull
PYnull_gedreht = PXnull
Drehung um 180°:
PXnull_gedreht = -PXnull
PYnull_gedreht = -PYnull
- Nullpunkt des Koordinatensystem wieder zurück verschieben:
Code: Alles auswählen
PXgedreht = PXnull_gedreht + RX
PYgedreht = PYnull_gedreht + RY
Die drei Schritte kann man zusammenfassen:
Code: Alles auswählen
Drehung um 90° im Uhrzeigersinn bzw. 270° gegen Uhrzeigersinn:
PXgedreht = (PY - RY) + RX
PYgedreht = -(PX - RX) + RY
Drehung um 90° gegen Uhrzeigersinn bzw. 270° im Uhrzeigersinn:
PXgedreht = -(PY - RY) + RX
PYgedreht = (PX - RX) + RY
Drehung um 180°:
PXgedreht = -(PX - RX) + RX
PYgedreht = -(PY - RY) + RY
Und noch weiter vereinfacht:
Code: Alles auswählen
dx = PX - RX
dy = PY - RY
Drehung um 90° im Uhrzeigersinn bzw. 270° gegen Uhrzeigersinn:
PXgedreht = RX + dy
PYgedreht = RY - dx
Drehung um 90° gegen Uhrzeigersinn bzw. 270° im Uhrzeigersinn:
PXgedreht = RX - dy
PYgedreht = RY + dx
Drehung um 180°:
PXgedreht = RX - dx
PYgedreht = RY - dy
Re: Eckpunkt exzentrisch rotierender Rechtecke
Verfasst: 19.05.2018 12:24
von Muttonhead
Richtig wäre:
180 grd:
Xgedreht= X * -1
Ygedreht= Y * -1
Hast vollkommen recht

Mutton