WordDraw.h

Go to the documentation of this file.
00001 // Copyright (C) 2006 Alexei Miasnikov
00002 //
00003 // Contents: Definition of an Image class
00004 //
00005 // Principal Author: Alexei Miasnikov
00006 //
00007 // Status: in progress
00008 //
00009 // Revision History:
00010 //
00011 
00012 
00013 #ifndef _WORD_DRAW_H_
00014 #define _WORD_DRAW_H_
00015 
00016 #include "AImage.h"
00017 #include "PDFgraphing.h"
00018 #include "Word.h"
00019 #include <fstream>
00020 #include <string>
00021 
00022 const int ssConst =  20;
00023 
00024 
00025 //
00026 //
00028 //
00029 //
00030 class WordDraw
00031 {
00032 public:
00033   WordDraw( int n, const Word& w, bool draw_grid = true ): 
00034     ss( ssConst ),
00035     //    theWord(w),
00036     N(n),
00037     betBraids(0),
00038     theLength( 0 )
00039   {
00040     theImage = new CImage( w.length()*(ssConst+1) + 1 , n*(ssConst+1) + 1 );
00041     
00042     for (int i=0;i<theImage->getWidth();i++)
00043       for (int j=0;j<theImage->getHeight();j++){
00044         theImage->setRedPixel(i,j,255);
00045         theImage->setBluePixel(i,j,255);
00046         theImage->setGreenPixel(i,j,255);
00047       }
00048     
00049     drawCompressedBraid( w );
00050 
00051     if (draw_grid){
00052       for (int i=0;i<=(theLength+1)*(ss+1);i+=(ss+1))
00053         drawVerticalGrid( i, (i/(ss+1) % 10 ? 220 :0) );
00054       for (int i=0;i<theImage->getHeight();i+=(ss+1))
00055         drawHorizontalGrid( i );
00056     }
00057   
00058   }
00059 
00060   WordDraw( int n, const list<Word>& w, bool draw_grid = true ): 
00061     ss( ssConst ),
00062     //    theWords(w),
00063     N(n),
00064     betBraids(20),
00065     theLength( 0 )
00066   {
00067     int max_length = 0;
00068     for (list<Word>::const_iterator I=w.begin();I!=w.end();I++)
00069       if (max_length  < I->length())
00070         max_length = I->length();
00071     
00072     int one_braid_width = n*(6+1)+1;
00073     theImage = new CImage( max_length*(ssConst+1) + 1 , w.size()*one_braid_width + 1 + (w.size()-1)*betBraids );
00074       
00075     for (int i=0;i<theImage->getWidth();i++)
00076       for (int j=0;j<theImage->getHeight();j++){
00077         theImage->setRedPixel(i,j,255);
00078         theImage->setBluePixel(i,j,255);
00079         theImage->setGreenPixel(i,j,255);
00080       }
00081     
00082     int i_offset=0;
00083     for (list<Word>::const_iterator I=w.begin();I!=w.end();I++,i_offset+=one_braid_width+betBraids)
00084       drawCompressedBraid( *I, i_offset );
00085 
00086     if (draw_grid){
00087       for (int i=0;i<=(theLength+1)*(ss+1);i+=(ss+1))
00088         drawVerticalGrid( i , ( i/(ss+1) % 10 ? 220 : 0 ));
00089       
00090       i_offset=one_braid_width;
00091       for (int i=0;i<theImage->getHeight();i+=(ss+1)){
00092         if ( i >= i_offset){
00093           i+=betBraids-ss;
00094           i_offset+=one_braid_width+betBraids;
00095         }
00096         drawHorizontalGrid( i );
00097       }
00098     }
00099   
00100   }
00101   ~WordDraw() { delete theImage; }
00102   void saveTo( const string& f_name ) {theImage->saveTo(f_name);}
00103  
00104 private:
00105   //  void drawBraid(){
00106     
00107   //    int i=0;
00108   //    for (ConstWordIterator wI=theWord.begin();wI!=theWord.end();wI++,i++)
00109   //      drawGenerator( *wI,i );    
00110   //  }
00111   
00112   
00113   void drawCompressedBraid( const Word& theWord, int vert_offset = 0){
00114     vector<int> positions(N+2,-1); // +2 for the left and right padding
00115     
00116     int i=0;
00117     for (ConstWordIterator wI=theWord.begin();wI!=theWord.end();wI++,i++){
00118       Generator g = *wI;
00119       int absg = abs(g);
00120       int pos = max(positions[absg],max(positions[absg-1],positions[absg+1])) + 1;
00121       drawGenerator( g,pos,vert_offset );
00122       positions[absg] = pos;
00123       if (theLength < pos) theLength = pos;
00124     }
00125     
00126   }
00127   
00128   void drawGenerator( Generator g, int pos, int vert_offset ){
00129     for (int iss=0;iss<ss;iss++)
00130       for (int jss=0;jss<ss;jss++)
00131         if ( g > 0 ){
00132           theImage->setRedPixel( pos*ss + iss + pos+1,  vert_offset+ g + (g - 1)*ss  + jss,168);
00133           theImage->setBluePixel( pos*ss + iss + pos+1, vert_offset+ g + (g - 1)*ss  + jss,168);
00134           theImage->setGreenPixel( pos*ss + iss + pos+1, vert_offset+g + (g - 1)*ss  + jss,168);
00135         } else {
00136           int ag = abs(g);
00137           theImage->setRedPixel( pos*ss +iss + pos+1,  vert_offset+ ag + (ag-1)*ss + jss,0); 
00138           theImage->setBluePixel( pos*ss +iss + pos+1, vert_offset+ ag + (ag-1)*ss + jss,0); 
00139           theImage->setGreenPixel( pos*ss +iss + pos+1,vert_offset+ ag + (ag-1)*ss + jss,0); 
00140         }
00141   }
00142   
00143   void drawVerticalGrid( int vpos, int color){ 
00144     
00145     for (int i=0;i<theImage->getHeight();i+=2){
00146           theImage->setRedPixel( vpos, i,color); 
00147           theImage->setBluePixel( vpos, i, color );
00148           theImage->setGreenPixel( vpos, i, color );
00149     }
00150   }
00151   
00152   void drawHorizontalGrid( int hpos){
00153     for (int i=0;i<=(theLength+1)*(ss+1);i+=2){
00154           theImage->setRedPixel( i, hpos,220); 
00155           theImage->setBluePixel( i, hpos, 220 );
00156           theImage->setGreenPixel( i, hpos, 220 );
00157     }
00158   }
00159   
00160   //  const Word& theWord;
00161   int N;
00162   CImage* theImage;
00163   int ss;
00164   int theLength;
00165   int betBraids;
00166 };
00167 
00168 //
00169 //
00170 //  CREATES A PS image of a table for braid word
00171 //
00172 //
00173 
00174 class RGB
00175 {
00176 public:
00177         RGB(double r, double g, double  b): R(r), G(g), B(b) {} 
00178         RGB(double gray ): R(gray),G(gray),B(gray) {}
00179 
00180 
00181         double R;
00182         double G;
00183         double B; 
00184 };
00185 
00186 
00188 class BraidDrawPDF
00189 {
00190 public:
00191 
00193 
00197   BraidDrawPDF( int n, string t = string() ):
00198     ss( ssConst ),
00199     //    theWord(w),
00200     N(n),
00201     betBraids(0),
00202     theLength( 0 ),
00203     theTitle( t ),
00204     useCircle( false ) // @am There is a problem with using circles when words size is large (say 10000)
00205         {
00206         }
00207         
00208         ~BraidDrawPDF() {  }
00209 
00211 void draw( const Word& w) {
00212         // need to start a new page!!!!
00213         pdf_out.newPage();
00214         drawCompressedBraid( w );
00215 
00216 }
00217 
00218 
00220 void save( const char* f ){
00221         pdf_out.save(f);
00222  }
00223         
00225  void setSS(int new_ss ) { ss = new_ss; }
00226 
00227 
00228 private:
00229 
00230  void drawGrid( int nP, int sN) {
00231         for (int i=PDFPage::lMargin();i<=PDFPage::lMargin()+PDFPage::mWidth();i+=(ss)) // )i<=(posInPage()+1)*(ss);i+=(ss)) // theLength
00232                 pdf_out.addObject( nP , new udPDFPageObjectVertLine( i, stripPosition( sN ),tableWidth(), 0.9, true ) );
00233     for (int i=stripPosition( sN );i<stripPosition( sN + 1);i+=(ss))
00234                 pdf_out.addObject( nP , new udPDFPageObjectHorizLine( PDFPage::lMargin() ,i,PDFPage::mWidth(), 0.9, true ) );           
00235         
00236         // Draw a line after the grid
00237         pdf_out.addObject( nP , new udPDFPageObjectRect(PDFPage::lMargin() , stripPosition( sN + 1) - ss, PDFPage::mWidth(), ss, 0.95, 0.95 ) );
00238     
00239     // add grid mark
00240 //    pdf_out.addObject( nP , new PDFPageObjectText( 10 , stripPosition( sN ) , string("AAAAA") ) );
00241     pdf_out.addObject( nP , new udPDFPageObjectText( PDFPage::lMargin() , PDFPage::tMargin() + 10 , theTitle ) );
00242 
00243   }
00244   
00245  int tableWidth() const { return N*(ss);}
00246  //int stripPosition(int i){return PDFPage::height() - i*tableWidth() - i*2;}
00247  int stripPosition(int i){return i*tableWidth() + i*ss + PDFPage::tMargin() + (theTitle.length() > 0 ? 20 : 0) ;} // i*ss is the gap between stripes + top margin
00248  
00249  
00250  
00251  
00252 private:
00253   
00254   void drawCompressedBraid( const Word& theWord, int vert_offset = 0){
00255     vector<int> positions(N+2,-1); // +2 for the left and right padding
00256     
00257  //   drawGrid(0,0);
00258         
00259         cout << "Positions in page: " << posInPage() << endl;
00260     cout << "Stripes per page : " << stripesInPage() << endl;
00261     
00262     int i=0;
00263     int maxSN = 0;
00264     int maxPage = 0;
00265     for (ConstWordIterator wI=theWord.begin();wI!=theWord.end();wI++,i++){
00266           Generator g = *wI;
00267       int absg = abs(g);
00268       int pos = max(positions[absg],max(positions[absg-1],positions[absg+1])) + 1;
00269       
00270           
00271       if ( maxSN < int(pos / posInPage()) ){    
00272                 drawGrid(maxPage,maxSN % stripesInPage() );
00273                 maxSN = int(pos / posInPage());
00274 //      drawGrid(maxPage,maxSN % stripesInPage() );
00275       }
00276       if ( maxPage < maxSN / stripesInPage() ){
00277                 pdf_out.newPage();      
00278         maxPage++;
00279 //      drawGrid(maxPage,maxSN % stripesInPage() );
00280         //      cout << "MAX PAGE " << maxPage << endl;
00281       }
00282       
00283       positions[absg] = pos;
00284       if (theLength < pos) theLength = pos;    
00285     
00286      drawGenerator( g,pos,vert_offset );
00287    
00288  
00289     }
00290     drawGrid(maxPage,maxSN % stripesInPage() );   
00291   }
00292 
00293   int posInPage() const { return PDFPage::mWidth() / (ss); }
00294   int stripesInPage() const { return PDFPage::mHeight() / ((N+1)*(ss)); }
00295         
00296   void drawGenerator( Generator g, int pos, int vert_offset ){
00297         
00298         int sPos  = pos % posInPage(); // position in the strip 
00299  
00300         int pN = getPageStrip( pos ).first;
00301         int sN = getPageStrip( pos ).second;
00302         int new_vert_offset = stripPosition(sN);
00303         
00304         if ( g > 0 ){
00305                 if (useCircle)
00306                         pdf_out.addObject( pN , new udPDFPageObjectCircle(PDFPage::lMargin() + sPos*ss + double(ss)/2.0 , new_vert_offset + (g-1)*(ss) + double(ss)/2.0, double(ss)/2.0, 0.9, 0.5 ) );
00307                 else
00308                         pdf_out.addObject( pN , new udPDFPageObjectSquare(PDFPage::lMargin() + sPos*ss , new_vert_offset + (g-1)*(ss), ss, 0.9, 0.5 ) );
00309 
00310         } else {
00311                 int ag = abs(g);
00312                 if (useCircle)
00313                         pdf_out.addObject( pN , new udPDFPageObjectCircle(PDFPage::lMargin() + sPos*ss + double(ss)/2.0, new_vert_offset + (ag-1)*(ss)+double(ss)/2.0, double(ss)/2.0, 0.9, 0 ) );
00314                 else
00315                         pdf_out.addObject( pN , new udPDFPageObjectSquare(PDFPage::lMargin() + sPos*ss, new_vert_offset + (ag-1)*(ss), ss, 0.9, 0 ) );
00316         }
00317   }
00318   
00319   pair<int,int> getPageStrip( int pos ) const {
00320         int totSN = pos / posInPage();  // the strip number     
00321         int pN = totSN / stripesInPage(); // the page number
00322         int sN = totSN % stripesInPage(); // the strip number on page pN
00323         
00324 //      cout << pN << endl;
00325         
00326         return pair<int,int>(pN,sN);
00327   } 
00328 
00329   //  const Word& theWord;
00330   int N;
00331   PDFStructure pdf_out;
00332   int ss;
00333   int theLength;
00334   int betBraids;
00335   bool useCircle;
00336   string theTitle;
00337 };
00338 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Mon Sep 26 18:43:45 2011 for CRyptography And Groups (CRAG) by  doxygen 1.6.1