Zahlenwerte aus Array grafisch darstellen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Zahlenwerte aus Array grafisch darstellen

    hallo und Frohe Ostern,

    ich habe eine Simulation in C geschrieben. Es werden physikalische Vorgänge in kleine Zeitintervalle zerschnitten und die Ergebnisse in Arrays gespeichert.
    Z.B. einhält ein Array die Zeitwerte für die x-Achse und 1 oder mehrere Arrays die Ergebnisdaten für die y-Achse. Dabei kommen schnell mal 200.000 Werte im
    Format double je Array vor. Diese möchte ich gerne grafisch in einem Fenster darstellen.
    Siehe dazu Bilder im Anhang...

    Ich arbeite auf einem Mac mit OSX 10.8.5 und xCode 5.1. Ich habe überhaupt keinen Schimmer wie das funktionieren könnte oder nach welchen
    Schlagworten ich im Netz suchen sollte - habe keinen Ansatz ?( …..hilft mir hier jemand auf die Sprünge ?

    Im Moment mache ich es so, dass die Werte in ein Textfile geschrieben werden und dann in SciLab mit dem plot-Befehl ausgegeben werden - das dauert jedoch bei
    noch grösseren Ergebnismengen mit 1.000.000 Werte pro Array ganz schön lange…

    Außerdem hätte ich schon gerne gewusst, wie das direkt in C funktioniert mit der Grafik!

    Ich hoffe, dass mir jemand Hilfe ;-)))


    Grüße

    deddi
    Dateien
  • Das eigentliche Malen ist gar nicht so schwierig - Punkte oder Linien nacheinander auf den Bildschirm malen. Wenn du aber riesige Datenmengen effizient als Graph malen willst, solltest du die Daten vorher resampeln, sodass deine Datenpunkte in der Größenordnung der Bildschirmauflösung landen.

    Eine Million Linien zu zeichnen kann lange dauern, einige hunderte Mittelwerte aus einer Million Datensätze zu ziehen geht im Vergleich dazu recht schnell (und wenn man es eingermaßen geschickt anstellt, muss man es nicht so oft machen wie man zeichnen muss). Dazu kann man aus den Werten, die in der Darstellung auf einen Punkt zusammenfallen, z.B. Mittelwerte oder Werteintervalle suchen o.ä. - hängt davon ab, was und wie du darstellen willst. Was man normalerweise nicht machen darf ist einfach Datenpunkte wegzulassen, weil man damit fast immer das Abtasttheorem verletzt.

    Wenn du im Graphen zoomen und scrollen willst, könnte es sinnvoll sein, etwas zu LOD (Level of Detail) zu lesen.
    Multigrad - 360°-Produktfotografie für den Mac
  • Meine Antwort kommt etwas spät aber vielleicht hilfts noch.
    Wie schon oben erwähnt führt der offizielle Weg über einen NSView oder seine Subklassen. So einen brauchst du immer wenn etwas sichtbar werden soll. Im drawRect: hast du die Möglichkeit etwas darzustellen. Bei deinen Daten sehe ich mehrere Möglichkeiten.

    1) Direkt in den View zeichnen z.B. mit Funktionen wie NSRectFill() etc. oder [NSBezierPath stroke] etc. Mit NSGraphicsContext *gc = [NSGraphicsContext currentContext]; kannst du den Zeichencontext holen und antialiasing einschalten oder clippen und vieles mehr.
    z.B.
    - (void)drawRect:(NSRect)r
    {
    NSGraphicsContext *gc = [NSGraphicsContext currentContext];
    [gc setShouldAntialias:YES];

    [[NSColor whiteColor] set];
    NSRectFill(r); /* weißen Hintergrund zeichnen*/

    [gc saveGraphicsState]; /* aktuellen graphictstate sichern (enthält ctm) */
    [ctm concat]; /* ev. eine matrix setzen z.b. für zoom */

    NSBezierPath *up = [NSBezierPath bezierPathWith..... oder moveToPoint: und lineToPoint: ....
    [up setLineWidth:0.5];
    [[NSColor redColor] set];
    [up stroke];
    [gc restoreGraphicsState]; /* zurück zum original gstate mit alter ctm */
    }

    2) In ein Bild zeichnen und dieses im View darstellen. Das bietet sich an wenn das Zeichnen selber recht lange dauert oder man selber Pixel setzen will. Dafür erstellt man ein NSImage mit der gewünschten Größe. Mit [NSImage lockFocus] die Zeichenfunktionen dorthin umlenken und mit den selben Funktionen wie im drawRect reinzeichnen. Im drawRect: des NSView dann das Image mit drawAtPoint: oder drawInRect: anzeigen.


    Ersteres ist einfacher aber bei größeren Datenmengen natürlich langsamer, weil ständig alles neu gezeichnet wird sobald der View ein display: bekommt. Und das kann bei nahezu jedem Event der Fall sein. Zweiteres ist ein caching wie es auch bei Videospielen verwendet wird und zeichnet nur wenn du es aufrufst.


    Falls du selber Pixel setzen willst dann gäbs noch die Möglichkeit ein NSBitmapImageRep zu verwenden. Das kann man zum NSImage hinzufügen oder mit [NSBitmapImageRep bitmapData] den Pointer auf die Daten holen und die Pixel selber manipulieren. Das ist sauschnell aber auch deutlich anspruchsvoller.

    Hoffe nicht verwirrt zu haben.


    Gruß