Re: How to plot simple 2D Graphs in C/C++ ?


B

Boris Glawe

LiquidSky said:
Hello !!
I am having problems finding on the internet how to plot some 2D Graph
in c/c++.
I am using GNU/Linux for programming.
I have tryed allready OpenGl to plot graphics .. but is not so
performant because I have to plot 5 to 10 graph at the same time in
different windows. So OpenGl is out !! :)

I cannot use GTK or Qt to plot the graphs because it takes a lot of
memory, and my initial program ( that I have to plot graphs for) uses
OpenGl, so I think is not so nice to add some extra libs just for
ploting graphs, but if we do not have anything else maybe will we use
it. Is is good to use it to plot graphs?
In do not know if I could use SDL, i do not have the experiance with
it. Is it good to use it to plot graph? ( I saw that is good for audio
and displaying bitmaps !! )

Actually, what I need is if someone knows how to plot Graphs in Linux
and with what libs?

Thank you !!
Have a nice programming guys !!

PS. I would be perfect if someone gives me a code or a link !! :)

Hi,

I wrote a plotter for the terminal a
long long time ago.
The function is hardcoded.
Many comments and some variable names
are in german...
And programming style is horrible, since
I wrote it a long long time ago ;-)

The code is attached to the message...

maybe it helps.

greets Boris

/* plotter.cpp Boris Glawe, 8.1.2002

Ausführbar auf Terminals mit einer Auflösung von 80x25
oder höher...
*/


#include <iostream.h>
#include <math.h>

#define TASTFREQ 80
#define ROWLENGTH 80 // Breite des Bildschirms
#define SCREENHEIGHT 50 // Höhe der Tabelle


/******************************************************************/

