Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

matriximage.h

Go to the documentation of this file.
00001 
00007 #ifndef __MATRIX_IMAGE_H__
00008 #define __MATRIX_IMAGE_H__
00009 
00010 #include <cassert>
00011 #include <algorithm>
00012 #include <cmath>
00013 
00014 // Uses roundabout paths to the current directory to avoid Cray C bug
00015 #include "../src/matrix.h"
00016 #include "../src/pixel.h"
00017 #include "../src/colorlookup.h"
00018 #include "../src/boundingbox.h"
00019 #include "../src/image.h"
00020 
00021 namespace  Plot {
00022 
00023 
00036 template<class PixelType=RGBPixel<>, class PixelMatrix= typename MatrixType<PixelType>::rectangular >  
00037 class MatrixImage : public AARImage<PixelType,PixelMatrix> {
00038 private:
00039   
00041   typedef typename AARImage<PixelType,PixelMatrix>::PixelSubscript PixelSubscript;
00042   
00044   typedef typename AARImage<PixelType,PixelMatrix>::CartesianCoordinate CartesianCoordinate;
00045   
00047   typedef int MatrixSubscript;
00048   
00050   PixelSubscript border;
00051   
00053   MatrixSubscript height;
00054   
00056   MatrixSubscript width;
00057   
00059   double size_scale;
00060   
00063   inline bool inside(const MatrixSubscript r, const MatrixSubscript c) const {
00064     return (r>=0 && r<height &&
00065             c>=0 && c<width);
00066   }
00067   
00069   inline MatrixSubscript matrix_row(const MatrixSubscript r) const 
00070     {  return MatrixSubscript(floor((r-border)/size_scale));  }
00071   
00073   inline MatrixSubscript matrix_col(const PixelSubscript c) const 
00074     {  return MatrixSubscript(floor((c-border)/size_scale));  }
00075   
00077   inline PixelSubscript pixel_row(const MatrixSubscript r) const 
00078     {  return PixelSubscript(r*size_scale)+border;  }
00079   
00081   inline PixelSubscript pixel_col(const MatrixSubscript c) const 
00082     {  return PixelSubscript(c*size_scale)+border;  }
00083   
00085   inline CartesianCoordinate x_from_matrixcol(const MatrixSubscript col)
00086     {  return CartesianCoordinate(pixel_col(col))+size_scale/2;  }
00087   
00089   inline CartesianCoordinate y_from_matrixrow(const MatrixSubscript row)
00090     {  return CartesianCoordinate(nrows()-1-(pixel_row(row)+size_scale/2))+0.5;  }
00091   
00093   inline void draw_element(const MatrixSubscript row, const MatrixSubscript col, PixelType p)
00094     {  draw_rectangle(pixel_row(row), pixel_col(col), pixel_row(row+1), pixel_col(col+1),p);  }
00095   
00096   template<class BoundingBoxType> bool onboundary
00097   (const BoundingBoxType& bb, unsigned thickness, PixelSubscript r, PixelSubscript c) const;
00098   
00099   
00100 public:
00103   
00105   MatrixImage() : border(0), height(0), width(0), size_scale(1.0)  {  }
00106 
00107   template <class Matrix>
00108   MatrixImage(const Matrix &A, double scale=1.0, int borderwidth=0,
00109               const ColorLookup<PixelType>& L=RYWColorLookup<PixelType>(),
00110               PixelType bordercolor=default_border );
00111   
00112   template <class Matrix>
00113   MatrixImage(const Matrix &H, const Matrix &S, const Matrix &V, double scale=1.0,
00114               int borderwidth=0, PixelType bordercolor=default_border );
00116   
00117   
00119   // Should length be scaled?
00120   void draw_bar_on_matrix_element(const MatrixSubscript row, const MatrixSubscript col,
00121                                   double angle, double length, double width=1, PixelType p=default_fg)
00122     {  draw_bar(x_from_matrixcol(col), y_from_matrixrow(row), angle, length, width, p);  }
00123   
00124   
00130   template<class BoundingBoxType> inline void outline_boundary
00131   (const BoundingBoxType& bb, unsigned thickness, PixelType p=default_fg, bool infinite_outline=false);
00132   
00133 };
00134 
00135 
00136 
00139 template<class PixelType, class PixelMatrix>
00140 template <class Matrix>
00141 MatrixImage<PixelType,PixelMatrix>::MatrixImage
00142 (const Matrix &A, double scale, int borderwidth, const ColorLookup<PixelType>& L,
00143  PixelType bordercolor)
00144   : AARImage<PixelType>(typename Matrix::size_type(scale*A.nrows()+2*borderwidth),
00145                         typename Matrix::size_type(scale*A.ncols()+2*borderwidth)),
00146   border(borderwidth), height(A.nrows()), width(A.ncols()), size_scale(scale) {
00147   draw_border(borderwidth,bordercolor);
00148   typedef typename Matrix::size_type Subscript;
00149   for   (Subscript r=0; r<A.nrows(); r++)
00150     for (Subscript c=0; c<A.ncols(); c++) {
00151       const Bounded::LargeFloat val = mat::elem(A,r,c);
00152       draw_element(r,c,L(val));
00153     }
00154 }
00155 
00156 
00157 
00159 template<class PixelType, class PixelMatrix>
00160 template <class Matrix>
00161 MatrixImage<PixelType,PixelMatrix>::MatrixImage
00162 (const Matrix &H, const Matrix &S, const Matrix &V, double scale, int borderwidth,
00163  PixelType bordercolor)
00164   : AARImage<PixelType>(typename Matrix::size_type(scale*H.nrows()+2*borderwidth),
00165                         typename Matrix::size_type(scale*H.ncols()+2*borderwidth)),
00166   border(borderwidth), height(H.nrows()), width(H.ncols()), size_scale(scale) {
00167   assert(H.nrows()==S.nrows()); assert(H.nrows()==V.nrows());
00168   assert(H.ncols()==S.ncols()); assert(H.ncols()==V.ncols());
00169   draw_border(borderwidth,bordercolor);
00170   typedef typename Matrix::size_type Subscript;
00171   for   (Subscript r=0; r<H.nrows(); r++)
00172     for (Subscript c=0; c<H.ncols(); c++)
00173       draw_element(r,c,HSVPixel<>(mat::elem(H,r,c),mat::elem(S,r,c),mat::elem(V,r,c)));
00174 }
00175 
00176 
00177 
00178 template<class PixelType, class PixelMatrix>
00179 template<class BoundingBoxType>
00180 void MatrixImage<PixelType,PixelMatrix>::outline_boundary
00181 (const BoundingBoxType& bb, unsigned thickness, PixelType pixel, bool infinite_outline)
00182 {
00183   PixelType p=pixel;
00184 
00186   const PixelSubscript nr = AARImage<PixelType,PixelMatrix>::nrows();
00187   const PixelSubscript nc = AARImage<PixelType,PixelMatrix>::ncols();
00188     
00191   if (p.istransparent()) {
00192     PixelAverage<> pa;
00193     for   (PixelSubscript row=0; row<nr; row++)
00194       for (PixelSubscript col=0; col<nc; col++)
00195         if (onboundary(bb,thickness,row,col))
00196           pa+=get_pixel(row,col);
00197     p=contrasting_color(pa());
00198   }
00199 
00200   for   (PixelSubscript row=0; row<nr; row++)
00201     for (PixelSubscript col=0; col<nc; col++)
00202       if ((infinite_outline && !bb.inside(matrix_row(row),matrix_col(col))) ||
00203           (onboundary(bb,thickness,row,col)))
00204         draw_pixel(row,col,p);
00205 }
00206 
00207 
00208 
00225 template<class PixelType, class PixelMatrix>
00226 template<class BoundingBoxType>
00227 inline bool MatrixImage<PixelType,PixelMatrix>::onboundary
00228 (const BoundingBoxType& bb, unsigned thickness, PixelSubscript r, PixelSubscript c) const
00229 {
00230   if (inside(matrix_row(r),matrix_col(c)) && bb.inside(matrix_row(r),matrix_col(c)))
00231     return false;
00232   
00234   const PixelSubscript nr = AARImage<PixelType,PixelMatrix>::nrows();
00235   const PixelSubscript nc = AARImage<PixelType,PixelMatrix>::ncols();
00236 
00237   for   (PixelSubscript sr=max<MatrixSubscript>(0,r-thickness);
00238          MatrixSubscript(sr)<=min<MatrixSubscript>(nr,r+thickness); sr++)
00239     for (PixelSubscript sc=max<MatrixSubscript>(0,c-thickness);
00240          MatrixSubscript(sc)<=min<MatrixSubscript>(nc,c+thickness); sc++) {
00241       const MatrixSubscript row=matrix_row(sr);
00242       const MatrixSubscript col=matrix_col(sc);
00243       if (inside(row,col) && bb.inside(row,col))
00244         return true;
00245     }
00246   
00247   return false;
00248 }
00249 
00250 
00251        
00252 } /* namespace Plot */
00253 #endif /* __MATRIX_IMAGE_H__ */

Generated on Mon Jan 20 02:35:44 2003 for RF-LISSOM by doxygen1.3-rc2