| Autor |
Beitrag |
Alebo
Hält's aus hier
Beiträge: 15
|
Verfasst: 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

|
|
MathiasH
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: 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
      
Beiträge: 47
|
Verfasst: 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 
Hält's aus hier
Beiträge: 15
|
Verfasst: Di 02.03.04 09:57
Danke für die Tips,
werde ich gleich mal ausprobieren
|
|
Marc Walter
      
Beiträge: 40
Win98, WinXP
D2 Pers, D7 Pers
|
Verfasst: 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
      
Beiträge: 278
|
Verfasst: 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
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: 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
      
Beiträge: 740
Win 2k, Win XP Pro
D5 Prof, D6 Ent, D2k5 PE
|
Verfasst: 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
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: 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:
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
      
Beiträge: 740
Win 2k, Win XP Pro
D5 Prof, D6 Ent, D2k5 PE
|
Verfasst: Di 02.03.04 18:18
Ehrlich gesagt versteh ich dein Problem nicht (mangelnde INtelligenz meinerseits?  )
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: 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]; DrawKoSy 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
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: 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
      
Beiträge: 278
|
Verfasst: Mi 03.03.04 00:09
hab dem nichts hinzuzufügen.
shadow.
_________________ "soylent grün ist menschenfleisch!"
|
|
Alebo 
Hält's aus hier
Beiträge: 15
|
Verfasst: 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:
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?
Moderiert von Peter Lustig: Code- durch Delphi-Tags ersetzt
|
|
MathiasH
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: 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
|
|
|