class Graph {

private:

long double tab[TASTFREQ]; //vertikale Breite
char row[ROWLENGTH+1]; // horizontale Breite (plus newline)

long double max; //maximalwert in Fkt.
long double min; //minimalwert in Fkt.

long double xa; //kleinster x-Wert
long double xe; //größter x-Wert -> dargestelltes Intervall...



long double f(long double x){
return sin(x) + sin(2*x) + sin(3*x) + sin(4*x);
}






/*Folgende Funktion ordnet einem Zahlenwert einen Feldindex zu.
Sie erwartet fünf Argumente.
1.Index des ersten Feldes im Array
2.Index des letzten Feldes im Array
3.Den kleinsten einzuordnenden Wert
4.Faktor, der den "Wert" eines Feldes angibt
5.der einzuordnende Wert
Es wird das Intervall zwischen einem Maximalwert und einem
Minimalwert in zwei Hälften geteilt.
Es wird geprüft, in welcher Hälfte der Wert liegt und der
selbe Vorgang wird mit dieser Hälfte solange rekursiv wiederholt,
bis ein eindeutiges Feld bestimmt ist...
Der rekursive Aufruf und die vielen Parameter machen das Programm
unübersichtlich, ersparen aber viele Rechenschritte...
*/

int classify(int a, int e,
long double minvalue, long double dx, long double v){

int anfang = a;
int ende = e;
int mitte;

if( (e - a) % 2 == 0) mitte = (e + a) / 2;
else mitte = (e + a -1) / 2;

if (mitte == a) return mitte ;

if(v >= minvalue + dx*(mitte) ){
anfang = mitte;
return classify(anfang,ende,minvalue,dx,v);
}
else{
ende = mitte;
return classify(anfang,ende,minvalue,dx,v);
}
}






void make_tab(){
long double dx = xa;
int i;

for (i=0; i<TASTFREQ; i++){
tab = f(dx);
dx += (xe - xa) / TASTFREQ;
}
}



void init_graph(){

int i;

//Finde Extremwerte des Graphen...
//falls alle fkt.-werte > 0 sind dann muss 0 trotzdem
//Minimum sein, damit die Achsen richtig gezeichnet werden
//Das gleich gilt, falls alle Wert < 0 sind...
max = 0;
min = 0;

for (i=0; i<TASTFREQ; i++){
if (tab > max) max = tab;
if (tab < min) min = tab;
}


//den array row[] reseten...
for(i=0; i<ROWLENGTH; i++){
row=' ';
}
}



public:

//Standardkonstruktor:Standardbereich 0 bis 2 PI...
Graph (){

xa = 0.0; xe = 2.0*M_PI;

make_tab(); // Tabellenwerte erstellen
init_graph(); // Eigenschaften des Graphen berechnen..

}

//Konstruktor: Parameter geben den Bildbereich an.
Graph (long double a, long double e){

xa = a; xe = e;

make_tab();
init_graph();

}//Ende Konstruktoren





void print_values(){
int i;

cout << "Min:\t" << min << endl;
cout << "Max:\t" << max << endl;

for (i=0;i<TASTFREQ; i++){
cout << tab << endl;
}

cout << endl << endl; // Abstand zur nächsten Ausgabe...

}




void draw_endless_graph() {

int i,k,zero_point;

//Normierung der Werte auf Arraylänge
long double fieldwidth = (max - min) / ROWLENGTH;


//Nullpunkt auf Bildschirmarray finden...
zero_point = classify(0,ROWLENGTH,min,fieldwidth,0.0);

// Kopfzeile schreiben...
cout << "MAX: " << max << "\t\tMIN: " << min << endl;

for(i=0; i<ROWLENGTH; i++) {
if (i == zero_point) cout << "0";
else cout << "-";
}
cout << endl;


/* Durchlaufe alle Werte in tab[] und ordne sie einzeln
in row[] ein...schreibe dann row[] auf Bildschirm */
for(i=0; i<TASTFREQ; i++){
row[zero_point] = '|';
k=classify(0,ROWLENGTH-1,min,fieldwidth,tab);
row[k] = '*'; row[ROWLENGTH] = 0;
cout << row << endl;// Einzeichnen des Fkt.-wertes

row[k] = ' '; // Feld wieder leeren...
}
//...und wieder aufräumen !!
for (i=0; i<ROWLENGTH; i++) { row = ' ' ; row[ROWLENGTH] = 0; }

cout << endl << endl; // Abstand zur nächsten Ausgabe...

}




void draw_window_graph() {

int i,j,zero_point_x,zero_point_y;
long double fieldwidth_x = (xe - xa) / ROWLENGTH;
long double fieldwidth_y = (max - min) / SCREENHEIGHT;


//Nullpunkt auf Bildschirmvertikalen finden...
zero_point_y = classify(0,SCREENHEIGHT-1,min,fieldwidth_y,0.0);
zero_point_x = classify(0,ROWLENGTH-1,xa,fieldwidth_x,0.0);


// Kopfzeile schreiben...
cout << "MAX: " << max << "\t\tMIN: " << min << endl;

for(i=0; i<ROWLENGTH; i++) cout << "-";
cout << endl;


/*Da der Index 0 mit dem minimalen Wert identifizeirt ist,
und die Ausgabe der Zeilen von oben nach unten erfolgt,
muss der Index rückwärts laufen. Damit ist die letzte Zeile
im Bildschirm auch der niedrigste Wert*/
for (i=SCREENHEIGHT-1; i>=0; i--) {

//erst mal aufräumen und dann x- und y-Achse einzeichnen...
for(j=0;j<ROWLENGTH;j++) row[j] = ' ';
if( i == zero_point_y )
for (j=0;j<ROWLENGTH;j++) row[j]='-';

for(j=0; j<ROWLENGTH; j++){

if( zero_point_x == j ) row[j]='|';//y-Achse einzeichnen...

if( classify(0,SCREENHEIGHT-1,min,fieldwidth_y,tab[j]) == i ){
row[j] = '*';
} // <- fkt.-wert einzeichnen

} //ende for j

row[ROWLENGTH] = 0; // Newline schreiben...
cout << row << endl;

}//ende for i

cout << endl << endl; // Abstand zur nächsten Ausgabe...

} //ende fkt.



};

/******************************************************************/








int main() {

cout << "Programm zum Zeichnen von Funktionskurven...." << endl;

Graph obj;
Graph obj2(-2,0.5);


cout << "Ausgabe in vertikaler Richtung..." << endl ;
obj.draw_endless_graph();
cout << "Ausgabe in horizontaler Richtung..." << endl ;
obj.draw_window_graph();


cout << "Ausgabe mit anderem x-Achsenintervall..." << endl;
obj2.draw_endless_graph();
obj2.draw_window_graph();

return 0;

}
 
Ad

Advertisements

K

Kevin Goodsell

Boris said:
Hi,

I wrote a plotter for the terminal a long long time ago.
The function is hardcoded.
Many comments and some variable names are in german...
And programming style is horrible, since I wrote it a long long time ago
;-)

The code is attached to the message...

maybe it helps.

greets Boris

Please don't post attachments to non-binary groups, and please do not
give non-standard code as the answer to a question on this group.

-Kevin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top