Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Grafische Verlaufskurve: Möglichst Ressourcenschonend

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 20:55    Titel: Grafische Verlaufskurve: Möglichst Ressourcenschonend Antworten mit Zitat

Hallo Comunity!

Folgendes: Ich möchte ein 800*600px-Fenster erstellen (<- das ist noch nicht das Problem grinsen ) 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... verwundert

Freue mich schon auf eure Antworten!
-schumi-
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 21:10    Titel: Antworten mit Zitat

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. happy

_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 21:55    Titel: Antworten mit Zitat

Das Ring-Array gefällt mir grinsen
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? durchgeknallt

MfG
-schumi-
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 22:01    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 22:08    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 22:10    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 22:30    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 22:46    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 23:06    Titel: Antworten mit Zitat

oha, *duck* grinsen

Ja, das muss ich leider zugeben... Naja, jedenfalls wieder was gelernt. happy

Es wird sich also doch auf GET/PUT hinauslaufen... Das du das nicht für mich ausprobieren brauchst sollte sich von selbst verstehen lachen .

Jedenfalls herzlichen Dank für die schnelle und kompetente Hilfe!
-schumi-
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 23:07    Titel: Antworten mit Zitat

-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 lachen .

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 23:23    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 23:25    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 566
Wohnort: Jüterbog

BeitragVerfasst am: 30.06.2010, 23:40    Titel: Antworten mit Zitat

schlägt dann der Herr Bresenham zu? grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 30.06.2010, 23:40    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 30.06.2010, 23:56    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OdinX



Anmeldungsdatum: 29.07.2005
Beiträge: 253
Wohnort: SG Schweiz

BeitragVerfasst am: 02.07.2010, 12:50    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden MSN Messenger
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 02.07.2010, 14:33    Titel: Antworten mit Zitat

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 grinsen


Ich muss leider zu meiner Schande gestehen, dass ich es bis jetzt noch nicht ausprobiert hab, sondern grad erst anfange..

MfG
-schumi-
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
-schumi-



Anmeldungsdatum: 28.10.2009
Beiträge: 131
Wohnort: Südbayern

BeitragVerfasst am: 05.07.2010, 21:55    Titel: Antworten mit Zitat

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 lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz