![]() |
Kreisförmige Bewegung eines Objektes
Hi,
ich will, dass sich ein Objekt, am Besten ein Label, auf dem Forumlar im Kreis bewegt (es soll sich nicht drehen). Hat wer eine Idee? Ich habs mit sin versucht, aber man kann ja nur mit Bogenmaß arbeiten -> keine Kommazahlen in label1.left Danke im Vorraus ErdNussLocke |
Re: Kreisförmige Bewegung eines Objektes
Beim zuweisen Rounden.
|
Re: Kreisförmige Bewegung eines Objektes
Was ist mir Komma-Zahlen in deinem Label? Position einfach per (sin(x),cos(x)) festlegen und dann je nach Vorliebe noch die Funktionen degtorad/RadToDeg benutzen.
|
Re: Kreisförmige Bewegung eines Objektes
Aber wie lege ich denn die Position fest? Ich kenne nur label1.left:=X; Wenn ich da einen Kommawert eingebe kommt ein Fehler.
|
Re: Kreisförmige Bewegung eines Objektes
Zitat:
Trunc rundet X, sodass Label1.Left ein Integer-Wert zugewiesen wird. Falls du einen fertigen Code haben willst, sag Bescheid. Aber vll kriegst du's jetzt ja auch selber hin. |
Re: Kreisförmige Bewegung eines Objektes
Wo gibts du welchen Wert ein, das welcher Fehler kommt? Was willst du genau machen?
|
Re: Kreisförmige Bewegung eines Objektes
Krieg ich nicht hin :( Wenn ich z.B. sin(360) runde kommt ja eins raus, weil das ja noch knapp kleiner is als 1. Aber mit nur 2 Zahlen kann ich ja keine Kreisbewegung simulieren :-/
|
Re: Kreisförmige Bewegung eines Objektes
event. geht es ja so:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin // Radius des Einheitskreises = 40 Dots X0 := Label1.left - 40; Y0 := Label1.top; Grad := 0; Timer1.Enabled := true end; procedure TForm1.Timer1Timer(Sender: TObject); begin inc(Grad,2); Label1.left := X0 + round (cos(2*Pi/360 * Grad) * 40); Label1.Top := Y0 - round (sin(2*Pi/360 * Grad) * 40); if Grad = 360 then Timer1.Enabled := false end; |
Re: Kreisförmige Bewegung eines Objektes
@TStringlist: Jetzt war ich auch gerade fertig mit meinem Vorschlag, aber du warst schneller :)
Man kann noch den Radius und die Drehrichtung einbeziehen:
Delphi-Quellcode:
... wenn man XR und YR unterschliedlich groß macht, entsteht eine Ellipse.
procedure TForm1.Button1Click(Sender: TObject);
begin XR := 40; YR := 40; X0 := Label1.left - XR; Y0 := Label1.top; Grad := 0; Richtung := 1 //1 = mathematische pos. Drehsinn (gegen Uhrzeigersinn), -1 = entsprechend anders herum Timer1.Enabled := true end; procedure TForm1.Timer1Timer(Sender: TObject); begin inc(Grad,2); Label1.left := X0 + round (cos(2*Pi/360 * Grad) * XR); Label1.Top := Y0 - round (sin(2*Pi/360 * Richtung * Grad) * YR); if Grad = 360 then Timer1.Enabled := false end; |
Re: Kreisförmige Bewegung eines Objektes
Danke sehr. Es funktionert! :)
Zwei Fragen noch: Wozu steht die "2" bei "inc(Grad,2)"? Warum bei der "left"+"top"- Zuweisung am Ende *40? Thx |
Re: Kreisförmige Bewegung eines Objektes
Hi ErdnussLocke.
Zitat:
Inc(Grad) heißt: Erhöhe Grad um 2. Zitat:
Gruß, Waldteufel |
Re: Kreisförmige Bewegung eines Objektes
Für kontinuierliches Drehen:
Anstatt: Inc(Grad, 2); folgendes: Grad:=(Grad+2) mod 360; ... und if Grad = 360 then Timer1.Enabled := false weglassen. Also so:
Delphi-Quellcode:
(Für sehr große Kreise Grad:=(Grad+1)mod 360, falls es ruckelt.)
procedure TForm1.Button1Click(Sender: TObject);
begin XR := 40; YR := 40; X0 := Label1.left - XR; Y0 := Label1.top; Grad := 0; Richtung := 1 //1 = mathematische pos. Drehsinn (gegen Uhrzeigersinn), -1 = entsprechend anders herum Timer1.Enabled := true end; procedure TForm1.Timer1Timer(Sender: TObject); begin Grad:=(Grad+2) mod 360; Label1.left := X0 + round (cos(2*Pi/360 * Grad) * XR); Label1.Top := Y0 - round (sin(2*Pi/360 * Richtung * Grad) * YR); end; |
Re: Kreisförmige Bewegung eines Objektes
thx!
Dann hab ichs jetz verstanden! Danke an euch alle! Bis zum nächsten Prob ;) MfG ErdNussLocke |
Re: Kreisförmige Bewegung eines Objektes
Das mod ist aber völlig überflüssig. Die Sinusfunktion ist doch schön periodisch (sin(alpha)=sin(alpha+360°) oder sin(x)=sin(x+2 pi))
|
Re: Kreisförmige Bewegung eines Objektes
Das habe ich zuerst auch gedacht und das geht vermutlich auch gut. Sauber programmiert ist das aber (wie ich finde) nicht, weil es irgendwann zum Überlauf kommt.
|
Re: Kreisförmige Bewegung eines Objektes
Naja, "sauber" programmiert wäre es, alle x und y eines 1/4 Kreises zu speichern
und den Rest durch Spiegelung an der X- und/oder der Y-Achse zu ermitteln. Das schont den Prozessor....Sin und Cos ist nicht mal eben so ermittelt. |
Re: Kreisförmige Bewegung eines Objektes
Zitat:
Delphi-Quellcode:
oder halt mit belibigen Zweierpotenzen und AND:
Var Grad: Byte; {0..255}
procedure TForm1.Timer1Timer(Sender: TObject); begin Inc(Grad, 2); Label1.left := X0 + round (cos(Pi/128 * Grad) * XR); Label1.Top := Y0 - round (sin(Pi/128 * Richtung * Grad) * YR); end;
Delphi-Quellcode:
Var Grad: Integer; {z.B.: 0..1023}
procedure TForm1.Timer1Timer(Sender: TObject); begin Grad := (Grad + 2) and $03FF; Label1.left := X0 + round (cos(Pi/512 * Grad) * XR); Label1.Top := Y0 - round (sin(Pi/512 * Richtung * Grad) * YR); end; |
Re: Kreisförmige Bewegung eines Objektes
Zitat:
Danke sehr |
Re: Kreisförmige Bewegung eines Objektes
naja, 2pi/360*Grad verwandelt Grad von Rad zu Deg, wie du Funktion RadtoDeg. also 0-360 -> 0-2pi. Die 40 ist der Radius des Kreises.
Wie sin und cos am Einheitskreis definiert sind, kannst du in der WIkipedia lesen. |
Re: Kreisförmige Bewegung eines Objektes
Schau mal im Tafelwerk, bei Wikipedia, oder sonstwo nach Kreisfunktionen, als sowas schimpfen sich Sinus und Cosinus schließlich :zwinker:
|
Re: Kreisförmige Bewegung eines Objektes
Zitat:
Cos ist Ankathete/Hypothenuse und berechnet das gleiche für die X-Position. Die Winkel, von denen der Cosinus bzw. Sinus berechnet wird, müssen in Delphi immer in Bogenmaß statt in Grad sein. Deswegen 2*Pi/360*Grad. Das könnte man alternativ auch mit DegToRad(Grad) machen. |
Re: Kreisförmige Bewegung eines Objektes
Hier nochmal ein ganz trivialer Erklärungsversuch: Du kennst doch bestimmt die Sache mit dem Einheitskreis und dem rechtwinkligen Dreieck darin. Die Hypotenuse dieses Dreieckes ist dabei nämlich immer der Kreis-Radius, der, wenn der Winkeln zur X-Achse langsam aber stetig zunimmt, dann natürlich auch jeden Punkt auf dieser Kreisbahn berühren kann. Und um nun rechnerisch zu diesen Punkten auf der Kreisbahn zu kommen, brauchst man jetzt nur noch mehr zu einer Ausgangsposition diejenigen Längen dazuaddieren, die dieser Radius (=Hypotenuse) jeweils auf die X- u. auf die Y-Achse projiziert ergibt. Und genau diese Projektionslängen sind nunmal die Ergebnisse dieser Sinus- und Kosinus-Funktionen... (Wie die jetzt mathematisch genau definiert sind, wird ja schon teilweise darüber beschrieben)
edit: Die obige Erklärung gilt, wenn die dort erwähnte Ausgangsposition (X0/Y0) immer der Kreismittelpunkt ist ...und daher musste das X0 vor dem eigentlichen Start des Timers dann eben auch immer zuerst noch auf diesen Kreismittelpunkt umgesetzt werden muss (X0 := Label1.left - 40)! ~~~ nur der absoluten Nachvollziehbarkeit halber ~~~ |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz