/* lgraph.cpp - line graph program Copyright (C) 2003, Matt Mahoney. This program is distributed without warranty under terms of the GNU general public license. See http://www.gnu.org/licenses/gpl.txt To compile: g++ lgraph.cpp Usage: lgraph files... Input files consist of up to 4 columns of numbers separated by other characters representing points on the Y axis. Output is lgraph.bmp as a line graph with each column graphed black, red, green, and blue. If more than one file is given, then the graphs overlap. */ #include #include #include #include #include #include #include #include using namespace std; template inline int size(const T& t) {return t.size();} // Image - can be drawn to, and saved as a .bmp file class Image { public: Image(int w, int h): pixels(w*h*3), width(w), height(h) {} // size w by h void saveBMP(const char *filename); // Save as .bmp file // Add colors (-255 to 255) to pixel at x,y (origin at lower left) void put(int x, int y, int red, int green, int blue) { assert(x>=0); assert(x=0); assert(y255?255:c<0?0:c; c=pixels[i+1]+green; pixels[i+1]=c>255?255:c<0?0:c; c=pixels[i+2]+red; pixels[i+2]=c>255?255:c<0?0:c; } void put(int x, int y, int color) {put(x, y, color, color, color);} int getwidth() const {return width;} // in pixels int getheight() const {return height;} // in pixels private: vector pixels; // width * height * blue-green-red (3 bytes) int width, height; // Image size in pixels void out2(FILE *f, int x) {fprintf(f, "%c%c", x, x>>8);} // Write 2 bytes void out4(FILE *f, unsigned long x) // Write 4 bytes, LSB first {fprintf(f, "%c%c%c%c", int(x), int(x>>8), int(x>>16), int(x>>24));} }; // Save as a .bmp file void Image::saveBMP(const char *filename) { FILE *f=fopen(filename, "wb"); if (!f) { perror(filename); return; } fprintf(f,"BM"); // magic number for .bmp files out4(f, 54+pixels.size()); // file size out4(f, 0); // reserved out4(f, 54); // offset to start of image (no palette) out4(f, 40); // info header size out4(f, width); // image size in pixels out4(f, height); out2(f, 1); // image planes out2(f, 24); // output bits per pixel out4(f, 0); // no compression out4(f, width*height*3); // image size in bytes out4(f, 3000); // x pixels per meter out4(f, 3000); // y pixels per meter out4(f, 0x1000000); // colors out4(f, 0x1000000); // important colors for (int i=0; i v[N]; // Data points int col=0; // Column number (0 to N-1) string s; // Input number so far, e.g. "-2.7" int c; // Input char e.g. '5' bool hasdigit=false; // There is a digit in s while ((c=getc(f))!=EOF) { if (isdigit(c) || c=='.' || c=='e' || c=='E' || c=='+' || c=='-') { s+=char(c); if (isdigit(c)) hasdigit=true; } else if (size(s)>0) { if (hasdigit) { if (col0) { double lo=v[i][0], hi=lo; for (int j=1; jhi) hi=v[i][j]; } printf("Column %d: %d values range %f to %f\n", i, size(v[i]), lo, hi); // Draw the graph if (hi>lo) { int shade=-1-20000/size(v[i]); if (shade<-64) shade=-64; for (int j=0; j