Autor Beitrag
Alebo
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Mo 01.03.04 18:13 
Hallo, hab mal wieder ein kleines Problem

Ich schreibe im Moment ein Programm zur Berechnung von Planetenbahnen (Drei-Körper-Problem).
Ich benutze eine TPaintBox um dort mit Canvas Ellipsen als Planeten zu zeichnen, so dass eine Animation entsteht.
Mein Problem ist, dass sich sehr schnell eine lange Reihe von Planeten bildet , da die alten nicht gelöscht werden.
Lasse ich die ganze Reichenfläche durch ein Rechteck löschen muss jedesmal das Koordinatensystem neu gezeichnet werden. Obwohl ich doublebuffered auf true gesetzt habe, flimmert es sehr stark.
Kann man z.B. irgendwie 2 Canvasflächen transparent übereinander legen, so dass das Koordinatensystem erhalten bleiben kann und ich nur die Planeten verschiebe, bzw neu zeichne?

Vielen Dank im Voraus
user defined image
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Mo 01.03.04 18:30 
was hältst du davon, nur den veränderten bereich neu zu zeichnen, d.h. an die alte position ein grauen kreis, das koosy neu zeichen und dann die Planis, damit sollte die sache schon einiges besser laufen...

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
Urba
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 47



BeitragVerfasst: Di 02.03.04 06:28 
Hallo,

Wäre es nicht auch eine Möglichkeit die Planten jeweils in eine TImage-Kompo auszulagern und sie nur über den Untergrund fahren zu lassen ? Wenn dann DoubleBuffered = true ist sollte es eigentlich nicht mehr flimmern.

Gruss
Urba

_________________
Es gibt keine blöden Fragen, nur blöde Antworten :)
Alebo Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Di 02.03.04 09:57 
Danke für die Tips,

werde ich gleich mal ausprobieren
Marc Walter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 40

Win98, WinXP
D2 Pers, D7 Pers
BeitragVerfasst: Di 02.03.04 13:07 
Du könntest, falls du keine Grafiken außer Kreisen benutzen willst, auch einfach TShape benutzen. Da kann man auch Kreise erstellen, und die Farbe kannst du ja über Brush / Pen noch ändern.
Dann musst du immer nur die .top und die .left Werte des Kreises verändern.

Kann sein, dass das auch nur in Uralt-Delphis geht, keine Ahnung.

_________________
möp
ShadowThief
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 278



BeitragVerfasst: Di 02.03.04 15:59 
ich würde das komplette bild im speicher (in einer tbitmap) erstellen und dann entweder
mit bitblt aus der winapi oder mit copyrect auf die form kopieren. das flimmert definitiv nicht.

shadow.

_________________
"soylent grün ist menschenfleisch!"
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Di 02.03.04 17:04 
aber damit kann man doch nur rechteckige bereiche kopieren, war das nicht so?
und ein 4eckiger Planet ich weis net.......

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
GSE
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 740

Win 2k, Win XP Pro
D5 Prof, D6 Ent, D2k5 PE
BeitragVerfasst: Di 02.03.04 17:36 
Ich denke er meint, dass das ganze Bild (also auch KoSy)im Speicher "gemalt"
und in die PaintBox kopiert wird. Da das Flimmern ja eigentlich nur daran liegt, dass er nach
jedem Zeichenprozess das Bild wieder neu malt, also nach jedem Planeten, jedem Punkt, etc
beim "Aus-dem-Speicher-kopieren" wird das Bild nur einmal neu gemalt, nämlich wenn es "fertig" ist.

mfg
GSE

_________________
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs
and the universe trying to produce bigger and better idiots. So far, the universe is winning. (Richard Cook)
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Di 02.03.04 17:51 
aber man kann doch kein image über ein bild malen das mit bitblt auf den Bildschirm geblittet wurde übermalen, oder?
und maskblt habe ich nie zum laufen gebracht (jedenfalls nicht unter win 9x) und das war auch recht unpraktisch im gebrauch

So sollte es funktionieren:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure draw;
begin
image1.canvas.brush.color := clBtnFace;
image1.canvas.Pen.color := clBtnFace;

drawPlanets;

drawKoosy;

movePlanets;

image1.canvas.brush.color := clYellow;
image1.canvas.Pen.color := clblack;

drawPlanets;
end;


drawplanets zeichnet blos die ellipsen für die Planeten, setzt aber keine Farben.
moveplanets bewegt die ganzen planeten weiter
drawKoosy zeichnet das koordinatensystem

Ich hoffe ich konnte helfen

MathiasH

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
GSE
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 740

Win 2k, Win XP Pro
D5 Prof, D6 Ent, D2k5 PE
BeitragVerfasst: Di 02.03.04 18:18 
Ehrlich gesagt versteh ich dein Problem nicht (mangelnde INtelligenz meinerseits? :shock:)

