[c++] Diagramma cartesiano con librerie SDL
Mi sto studiando le librerie SDL per poter fare un diagramma cartesiano aggiornato in real time. Praticamente ho il programma che acquisisce dei dati e li dovrei diagrammare.
Qualche idea su come fare? Qualche link su cosa dovrei studiare in particolare?
Ho visto solo come poter muovere un'immagine con i tasti della tastiera.
Grazie
Qualche idea su come fare? Qualche link su cosa dovrei studiare in particolare?
Ho visto solo come poter muovere un'immagine con i tasti della tastiera.
Grazie
Risposte
no! Ho messo la cartella di gnuplot (scaricata da qui http://archives.math.utk.edu/software/m ... lot/msdos/) sul desktop.
Poi ho messo nella stessa cartella questi due file presi da qui per fare una prova http://www.quantfinancejobs.org/modules ... hp?faqid=5
Anche se faccio partire gnuplot.exe e poi scrivo load 'mycmdfile.txt' non parte....mmmm
Poi ho messo nella stessa cartella questi due file presi da qui per fare una prova http://www.quantfinancejobs.org/modules ... hp?faqid=5
Anche se faccio partire gnuplot.exe e poi scrivo load 'mycmdfile.txt' non parte....mmmm
"akiross":
Ah, fai una cosa utile: controlla il valore di ritorno della system(): se e' diverso da 0 vuol dire che c'e' stato un errore (e magari si capisce meglio cosa non va).
mmmm....come faccio?!

int valore = system("comando");
if (valore != 0)
printf("Errore! %d\n", valore);
if (valore != 0)
printf("Errore! %d\n", valore);
errore 1
comando non è riconoscibile come un file interno o esterno, programma eseguibile o un file patch. Errore! 1
Però con system ("wgnuplot.exe") me lo apre, che significa?
Però con system ("wgnuplot.exe") me lo apre, che significa?
nel frattempo sto capendo gnuplot, e ho capito come plottare dei grafici partendo da file esterni.
Significa che probabilmente system() cerca di lanciare il comando "gnuplot file" anziche' lanciare "gnuplot" passandogli "file" come parametro... Probabilmente il contenuto di system deve essere il nome di un comando valido, parametri esclusi.
??????mi sono perso
Il seguente codice mi funziona correttamente su Windows (compilato con Visual Studio):
Quindi secondo me il problema è semplicemente dovuto ad un problema di path. Hai provato a lanciare quel comando dalla stessa cartella in cui hai l'eseguibile? system non permette però di mandare messaggi al processo che hai creato, cosa che credo sia necessaria per poter modificare i dati in real-time. Dovresti dare un occhiata alla funzione _swapnl e simili.
Che compilatore stai usando?
#include <stdlib.h> int main() { system("wgnuplot.exe simple.dem"); }
Quindi secondo me il problema è semplicemente dovuto ad un problema di path. Hai provato a lanciare quel comando dalla stessa cartella in cui hai l'eseguibile? system non permette però di mandare messaggi al processo che hai creato, cosa che credo sia necessaria per poter modificare i dati in real-time. Dovresti dare un occhiata alla funzione _swapnl e simili.
Che compilatore stai usando?
bhe per lo meno è la prima volta che sono riuscito ad avere un grafico come dico io.
Praticamente ho fatto partire l'analisi del mio programma c++ e gli ho fatto mettere i dati in un file. Poi ho aperto gnuplot e gli ho fatto aprire un file di testo con scritto:
plot 'C:\Users\Valerio\Documents\Visual Studio 2005\Projects\unione\unione\dati.dat' with linespoints
pause 3
reread
praticamente ogni 3 secondi mi fa un aggiornamento dei dati
Solo che è un pò rozzetto come impostazione, e in più non riesco a farlo partire direttamente da c++ (quel dannato system).
Praticamente ho fatto partire l'analisi del mio programma c++ e gli ho fatto mettere i dati in un file. Poi ho aperto gnuplot e gli ho fatto aprire un file di testo con scritto:
plot 'C:\Users\Valerio\Documents\Visual Studio 2005\Projects\unione\unione\dati.dat' with linespoints
pause 3
reread
praticamente ogni 3 secondi mi fa un aggiornamento dei dati








Solo che è un pò rozzetto come impostazione, e in più non riesco a farlo partire direttamente da c++ (quel dannato system).
"apatriarca":
Il seguente codice mi funziona correttamente su Windows (compilato con Visual Studio):
#include <stdlib.h> int main() { system("wgnuplot.exe simple.dem"); }
Quindi secondo me il problema è semplicemente dovuto ad un problema di path. Hai provato a lanciare quel comando dalla stessa cartella in cui hai l'eseguibile? system non permette però di mandare messaggi al processo che hai creato, cosa che credo sia necessaria per poter modificare i dati in real-time. Dovresti dare un occhiata alla funzione _swapnl e simili.
Che compilatore stai usando?
ok ok funziona anche a me...forse si sbagliavo le patch.
Adesso mi esce in real time ma si impalla subito, come posso fare

Il discorso e' che per disegnare un grafico va comunque bene: Qt e' facile da usare per fare molte cose e come ho detto, per disegnare basta fare subclassing ed ereditare un metodo. Non e' una funzione avanzata di C++ e anche a non conoscerla e' un concetto capibile in 5 minuti
L'unica "pecca" di Qt e' che per usarle al meglio dovresti conoscerle per intero, ed essendo grosse... Ma suppongo ci si possa fidare se dico che per lo scopo si possono usare facilmente
Intendevo proprio quella pecca. per usarla al meglio è necessario studiarla a fondo e ci vuole del tempo. È vero che l'ereditarietà non è una funzionalità molto complicata, ma sui libri sul C++ le classi e la programmazione ad oggetti vengono spesso trattati abbastanza tardi. Non è quindi detto che valentino86 ne sappia qualcosa della programmazione ad oggetti in C++. Vista l'inclusione delle librerie C usando la sintassi
Non conosco SFML (ci ho dato un occhio in fretta), quindi non saprei davvero giudicare. Come ho detto, pero', pensavo che il suo scopo fosse fare il programma di plotting, non "usare" il programma di plotting. E' ovvio che usare una libreria completa di widget potrebbe risultare molto utile se decidesse di metterci, ad esempio, un semplice bottone per cancellare la schermata (sparo a caso). Non so se SFML lo fa. E' che quando inizio un progetto penso gia' a cosa si potrebbe voler fare in futuro, quindi cerco la completezza degli strumenti (e qui stava il "vantaggio"). Ma, come ho detto, ha detto che questa e' una cosa "marginale" nel progetto. Neanche avrei scomodato C++ per una cosa simile
Avendo risposto alla sua precedente discussione immaginavo fosse solo un aggiunta e non il vero scopo dell'applicazione. È principalmente per quello che ritenevo migliore SFML rispetto a Qt. SFML ha scopi e funzionalità simili a quelle di SDL, anche se è scritto in C++ ed è quindi ad oggetti. Non è quindi adatta allo sviluppo di una GUI (anche se può essere integrata con Qt, wxWidget, Win32...). Ma se lo scopo è solo quello di visualizzare dei dati allora è più che sufficiente e forse più semplice da usare (ma è probabilmente solo una questione di gusti in ogni caso).
Anche io non avrei usato il C++ per questo comunque. Avrei probabilmente valutato l'uso di Python o i linguaggi .NET.
Sul "disegnare gli elementi con qualsiasi libreria", non sono affatto d'accordo. Forse sei abituato a librerie dove si usa line(qui, li, la, lassu) e circle(qui, li, raggio), ma ti assicuro che non e' una cosa banale. Con le SDL, tanto per cominciare, tutto questo non si puo' fare e servono delle estensioni. Con le OpenGL e' una pratica sconsigliata e obsoleta. Anche per disegnare una spezzata si dovrebbero usare i vertex buffer.
A dire il vero mi occupo principalmente di grafica 3D e non uso mai librerie con funzioni tipo line e circle. Ma questa applicazione è molto semplice da realizzare con qualsiasi libreria che fornisca quelle funzionalità (quindi non SDL). Mi vengono per esempio in mente anche cairo o GDI.
Non ho mai detto che nelle OpenGL avrei usato l'immediate mode. Non vedo sinceramente nessun vantaggio di questo metodo rispetto ai vertex arrays. I VBO richiedono certamente un po' più di codice ma alla fine la differenza riguarda più che altro l'inizializzazione dei vari stati. Non volevo consigliarla comunque, ho parlato delle OpenGL solo perché il codice per disegnare il grafico non sarebbe molto più lungo nonostante sia di livello molto più basso (quello che cambia è principalmente la lunghezza del resto del codice).
"valentino86":
[quote="apatriarca"]Il seguente codice mi funziona correttamente su Windows (compilato con Visual Studio):
#include <stdlib.h> int main() { system("wgnuplot.exe simple.dem"); }
Quindi secondo me il problema è semplicemente dovuto ad un problema di path. Hai provato a lanciare quel comando dalla stessa cartella in cui hai l'eseguibile? system non permette però di mandare messaggi al processo che hai creato, cosa che credo sia necessaria per poter modificare i dati in real-time. Dovresti dare un occhiata alla funzione _swapnl e simili.
Che compilatore stai usando?
ok ok funziona anche a me...forse si sbagliavo le patch.
Adesso mi esce in real time ma si impalla subito, come posso fare

Quel file viene modificato dal tuo programma? Potresti postare il tuo programma in C++ in modo da testarlo?
il mio programma non potresti testarlo cmq perche prendo i dati da un accelerometro attaccato all'usb.
Però adesso posto quello che ho fatto che mi sembra ragionevole. Metto i dati in un file e li faccio leggere a gnuplot, e lui li aggiorna ogni 3 secondi.
Però adesso posto quello che ho fatto che mi sembra ragionevole. Metto i dati in un file e li faccio leggere a gnuplot, e lui li aggiorna ogni 3 secondi.
Mi raccomando non vi spaventate
HO ELIMINATO LE VARIE PROVE CHE AVEVO FATTO
non so dove mettere il system



HO ELIMINATO LE VARIE PROVE CHE AVEVO FATTO
/*Il dispositivo ha una frequenza di campionamento di 0,06 (eventi/ms) e quindi un periodo di 16,667 (ms/evento), da manuale sono 60(samples/s). */ #include <chplot.h> #include <math.h> #include "stdafx.h" #include "phidget21.h" #include <time.h> #include <iostream> #include <fstream> #include <stdlib.h> using namespace std; //Include il file iso631.cpp, con la sua funzione iso2631() extern int iso2631(); //VARIABILI PER L'ACCELEROMETRO #define MAX_INT 16384 int millis; int t=0; double accz[MAX_INT]; double tempo[MAX_INT]; FILE* dati= fopen("dati.dat","w"); //Chiamata che registra una variazione di accelerazione (è un loop) int __stdcall accel_AccelChangeHandler(CPhidgetAccelerometerHandle WGT, void *userptr, int Index, double Value) { //Filtro per un solo asse dell'accelerometro if(Index==0){ //Condizione per cui esegue l'analisi dell'rms if(t==MAX_INT) { //Perchè nell'else l'ultima istruzione è t++ t--; fclose (dati); system("wgnuplot.exe prova.txt"); dati= fopen("dati.dat","w"); //IMPORTA LA FUNZIONE ISO2631 iso2631(); //Riporta a 0 il contatore dell'array accez e tempo t=0; } else { //Funzione della libreria time.h clock_t clock(); //Quanti cilci fa il PC in un millesimo di secondo millis=CLOCKS_PER_SEC/1000; //Scrive in accz[] il valore dell'accelerazione accz[t]=Value; //Tempo in secondi tempo[t]=0.001*(clock()/millis); fprintf (dati,"%f %f\n",tempo[t],accz[t]); //Stampa a video il contatore degli array, tempo, l'asse e l'accelerazione printf("t= %i Secondi: %f Asse: %i Accel: %6f\n",t,tempo[t], Index,accz[t] ); //Incrementa il contatore degli array t++; } } //Chiusura dell'if per l'indice accelerometro } return 0; //Chiusura chiamata accel_AccelChangeHandler } //Entrata principale del programma int main(int argc, char* argv[]) { int result; const char *err; //Declare an accelerometer handle CPhidgetAccelerometerHandle accel = 0; //create the accelerometer object CPhidgetAccelerometer_create(&accel); //Impostando -1 apre il primo dispositivo disponibile CPhidget_open((CPhidgetHandle)accel, -1); //get the program to wait for an accelerometer device to be attached printf("Waiting for accelerometer to be attached.... \n\n"); //Aspetta 10 secondi che venga connesso il dispositivo if((result = CPhidget_waitForAttachment((CPhidgetHandle)accel, 10000))) { CPhidget_getErrorDescription(result, &err); printf("Problem waiting for attachment: %s\n", err); //Interruzione, spingere invio per continuare getchar(); return 0;} //Imposta la sensibilità CPhidgetAccelerometer_setAccelerationChangeTrigger(accel, 0, 0.00); CPhidgetAccelerometer_setAccelerationChangeTrigger(accel, 1, 0.00); CPhidgetAccelerometer_setAccelerationChangeTrigger(accel, 2, 0.00); //Registra un evento se l'accelerazione cambia oltre una certa soglia. CPhidgetAccelerometer_set_OnAccelerationChange_Handler(accel, accel_AccelChangeHandler, NULL); //Interruzione getchar(); //Chiude il dispositivo e l'oggetto printf("Closing...\n"); CPhidget_close((CPhidgetHandle)accel); CPhidget_delete((CPhidgetHandle)accel); //Interruzione getchar(); return 0; }
non so dove mettere il system
E se usassi una cosa del genere??
http://www.oscilloscope-lib.com/
PS: cmq uso visual c++ 2005 express edition
http://www.oscilloscope-lib.com/
PS: cmq uso visual c++ 2005 express edition
ho consumato google questi giorni 
http://ttsiodras.googlepages.com/gnuplotStreaming.html
Mi aiutate a capire come ha fatto?

http://ttsiodras.googlepages.com/gnuplotStreaming.html
Mi aiutate a capire come ha fatto?
"apatriarca":
A dire il vero mi occupo principalmente di grafica 3D e non uso mai librerie con funzioni tipo line e circle.
Ecco, anche io l'ho fatto per anni, pertanto saprai quanto me che ogni libreria ha i suoi modi



Per il resto delle questioni, sei stato chiarissimo

valentino86, gnuplot puo' anche ricevere i dati in input da console: hai pensato a stampare direttamente i comandi gnuplot dal tuo programma e lanciare il tutto usando la redirezione? tuoprogramma | gnuplot
In questo modo l'output del tuo programma viene messo in ingresso a gnuplot, che funzionerebbe come se fossi tu a scrivere a mano ogni istruzione.
(Sempre se esiste la redirezione su windows

La oscilloscope lib non sembra male! E non sembrava male neanche quella che usavi prima...
"valentino86":
ho consumato google questi giorni
http://ttsiodras.googlepages.com/gnuplotStreaming.html
Mi aiutate a capire come ha fatto?
Fantastico, proprio quello che intendevo dire

Bhe, come vedi usa uno script perl per eseguire i comandi di impostazione di gnuPlot. Se hai possibilita' di usare perl fai prima ad usare quello script

Comunque non e' necessario (credo). Da quel che vedo lo usa per configurare gnuplot.
Il succo del discorso e' che usa le pipe (cioe' redirezione dell'output) come ti ho detto prima.
Se non usi perl, puoi scrivere la configurazione che ti interessa dal tuo programma:
print("set range") etc etc, come fa nel file perl
poi semplicemente scrivi i punti come fa nell'esempio riportato:
while(1) { print sin($offset)."\n"; print cos($offset)."\n";
Fatto questo il tuo programma lo lanci con: tuoprog | gnuplot
Il programma stampera' i comandi e i dati necessari che verranno letti da gnuplot e stampati.
Ora devo andare, sono di fretta, ma i dettagli su cosa fa son tutti nello script!
Ciao
"akiross":
[quote="apatriarca"]A dire il vero mi occupo principalmente di grafica 3D e non uso mai librerie con funzioni tipo line e circle.
Ecco, anche io l'ho fatto per anni, pertanto saprai quanto me che ogni libreria ha i suoi modi



Ma i grafici non si fanno usando le curve di Bézier... I punti di controllo di una curva di Bézier non si trovano sulla curva mentre i samples che valentino86 cattura lo sono. Credo sia quindi più opportuno l'uso di una semplice linea spezzata o una catmull-rom spline. La prima è ovviamente molto semplice da implementare, mentre per la seconda è più complicata e non sempre presente. Io pensavo di disegnare il grafico facendo semplicemente una linea spezzata.
Sfortunatamente in Windows la shell è molto meno potente e credo sia quindi necessario usare le API di Windows.