Bewegungslehre
-> monotone Bewegung im Kreis
Aufgabenstellung:
Ein Sprite soll sich mit konstanter Geschwindigkeit kreisförmig um einen Mittelpunkt bewegen.

Kennt man von einem Kreis den Mittelpunkt und den Radius r, so kann man ein Sprite um diesen Mittelpunkt kreisförmig bewegen. Zum Beispiel, indem man den Winkel stetig erhöht.

Die fehlenden Informationen x und y, die Koordinaten für den neuen Punkt, lassen sich anhand eines rechtwinkeligen Dreiecks und den Winkelfunktionen berechnen:
 
Cosinus des Winkels = Ankathete / Hypotenuse
Sinus d. Winkels = Gegenkathete / Hypotenuse

Billig umformuliert würde das in Lingo folgendes ergeben:
cos(alpha) = x / radius
sin(alpha) = y / radius

Berücksichtigt man, vom Bogenmaß in Grad umrechnen zu müssen, und löst die Gleichungen nach x und y auf, so kann man dies mit folgendem Handler zusammenfassen:
 
on GetCirclePoint angle, radius
  rads = angle * pi() / 180.00
  Px = cos(rads) * radius
  Py = sin(rads) * radius
  RETURN point(Px,Py)
end

Möchte man statt einem übersichtlichen Script doch lieber eines, das einen Hauch schneller funktioniert, empfiehlt sich stattdessen die einzeilige Kurzform:
 
P = point(cos(angle*pi()/180.00), sin(angle*pi()/180.00)) * radius

Nun braucht man nur mehr für den Winkel ansteigende Werte mitschicken, und schon tanzt das Sprite rund um den Mittelpunkt.
 
property pCenter, pRadius, pAngle

on beginSprite me
  pCenter = point(200,200) -- ein Mittelpunkt
  pRadius = 100 -- ein Radius
  pAngle = 0 -- ein Winkel, bei dem begonnen werden soll
end

on exitFrame me
  pAngle = (pAngle + 5) mod 360 -- der Winkel wird um 5° erhöht
  newLoc = pCenter + GetCirclePoint(pAngle, pRadius) -- ein neuer Punkt wird berechnet
  sprite(me.spriteNum).loc = newLoc -- das Sprite wird positioniert
end


 
Example: circular1_inSteps.dir (Geschwindigkeit in Anzahl Schritten pro Drehung)
Example: circular2_InTime.dir (Geschwindigkeit in Zeit pro Drehung)


Aufgabenstellung: Berechnung des Winkels

Für den täglichen Hausgebrauch gibt es aber noch eine Situation, bei der die Winkelfunktionen sehr hilfreich zur Seite stehen:
Wenn man den momentanen Winkel eines Sprites im Bezug auf einen Kreismittelpunkt errechnen möchte.
 
Tangens des Winkels = Gegenkathete / Ankathete
-- ein "billige" Übersetzung  in Lingo:
tan(alpha) = y / x
rads = atan(y / x)
alpha =  rads * 180 / pi()


Ein funktionsfähiger, ausführlicher Handler zur Berechnung eines Winkels sieht folgendermaßen aus:
 
on GetAngle TheVector
  dx = TheVector[1]
  dy = TheVector[2]
  rads = atan(float(dy),float(dx))
  angle = rads * 180 / pi()
  RETURN angle
end

Anmerkung: "TheVector" stellt die Distanz zwischen dem Punkt auf dem Kreis und den Mittelpunkt des Kreises dar. zB TheVector = KreisPunkt - Mittelpunkt

Die schnellere Kurzform des Handlers:
 
angle = atan(float(TheVector[2]), float(TheVector[1])) * 180 / pi()

Anmerkung: Der Winkel, der hier berechnet wird, hat folgende Ergebnisse:
rechts = 0°
unten = 90°
links = 180°
oben = 270°
Vergleicht man dies mit dem mathematischen Standard, so wird dort ein Kreis GEGEN den Uhrzeigersinn beschrieben. Der Unterschied erklärt sich daher, daß in der Mathematik die positive y-Achse immer nach oben eingezeichnet wird, während in Director die Werte für y nach unten ansteigen. (Der Koordinatenursprung in Director ist der linke obere Punkt der Bühne.)

Ein sehr einfaches und effizientes Mittel, die Winkelfunktionen praktisch anzuwenden, ist ein Sprite mittels rotation of sprite in eine bestimmte Richtung zu drehen. Mit dem oben beschrieben Handler "GetAngle" bleibt nicht mehr viel übrig, was noch zu tun ist...

Example: circular3_gettingAngle.dir



Obwohl im letzten Abschnitt (Bewegung von A nach B) beschrieben steht, daß man lediglich mit Vektoren rechnen braucht, um ein Sprite fortzubewegen, ist es natürlich auch möglich, dies mittels Winkelfunktionen zu erledigen. 
Die Richtung, in die das Sprite wandern soll, kann wieder mittels "GetAngle" errechnet werden. Der nächste Punkt, wo das Sprite gezeichnet werden soll, mittels "GetCirclePoint(angle, radius)", wobei als Parameterübergabe für "radius" die Schrittweite in Pixel mitgeschickt werden kann.

Verwendet man als Zielpunkt für den Spaziergang des Sprites keinen starren Punkt, sondern zum Beispiel die Maus, so sieht das Ganze beinahe schon witzig aus:

Example: circular4_moveIt.dir

Hmm, aber noch viel lustiger wirds, wenn sich das Sprite nicht mit konstanter Geschwindigkeit bewegt...


Last: Bewegung von A nach B