Ich denke ShadowThief (meld' dich mal und gib dein Statement ab, vielleicht interpretier ich deinen
Vorschlag ja auch total falsch) hat gemeint, dass du alle Zeichenroutinen auf ein im Speicher befindliches TBitMap (o.ä.)
leiten sollst, anstatt die Befehle direkt auf die Paintbox zu malen.
Ungefähr so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
var
 bmp: TBitMap;
begin
 bmp := TBitMap.create;
 bmp.width := [die Breite];
 bmp.height := [die Höhe];
//Jetzt deine Proceduren
DrawKoSy//, und wie sie alle heißen
//Eben nur, dass sie anstatt auf die Paintbox auf das Bmp "malen"
//Beispiel:
//aus "Paintbox.canvas.Rectangle(..)" wird "bmp.canvas.Rectangle(..)"

//Jetzt in die Paintbox malen
 PaintBox.canvas.copyrect(Rect(0,0,bmp.width,bmp.height), bmp.canvas,Rect(0,0,bmp.width,bmp.height));

 bmp.free;
end;


Hoffe hab das alles richtig interpretiert und erklärt.
Hab grad kein Delphi zur Hand von wegen Testen

mfg
GSE

_________________
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs
and the universe trying to produce bigger and better idiots. So far, the universe is winning. (Richard Cook)
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Di 02.03.04 18:22 
optimal wäre es dann wohl unsere beiden techniken zu verreinen
- nicht alles neuzeichenen und erst blitten wenn man fertig ist mit einem frame

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
ShadowThief
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 278



BeitragVerfasst: Mi 03.03.04 00:09 
hab dem nichts hinzuzufügen.

shadow.

_________________
"soylent grün ist menschenfleisch!"
Alebo Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Mi 03.03.04 15:48 
Vielen Dank nochmal für eure schellen Antworten!

Ich habe das Problem jetzt ein Stück weit gelöst.
Jedesmal, wenn ich neue Koordinaten errechnet habe, lass ich die Planeten und das Koordinatensystem in einen Schattenspeicher speichern um dann alles auf einmal in die Paintbox zu übertragen. So ist das flickern schonmal weg.
Allerdings habe ich trotzdem noch ein weiteres Problem.
Die Planeten sollen eine Spur hinterlassen, damit man die Bahn sehen kann.
Bisher habe ich jeweils die letzten 700 Positionen der 3 Planeten speichern lassen, unm sie auch im den Schattenspeicher darzustellen und dann mit dem Kooridantensystem und den Planeten auf die Paintbox auszugeben.
also etwa so:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
var
pos1 : Array[1..700] of TPoint;
pos2 : Array[1..700] of TPoint;
pos3 : Array[1..700] of TPoint;
i : integer;

....

i := 1;

procedure TForm2.Timer1Timer(Sender: TObject);
var
z : integer;
begin
  pos1[ i ].x :=M1PosX;
  pos1[ i ].y := M1PosY;
  pos2[ i ].x := M2PosX;
  pos2[ i ].y := M2PosY;
  pos3[ i ].x := M3PosX;
  pos3[ i ].y := M3PosY;

  inc(i);
  if i > 700 then i := 1;
  with Bit.Canvas do begin
          DrawCoordSys2;
          for z := 1 to 700 do begin
              Pixels[pos1[z].x, pos1[z].Y] := clyellow;
              Pixels[pos2[z].x, pos2[z].Y] := clblue;
              Pixels[pos3[z].x, pos3[z].Y] := clred;
              end;
          brush.Color := clyellow;
          ellipse(M1PosX+11,M1PosY+11,M1PosX-10,M1PosY-10);
          ...... Das gleiche für die anderen Planeten
           
    form1.PaintBox1.Canvas.Draw(0, 0, Bit);
 end;


Leider hat dieses Verfahren 2 Nachteile:
Es werden nicht alle Positionen dargestellt, an denen die Planeten schon waren, außerdem ist es sehr langsam, da jedesmal 21000 Punkte neu gemalt werden müssen.
Gibt es nicht eine Möglichkeit, dass die Punkte von einem zum nächstem Bild erhalten bleiben, und immer nur 3 neue gezeichnet werden müssen?

user defined image

Moderiert von user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Mi 03.03.04 18:29 
wenn du das von mir beschrieben verfahren verwendest reciht es wenn du die letzten paar Positionen(so viele wie ein plani halt verdeckt) speicherst, da in meinem verfahren nicht alles neugezeichnet wird.

Also nochmal:
alte planis mit grau übermalen
koosys malen
letzte positionen mit punkten markieren
planipositionen updaten
planis malen

das ganze auf einem backbuffer, der am besten mit bitblt bei ontimer auf dem bildschirm geholte wird. alternativ copyrect und ein image, aber das ist meines wissens nach etwas langsamer...

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche