Entwickler-Ecke

Multimedia / Grafik - Object soll Kreisbewegung vollführen


Karlson - Fr 29.10.04 20:07
Titel: Object soll Kreisbewegung vollführen
Moin,

Ist es möglich mit einem Objekt eine Kreisbewegung zu vollführen? Also ganz "primitiv" mit Timer und nem Panel?


.Chef - Fr 29.10.04 20:24
Titel: Re: Object soll Kreisbewegung vollführen
Karlson hat folgendes geschrieben:
Ist es möglich mit einem Objekt eine Kreisbewegung zu vollführen? Also ganz "primitiv" mit Timer und nem Panel?

Klar. :nixweiss:

Für y lässt du den Sinus, für x den Cosinus laufen, jeweils multipliziert mitd em Radius. Dann noch den Mittelpunkt addieren, fertig.

Gruß,
Jörg


Karlson - Fr 29.10.04 20:27

Jop genausowas hab ich gesucht ;)
Nur war ich zu faul (und dumm :lol: ) mir sowas selbst zu überlegen.

dank dir!


ScorpionKing - Sa 30.10.04 15:37

hier ein bsp:


Quelltext
1:
2:
y := y + sin(y);
x := x + cos(x);


mfg, scorpionking 8)


.Chef - Sa 30.10.04 15:43

Also nimms mir nicht übel, aber _das_ ist gequirlter Unsinn!


ScorpionKing - Sa 30.10.04 15:48

wieso ist das gequirlt?
lästern aber ohne begründung! toll!


Maweki - Sa 30.10.04 15:51

weil x und y Winkel zu sein haben...


.Chef - Sa 30.10.04 15:53

Weil:

Delphi-Quelltext
1:
2:
Objekt.Left:=Round(Cos(Winkel)*Radius)+Mittelpunkt.X;
Objekt.Top:=Round(Sin(Winkel)*Radius)+Mittelpunkt.Y;

Die Typen:

Delphi-Quelltext
1:
2:
3:
Winkel, Radius : Real;
Mittelpunkt : TPoint;
Objekt : TControl;

Winkel ist eine globale Variable und wird z.B. im OnTimer jeweils erhöht, z.B. um pi/20.


Maweki - Sa 30.10.04 15:55

das hier koennte (imho) so in einen Timer:

Delphi-Quelltext
1:
2:
3:
4:
5:
// Die Varible Winkel sollte Global deklariert sein
// die Konstanten WinkelIncrement und Radius koennen auch lokal sein
Winkel := Winkel + WinkelIncrement;
Panel.left := Panel.Left + cos(Winkel) * Radius;
Panel.Top := Panel.Top + sin(Winkel) * Radius;

wenn du eine Drehung in die andere Richtung vollfuehrt haben moechtest, dann das + durch ein - ersetzen...

sollte so gehen, oder?


Edit: da war einer schneller...
hmmmm, und das Round hab ich auch vergessen. naja...


ScorpionKing - Sa 30.10.04 16:14

ich dachte x und y währen die koordinaten des pictures!


.Chef - Sa 30.10.04 16:16

ScorpionKing hat folgendes geschrieben:
ich dachte x und y währen die koordinaten des pictures!

Naja, deswegen können es ja keine Winkel sein. Den Winkel brauchst du aber, weil er es ist, der "wandert".


Karlson - Sa 30.10.04 21:41

Jop, hab das jetzt so gemacht wie chef es oben gesagt hat.

Für die Nachwelt wollte ich noch was anfügen: Dat klappt so nicht ;) Auf meinem Sys (p3,1000mhz,256sdram) erkennt man ausser flimmer nichts mehr, doublebuffered natürlich drin ;)


Maweki - Sa 30.10.04 21:44

hast du es in einen Timer getan? Das soll nicht in eine Schleife...


Karlson - Sa 30.10.04 21:46

Ja klar ist in nem Timer.
Das man gar nichts erkennt ist übertrieben, aber es reicht dass es extrem unschön wirkt.


Maweki - Sa 30.10.04 21:51

wie gross is der Intervall und der Winkelschritt?


Karlson - Sa 30.10.04 21:59

Es geht nicht darum dass es zu schnell ist :? ganz blöd bin ich auch nicht.
Es gibt einfach dieses Problem das dass canvas immer wiedr neu gezeichnet wird und deswegen flimmert.
Das Problem ist doch nichts neues! Hau mal ein grosses Image auf einen Timer, der immer left := left + 15 macht, genau das ist der effekt.


.Chef - So 31.10.04 00:19

Im Zuge der obigen Diskussion hatte ich es mit einem Button ausprobiert. Und da ging es wunderbar, so wie ich mir in etwa vorgestellt hatte.

Ich habe vorher noch nie das Bedürfnis gehabt, eine Komponente im Kreis zu bewegen. :nixweiss:


ScorpionKing - So 31.10.04 08:39

Also ihr könnt mir sagen was ihr wollt, aber folgender code funktioniert bei mir einwandfrei (bisschen abgeändert, hab ich aus Kopf getippt, weil ich projekt nicht jetzt laden will):


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var x,y: integer;

procedure TForm1.FromCreate;
begin
x := Button1.Width;
y := Button1.Height;
end;

procedure Timer1.OnTimer;
begin
x := x + sin(x);
y := y + cos(y);
Button1.Widht := x;
Button1.Height := y;
end;


ScorpionKing


.Chef - So 31.10.04 09:43

Komm, erzähl koane Gschichtn!

Es gibt mindestens hier Fehler, weil sin und cos Real-Werte zurückliefern:

Delphi-Quelltext
1:
2:
x := x + sin(x);
y := y + cos(y);

Außerdem entbehrt das jeder mathematischen Grundlage. Du darfst mich aber gern über dieses Verfahren zur Kreisberechnung aufklären.


Maweki - So 31.10.04 11:22

selbst mit

Delphi-Quelltext
1:
2:
x := Round(x + sin(x));  
y := Round(y + cos(y));


oder


Delphi-Quelltext
1:
2:
x := x + Round(sin(x));  
y := y + Round(cos(y));


wuerde sich die groesse des Buttons (die Position wird ja garnich veraendert) einfach nur nicht veraendern.
Denn Wenn Man mal Sinus und Cosinus Rundet kommt immer 0, 1 oder -1 bei raus. Und das immer gleichmaessig. Also wuerde der seine groesse maximal um 1 Pixel vergroessern und dann wieder verkleinern, wenn ich das richtig sehe. Aber ich teste deinen Code dachm Fruehstueck gerne mal aus...


BenBE - So 31.10.04 11:50

Für alle, die's richtig haben wollen:


Delphi-Quelltext
1:
2:
3:
Inc(Winkel);
X := X + Round(Radius * sin(2 * Pi * Winkel / 180));
Y := Y + Round(Radius * cos(2 * Pi * Winkel / 180));


Christian S. - So 31.10.04 11:54

BenBE hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
Inc(Winkel);
X := X + Round(Radius * sin(2 * Pi * Winkel / 180));
Y := Y + Round(Radius * cos(2 * Pi * Winkel / 180));
Ich denke nicht, dass das richtig ist. Zum einen definiert man den Winkel meist zwischen x-Achse und Radius, positiv gegen den Uhrzeigersinn. Dann ist, wenn der Winkel 0 ist, X maximal. Bei Dir ist es minimal. Zum anderen macht das "X + ..." keinen Sinn. Das "..." reicht. Lediglich ein Offset zur Verschiebung des Mittelspunktes kann noch mit rein!


.Chef - So 31.10.04 14:18

Der Ansatz mit X:=X+... ist völliger Quatsch. Wies richtig geht haben wir ja viel weiter vorne in diesem Thread bereits erklärt. Nur ein gewisser User wollte das noch nicht glauben. :roll:

Kann man diesen Thread nicht schließen?


Delete - So 31.10.04 14:58

Also ich sehe das Problem nicht. Chef hat die Lösung doch schon geschrieben:

Delphi-Quelltext
1:
2:
Button1.Left:=Round(Cos(Winkel)*Radius)+Mittelpunkt.X;
Button1.Top:=Round(Sin(Winkel)*Radius)+Mittelpunkt.Y;

Zu ergänzen wäre evt. noch, dass Winkel natürlich eine Gleitkommazahl sein sollte, die pro Intervall um 0.1 erhöht wird. Dadurch wird ein zu schnelles Springen des Objekts verhindert.