Hallo!
Wie kann ich eine Linie auf einem Canvas in einer Animation um den anfangspunkt um 90° drehen?
Bzw. drehen kann man Canvas-Objekte ja nicht wirklich.(Oder etwa doch?) Also muss man doch den Endpunkt mit coords() schritt für schritt verlegen, oder?
Wie schreibe ich aber jetzt eine dynamische Funktion, die eine Animation erzeugt, bei der sich die Länge der Linie nicht verändert?
mfg, jj
Canvas-Objekte/Linie animiert drehen [gelöst]
-
- User
- Beiträge: 419
- Registriert: Sonntag 3. September 2006, 15:11
- Wohnort: in den weiten von NRW
- Kontaktdaten:
Zuletzt geändert von schlangenbeschwörer am Donnerstag 9. November 2006, 18:14, insgesamt 1-mal geändert.
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi Schlangenbeschwörer,schlangenbeschwörer hat geschrieben: Wie schreibe ich aber jetzt eine dynamische Funktion, die eine Animation erzeugt, bei der sich die Länge der Linie nicht verändert?
mfg, jj
das Zauberwort heißt "Mathematik"

a) Winkelfunktionen im rechtwinkligen Dreieck:
sin(w) * Laenge = GK
cos(w) * Laenge = AK
b) Satz des Pythagoras:
x**2 + y**2 = Laenge**2
Im ersten Fall zaehlst Du die Winkel hoch und berechnest den Abstand vom Mittelpunkt in x- und y-Richtung. Das führt zu einer gleichmäßigen Drehung, benötigt aber etwas Rechenleistung. Hier ein Beispiel:
Code: Alles auswählen
from Tkinter import *
class Rotor:
import Canvas, math, time, thread
def __init__(self, wMaster, center = (100, 100), length = 100, freq = 1, fps = 25):
self.fWinkelProTic = 2 * self.math.pi * freq / fps
self.iWaitTime = int(1000.0/fps)
self.fAktWinkel = 0.0
self.fRadius = float(length)/2
self.iX, self.iY = center
self.wMaster = wMaster
self.isRotating = False
self.Line = self.Canvas.Line(wMaster, 0, 0, 0, 0)
self.update_line()
def update_line(self):
fAbstandX = self.fRadius * self.math.sin(self.fAktWinkel)
fAbstandY = self.fRadius * self.math.cos(self.fAktWinkel)
self.Line.coords(((self.iX+fAbstandX, self.iY-fAbstandY), (self.iX-fAbstandX, self.iY+fAbstandY)))
def progress(self):
if self.isRotating:
self.fAktWinkel += self.fWinkelProTic
if self.fAktWinkel > self.math.pi: self.fAktWinkel -= self.math.pi
self.update_line()
self.wMaster.after(self.iWaitTime, self.progress)
def start(self):
if self.isRotating: return
self.isRotating = True
self.thread.start_new_thread(self.progress, ())
def stop(self):
self.isRotating = False
wCanvas = Canvas(width = 400, height = 200, bd = 3, relief = SUNKEN)
wCanvas.grid()
R1 = Rotor(wCanvas, center = (100, 100), length = 50, freq = 1, fps = 20)
R2 = Rotor(wCanvas, center = (200, 100), length = 70, freq = 0.5, fps = 15)
R3 = Rotor(wCanvas, center = (300, 100), length = 20, freq = -2)
R1.start()
R2.start()
R3.start()
wCanvas.mainloop()
Wenn es Dir auf Performance ankommt, kannst Du auch die Positionen der Linienpunkte für eine Umdrehung zwischenspeichern und brauchst sie dann nicht immer neu zu berechnen.
EDIT: Eigentlich reichen die Sinuswerte für 0.5 Radiant aus
Grüße,
der Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
-
- User
- Beiträge: 419
- Registriert: Sonntag 3. September 2006, 15:11
- Wohnort: in den weiten von NRW
- Kontaktdaten:
Hi Michael,
danke für den Code, mit sin/cos hab ichs grad auch hinbekommen, zumidest einigermaßen. Doch es gibt echt keine kurze einfache Funktion dafür? Wenn man z.B. jetzt ein Quadrat drehen will, muss man das also entweder als sehr dicke Linie erzeugen, oder als Polygon, nur das wird dann echt schwer...
Gruß, jj
danke für den Code, mit sin/cos hab ichs grad auch hinbekommen, zumidest einigermaßen. Doch es gibt echt keine kurze einfache Funktion dafür? Wenn man z.B. jetzt ein Quadrat drehen will, muss man das also entweder als sehr dicke Linie erzeugen, oder als Polygon, nur das wird dann echt schwer...
Gruß, jj
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi,
stimmt, wenn Du Torsionsmatrizen einbaust, wirds einfacher.
Aber im Ernst, Du kannst natürlich Bilder mit der .rotate-Methode der Image-Instanzen drehen und dann ins Photoimage einfügen ... aber darunter werden Performance und Bildqualität erheblich leiden. Wenn Du das Bild nur auf 90° kippen willst ist es aber gut genug.
Michael
stimmt, wenn Du Torsionsmatrizen einbaust, wirds einfacher.

Aber im Ernst, Du kannst natürlich Bilder mit der .rotate-Methode der Image-Instanzen drehen und dann ins Photoimage einfügen ... aber darunter werden Performance und Bildqualität erheblich leiden. Wenn Du das Bild nur auf 90° kippen willst ist es aber gut genug.
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...