 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 20:55 Titel: Grafische Verlaufskurve: Möglichst Ressourcenschonend |
|
|
Hallo Comunity!
Folgendes: Ich möchte ein 800*600px-Fenster erstellen (<- das ist noch nicht das Problem ) das mir einen sich ständig ändernden Wert (der einfachheit halber: von 0-600) und den bisherigen Verlauf (die letzten 800 Werte) grafisch anzeigt. (Der Verlauf muss nicht abgespeichert werden, nur angezeigt)
Wie zum Beispiel die CPU-Auslastung im Taskmanager.
Die Sache an sich ist ja leicht zu realisieren, aber ich möchte nur so wenig CPU-Leistung wie möglich verbraten.
Mir sind bis jetzt 2 Möglichkeiten eingefallen:
1.
Code: |
DIM AS INTEGER werte(1 TO 800)
DIM AS INTEGER aktueller_wert, tempwert, wertnummer
SCREENRES 800, 600, 32
DO
aktueller_wert = [FUNKTION: ermittle aktuellen Wert]
FOR wertnummer = 1 TO 799
werte(wertnummer) = werte(wertnummer+1)
NEXT
werte(800) = aktueller_wert
FOR wertnummer = 1 TO 800
LINE (wertnummer, 0)-(wertnummer, 600), RGB(255, 255, 255)
PSET (wertnummer, werte(wertnummer)), 0
NEXT
LOOP
|
2. Man GETtet den Bildausschnitt (2,1)-(799, 599) und PUTtet ihn an (1,1). Dann malt man ganz rechts den neuen Wert hin, alles geht wieder von vorne los
Aber das ist irgendwie beides nicht so toll...
Freue mich schon auf eure Antworten!
-schumi- |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 21:10 Titel: |
|
|
jedes mal das array um eins zu verschieben ist auch alles andere als toll. nimm doch lieber einen ringpuffer... Geht ungefähr so. Da muss nicht das Array jedes mal verschoben werden -> Quasi 0 CPU-Last dadurch. GET und PUT ist wesentlich effizienter als jedes mal 800 Linien zu zeichnen. So wird das im Prinzip auch häufig in anderen Programmen realisiert, wenn gescrollt wird.
PS: Wer meint, dass in dem Ausdruck "(curpos + rbuflen - 1) Mod rbuflen" ein "rbuflen" zu viel vorkommt, mag zwar in Mathe gut aufgepasst haben, hat aber übersehen, dass FB bei Modulo auch negative Werte zurückliefert und -1 MOD 800 somit nicht 799 ergibt.
_________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 21:55 Titel: |
|
|
Das Ring-Array gefällt mir
Aber wie krieg ich jetzt die Werte möglichst schnell und mit wenig Rechenleistung auf den Bildschirm? Irgendwie müssen die alten Werte ja wieder weg...
Wie schnell ist PSET? Wenn es schnell ist könnte ich die alten Punkte mit weis wegPSETten... (Ich hab die Werte ja alle)
Zitat: | So wird das im Prinzip auch häufig in anderen Programmen realisiert, wenn gescrollt wird. |
Ja, was willst du denn da sonst benutzen? Alle Pixel in ein 1280*1024px-Array, Array um 1280*5 verschieben und dann in einer FOR-Schleife hinpesetten?
MfG
-schumi- |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 22:01 Titel: |
|
|
ich versteh dein problem nicht so ganz. du willst ja scheinbar eine kurve zeichnen. also zeichnest du initial die
komplette kurve (alles nullwerte) und kopierst die komplette grafik bis auf die erste pixelzeile und setzt sie einen pixel nach links. dann zeichenst du vom vorletzten pixel zum letzten (jetzt neuen) pixel eine linie und du hast wieder eine schöne kurve. natürlich geht das nicht umsonst, von daher sollte so ein update natürlich nicht kontinuierlich passieren (tut's im task-manager ja auch nicht). Du kannst's natürlich auch mit PSET versuchen (sieht aber unschön aus, also eher LINE) - sei einfach kreativ! Ob eine Lösung schlechter als die andere ist, solltest du ja selbst merken können. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.

Zuletzt bearbeitet von Jojo am 30.06.2010, 22:08, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 22:08 Titel: |
|
|
Du hast es erfasst, fast zumindest:
1. Ich will keine Linien, weil die wieder zu viele Ressourcen verbrauchen.
2. Ich will kein GET/PUT, weil das sehr Zeitkritisch werden könnte)
Zitat: | daher sollte so ein update natürlich nicht kontinuierlich passieren (tut's im task-manager ja auch nicht) |
Das tuts aber (ca. 2-5 mal /sec). Deswegen soll es ja schnell gehen.
Im Taskmanager tuts das glaub ich nicht, weil es sehr lange dauert bis man die aktuelle CPU-Auslastung hat. (Ist ja z.B. mit dem VBS-Script im Q(uick)B/FB-Beispiel auch so) |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 22:10 Titel: |
|
|
Der Taskmanager hat auch relativ kleine Displays, da geht das auch recht flott. Und ich bin mir ziemlich sicher, dass die mit einem zu GET/PUT ähnlichen Befehlspaar gescrollt werden. Wenn du jeweils nur eine Linie zeichnest und den rest wie vorgeschlagen mit GET/PUT wird die Linie nicht ins Gewicht fallen. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 22:30 Titel: |
|
|
Natürlich fällt eine einzige Linie pro Durchgang nicht ins Gewicht.
Aber GET/PUT gefällt mir gar und gar nicht:
800*600=480000 Pixel für 800 Pixel der Kurve ist nicht gerade ergonomisch. Das währe ein "Wirkungsgrad" von 0.1666667% !!! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 22:46 Titel: |
|
|
Leider scheint dir da ein bisschen das Wissen zur Funktion von Speicher und CPU zu fehlen, sonst wäre es dir vielleicht etwas deutlicher. Auf ein einzelnes Wort (einen Pixel) zuzugreifen ist total ineffizient. Eine ganze Reihe Pixel in einem Rutsch zu lesen/schreiben ist dagegen ziemlich schnell. Ob du es willst oder nicht, wenn du auf einen Pixel in deinem Bild zugreifst, werden die angrenzenden Pixel(-reihen) sowieo mitgespeichert und mitgeladen (und zwar vom bzw in den Cache), von daher ist auch GET/PUT ziemlich schnell. Du kannst auch nix dagegen tun, dass die umliegenden Pixel mit in den Cache geladen werden, und das ist auch gut so. Wenn du einfach die ganze Grafik kopierst, wird nach und nach auf alle Zeilen zugegriffen, was ziemlich schnell geht. Wenn du dagegen auf deine 800 Punkte zugreifst, muss mal auf Zeile 1 des Bildes, dann vielleicht direkt danach auf Zeile 500, dann auf Zeile 325 etc zugegriffen werden. Das ist nicht sonderlich effizient, je nach Größe des Caches.
Natürlich ist auch blockweises Kopieren nicht immer effizienter - Aber ich schreibe dir auch nicht vor, welche Implementierung schneller ist und ich werde garantiert nicht für dich ausprobieren, welche in deinem Konkreten Fall schneller ist - das musst du schon selbst tun. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 23:06 Titel: |
|
|
oha, *duck*
Ja, das muss ich leider zugeben... Naja, jedenfalls wieder was gelernt.
Es wird sich also doch auf GET/PUT hinauslaufen... Das du das nicht für mich ausprobieren brauchst sollte sich von selbst verstehen .
Jedenfalls herzlichen Dank für die schnelle und kompetente Hilfe!
-schumi- |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 23:07 Titel: |
|
|
-schumi- hat Folgendes geschrieben: | Es wird sich also doch auf GET/PUT hinauslaufen... Das du das nicht für mich ausprobieren brauchst sollte sich von selbst verstehen . |
Ich hab es wie gesagt nicht ausprobiert. Es aus was für Gründen auch langsamer laufen, aber das bezweifle ich doch ziemlich stark, da GET/PUT ziemlich vom Cache profitiert. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 23:23 Titel: |
|
|
Ja, ich glaub ich werd beides mal ausprobieren (sooo viel Code ist es ja nicht).
Aber das würde ja Theoretisch heissen:
Eine
LINE (100, 100)-(600, 100) (sieht so aus: - )
würde ja nicht so lange dauern wie
LINE (100, 100)-(400, 500) (sieht so aus: \ )
(beide sind exakt 500px lang) weil bei ersterem alle Pixel in einer Reihe liegen... Oder ist das föllig falsch oder checkt FB das nicht?
Nochmal Danke!
Für weitere Ideen/Anregungen bin ich natürlich dankbar |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 23:25 Titel: |
|
|
Eine horizontal verlaufende Linie sollte generell aus mehreren Gründen schneller gezeichnet werden (unter anderem, da dann netterweise keine komplizierte Steigung vorliegt). _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
Muttonhead

Anmeldungsdatum: 26.08.2008 Beiträge: 566 Wohnort: Jüterbog
|
Verfasst am: 30.06.2010, 23:40 Titel: |
|
|
schlägt dann der Herr Bresenham zu?  |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 30.06.2010, 23:40 Titel: |
|
|
Nachdem ich die Frage gestellt hab ist mir eingefallen, das ich das einfach mal ausprobieren könnte...
Code: |
DIM AS INTEGER forx1, forx2
DIM AS SHORT starttime
SCREENRES 800,600,32
COLOR 0, RGB(255, 255, 255)
CLS
forx2=0
starttime=TIMER
DO
LINE(100, 100)-(500, 400), 0
forx2=forx2+1
LOOP UNTIL starttime+2<=TIMER
forx1=0
starttime=TIMER
DO
LINE(100, 100)-(600, 100), 0
forx1=forx1+1
LOOP UNTIL starttime+2<=TIMER
PRINT "LINE(100, 100)-(600, 100), 0 : ", forx1
PRINT "LINE(100, 100)-(500, 400), 0 : ", forx2
SLEEP
|
Das Ergebnis is - ähm - irgendwie überraschend&beängstigend...
In 2 Sekunden schafft die \-Linie es 35300 mal
In 2 Sekunden schafft die --Linie es 534900 mal
also rund 15 mal so viel! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 23:56 Titel: |
|
|
nicht wirklich überraschend (für mich). Es wäre sehr schlecht, wenn sich ein Code immer gleich schnell unter allen Bedingungen verhalten würde, denn das hieße auch, dass er sich an die langsamste Ausführung "anpassen" müsste. So einen Code zum Zeichnen von Linien kann man aber auf verschiedene Arten beschleunigen, sodass z.B. Spezialfälle (vertikale/horizontale Linien) besonders schnell abgearbeitet werden, und schräge Linien evtl mit Gleitkommaarithmetik berechnet werden). _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
OdinX

Anmeldungsdatum: 29.07.2005 Beiträge: 253 Wohnort: SG Schweiz
|
Verfasst am: 02.07.2010, 12:50 Titel: |
|
|
Wie wärs, wenn du dir einfach die position merkst und nen Rundlauf machst? Beispiel nicht getestet und wahrscheinlich voller Fehler^^
Code: | DIM AS INTEGER werte(1 TO 800)
DIM AS INTEGER position
SCREENRES 800,600,32
position = 0
DO
position = position + 1
IF position > 800 THEN position = 1
PSET (0,werte(position)),RGB(255,255,255)
werte(position) = [FUNKTION: ermittle aktuellen Wert]
FOR A = 0 TO 800 STEP 1
B = A + position
IF B > 800 THEN B = B - 800
C= A+position-1
IF C > 800 THEN C = C - 800
PSET (A,werte(C)),RGB(255,255,255)
PSET (A,werte(B)),0
NEXT
LOOP |
|
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 02.07.2010, 14:33 Titel: |
|
|
Hi
Hat erst n bischen gedauert, bis ich durch den Code gestiegen bin, aber ich gaub ich weis wie du das meinst...
Ich hab aber dann da für jeden neuen Wert (werte(position) = [FUNKTION: ermittle aktuellen Wert] ) wieder 1600 mal ein PSET (2x in der FOR-Schleife)
Du wolltest mit dem Position merken und Rundlauf machen warscheinlich darauf hinaus, dass ich das Array dann nicht verschieben brauche, oder? Aber das ist ja in Prinzip das oben genannte Ring-Array
>>wahrscheinlich voller Fehler^^ << du hast A, B & C nicht declariert
Ich muss leider zu meiner Schande gestehen, dass ich es bis jetzt noch nicht ausprobiert hab, sondern grad erst anfange..
MfG
-schumi- |
|
Nach oben |
|
 |
-schumi-

Anmeldungsdatum: 28.10.2009 Beiträge: 131 Wohnort: Südbayern
|
Verfasst am: 05.07.2010, 21:55 Titel: |
|
|
So, damit ihr auch wisst was aus dem Teil jetzt geworden ist:
Das mit dem "Linie hinzeichnen + Bild in Array + Array um 1 nach links pflanzen" funzt echt nicht schlecht
Es ist sogar so schnell, dass ich eine richtige flüssige Bewegung krieg, wenn ich einen 640*480 Fenster nehme. (Bei einem 700Mhz Laptop!)
MfG + Danke für die kompetente & schnelle Hilfe
-schumi- |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|