Main Page | File List

Canvas.h

Go to the documentation of this file.
00001 /**
00002  *\file         Canvas.h
00003  *
00004  *\brief        The Canvas class is a discrete simulation of the real life canvas. 
00005  *
00006  *              The canvas is cutted into grid structure, with <b><var>vReso</var></b> grids along
00007  *              vertical (<b><var>Row</var></b>) direction and <b><var>hReso</var></b> horizontal grids along 
00008  *              horizontal(<b><var>Col</var></b>) direction. Each rectangular grid is called a pixel, or picture
00009  *              element, and is specified by its lower-left <b><var>(row, col)</var></b> position. 
00010  *              The coordinate system has the lower-left corner of the canvas as its origin, 
00011  *              with <b><var>Row</var></b> going up and <b><var>Col</var></b> going right. The lower-left corner 
00012  *              pixel has a coordinate of <b><var>(0,0)</var></b>, and the upper-right one of <b><var>
00013  *              (hReso - 1, vReso - 1)</var></b>. 
00014  *
00015  *              A <b><var>(x, y)</var></b> pair means <b><var>col = x+hReso/2, and row = y+vReso/2</var></b>.
00016  *
00017  *              To each piexel <b><var>(row, col)</var></b> on the Canvas, a RGB color value is associated,
00018  *              which can be accessed via index operator [<b><var>row</var></b>][<b><var>col</var></b>].
00019  *
00020  *              WritePPM() writes the Canvas to an image file of PPM format.
00021  *
00022  *\author       Xianming Chen
00023  *
00024  */
00025 
00026 
00027 #ifndef _CANVAS_H_
00028 #define _CANVAS_H_
00029 
00030 #include "RGB.h"
00031 
00032 #include <string>
00033 #include <cassert>
00034 #include <map>
00035 
00036 using namespace std;
00037 
00038 namespace columbia
00039 {
00040   class Canvas
00041   { 
00042   public:
00043       explicit Canvas(int resoH = 512, int resoV = 512) : hReso(resoH), vReso(resoV), filename("tmp.ppm"), data(0)  { init(); }
00044       ~Canvas()                                  { delete [] data; }
00045       void Clear(RGB const&);
00046       
00047 
00048       RGB* operator[] (int r)                    { assert(r>=0 && r<vReso); return data + r*hReso; }
00049       RGB& Pixel(int row, int col);              //! Use this instead of the [] operator if both row and col number checking is needed.
00050       
00051       /**
00052        * Scan-convert a line segment given two end points. The scan conversion stop right before the second end point.
00053        * If output = 0, Draw a line segment between two end points, (x1,y1) and (x2,y2).  Each pixel color is interpolated from two end colors.
00054        * Else only return scanned result to output.
00055        */
00056       void ScanLineSegment(int x1, int y1, RGB const& color1, int x2, int y2, RGB const& color2, multimap<int, int>* output=0);  
00057 
00058       void WireCircle(int center_x, int center_y, int radius, int reso, RGB const& col);
00059 
00060       /**
00061        * These implement simple filling algorithms for circles, axis alligned rectangles, and general triangles.
00062        */
00063       void SolidCircle(int center_x, int center_y, int radius, RGB const& col);
00064       void SolidRectangle(int minx, int miny, int maxx, int maxy, RGB const& col);
00065 
00066       void SolidTriangle(int x1, int y1, RGB const& col1, int x2, int y2, RGB const& col2, int x3, int y3, RGB const& col3);
00067 
00068       void WritePPM(const char* = 0) const;
00069 
00070       int hReso, vReso;                          //! Resolutions (pixel #)at horizontal and vertical directions.
00071       std::string filename;                      //! write as PPM image file name.
00072   private:
00073       RGB* data;
00074       bool swap_xy, flip_y;                      // if line has abs(slope) > 1.0, flip it around y=x for scan conversion, and then flip back to fill pixel.
00075 
00076       void init();
00077 
00078       /* Only for lines of |slope| <= 1.0 && x1!=x2.  */
00079       void scanLineSegment(int x1, int y1, RGB const& col1, int x2, int y2, RGB const& col2, multimap<int, int>* output);
00080   };
00081   
00082 
00083   inline RGB& Canvas :: Pixel(int row, int col)
00084   {
00085     if(row >= vReso)
00086     {
00087       cout << "row = " << row << endl;
00088       throw "row number overflow\n";
00089     }
00090     if(row < 0)
00091     {
00092       cout << "row = " << row << endl;
00093       throw "row number underflow\n";
00094     }
00095     if(col >= hReso)
00096     {
00097       cout << "col = " << col << endl;
00098       throw "col number overrflow\n";
00099     }
00100     if(col < 0)
00101     {
00102       cout << "col = " << col << endl;
00103       throw "col number underflow\n";
00104     }
00105     return *(data + row * hReso + col);
00106   }
00107   
00108 
00109 }
00110 
00111 #endif

Generated on Fri Jul 9 11:02:31 2004 by doxygen 1.3.6