SciFigs/GridPlot.h
Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 **  This file is part of SciFigs.
00004 **
00005 **  This library is free software; you can redistribute it and/or
00006 **  modify it under the terms of the GNU Lesser General Public
00007 **  License as published by the Free Software Foundation; either
00008 **  version 2.1 of the License, or (at your option) any later version.
00009 **
00010 **  This file is distributed in the hope that it will be useful, but WITHOUT
00011 **  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 **  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00013 **  License for more details.
00014 **
00015 **  You should have received a copy of the GNU Lesser General Public
00016 **  License along with this library; if not, write to the Free Software
00017 **  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 **
00019 **  See http://www.geopsy.org for more information.
00020 **
00021 **  Created : 2002-09-09
00022 **  Authors :
00023 **    Marc Wathelet
00024 **    Marc Wathelet (ULg, Liège, Belgium)
00025 **    Marc Wathelet (LGIT, Grenoble, France)
00026 **
00027 ***************************************************************************/
00028 
00029 #ifndef GRIDPLOT_H
00030 #define GRIDPLOT_H
00031 
00032 #include "GraphContentLayer.h"
00033 #include "LayerPainterRequest.h"
00034 
00035 namespace SciFigs {
00036 
00037 class PaletteEditor;
00038 class GridEditProperties;
00039 class IrregularGrid2DDraw;
00040 
00041 class SCIFIGS_EXPORT GridPlot : public GraphContentLayer
00042 {
00043   Q_OBJECT
00044   Q_PROPERTY(bool smooth READ smooth WRITE setSmooth SCRIPTABLE true);
00045   Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid SCRIPTABLE true);
00046 public:
00047   GridPlot(AxisWindow * parent);
00048   ~GridPlot();
00049 
00050   virtual const QString& xml_tagName() const {return xmlGridPlotTag;}
00051   static const QString xmlGridPlotTag;
00052 
00053   virtual bool hasProperties() {return true;}
00054   virtual void addProperties(PropertyProxy * pp);
00055   virtual void removeProperties(PropertyProxy * pp);
00056   virtual void properties(PropertyWidget * w) const;
00057   virtual void setProperty(uint wid, int pid, QVariant val);
00058 
00059   const ColorPalette& palette() const {return _pal;}
00060   void setLinearPalette(double minVal, double maxVal);
00061 
00062   bool showGrid() const {return _showGrid;}
00063   void setShowGrid(bool b) {_showGrid=b;}
00064 
00065   bool smooth() const {return _smooth;}
00066   void setSmooth(bool b) {_smooth=b;}
00067 
00068   Rect::Area fillType() const {return _fillType;}
00069   void setFillType(Rect::Area ft) {_fillType=ft;}
00070 
00071   double fillValue() const {return _fillValue;}
00072   void setFillValue(double v) {_fillValue=v;}
00073 public slots:
00074   void setPalette(const ColorPalette& pal);
00075 signals:
00076   void paletteChanged(const ColorPalette& pal);
00077 protected:
00078   template <class ValueType>
00079   static void drawGrid2DYSmooth(const Grid2D<ValueType>& grid, ColorPalette pal,
00080                                  const LayerPainterRequest& lp, QPainter& p);
00081   template <class ValueType>
00082   static void drawGrid2DBlock(const Grid2D<ValueType>& grid, ColorPalette pal,
00083                                const LayerPainterRequest& lp, QPainter& p);
00084   static void drawGrid2DSmooth(const IrregularGrid2D& grid, ColorPalette pal,
00085                                  const LayerPainterRequest& lp, QPainter& p, IrregularGrid2DDraw& d);
00086   static void drawGrid2DBlock(const IrregularGrid2D& grid, ColorPalette pal,
00087                                const LayerPainterRequest& lp, QPainter& p, const IrregularGrid2DDraw& d);
00088   void drawGridLines(QPainter& p, const IrregularGrid2DDraw& d) const;
00089   template <class ValueType>
00090   void drawGridLines(const Grid2D<ValueType>& grid,
00091                      const LayerPainterRequest& lp, QPainter& p) const;
00092 
00093   virtual void xml_writeChildren(XML_WRITECHILDREN_ARGS) const;
00094   virtual XMLMember xml_member(XML_MEMBER_ARGS);
00095   virtual void xml_polishChild(XML_POLISHCHILD_ARGS);
00096 
00097   Rect::Area _fillType;
00098   double _fillValue;
00099   ColorPalette _pal;
00100 private:
00101   bool _showGrid;
00102   bool _smooth;
00103 
00104   static uint _tabPalette, _tabGrid;
00105 private:
00106   static inline bool notEnd(int i, int stopi, int di);
00107 };
00108 
00109 template <class ValueType>
00110 void GridPlot::drawGrid2DYSmooth(const Grid2D<ValueType>& grid, ColorPalette pal,
00111                                  const LayerPainterRequest& lp, QPainter& p)
00112 {
00113   TRACE;
00114   const GraphContentOptions& gc=lp.options();
00115 
00116   double startx, ddx, stopx, x;
00117   double starty, ddy, stopy, y;
00118   double coef;
00119   int startix, startiy, dmx, dmy;
00120   int y1, y2, x1, x2, dx, dy, dlim, limx, limxdy, yn1, yn2;
00121 
00122   ddx=grid.deltaX();
00123   ddy=grid.deltaY();
00124   startx=grid.origin().x() - ddx * 0.5;
00125   starty=grid.origin().y();
00126   stopx=startx + (double) grid.nx() * ddx;
00127   stopy=starty + (double) (grid.ny() - 1) * ddy;
00128 
00129   // Find first x and stopx
00130   if(startx > gc.xVisMin()) {
00131     if(startx > gc.xVisMax()) return ;
00132     startix=0;
00133   } else {
00134     if(stopx < gc.xVisMin()) return ;
00135     startix=(int) floor(( gc.xVisMin() - startx)/ddx);
00136     startx += (double) startix * ddx;
00137   }
00138   stopx -= 0.5 * ddx;
00139   if(stopx > gc.xVisMax()) stopx=gc.xVisMax();
00140 
00141   // Find first starty and stopy
00142   if(starty > gc.yVisMin()) {
00143     if(starty > gc.yVisMax()) return ;
00144     y=starty;
00145     startiy=0;
00146   } else {
00147     if(stopy < gc.yVisMin()) return ;
00148     startiy=(int) floor(( gc.yVisMin() - starty)/ddy);
00149     y=starty + (double) startiy * ddy;
00150   }
00151   stopy -= 0.5 * ddy;
00152   if(stopy > gc.yVisMax()) stopy=gc.yVisMax();
00153 
00154   // Adjust ddx, increase it if less than a pixel
00155   if(fabs( gc.ax() * ddx) < 1.0) {
00156     dmx=(int) ceil(( double) 1.0/fabs(gc.ax() * ddx) );
00157     ddx *= (double) dmx;
00158   } else dmx=1;
00159 
00160   // Adjust ddy, increase it if less than a pixel
00161   if(fabs( gc.ay() * ddy) < 1.0) {
00162     dmy=(int) ceil(( double) 1.0/fabs(gc.ay() * ddy) );
00163     ddy *= (double) dmy;
00164     dmy *= grid.nx();
00165   } else dmy=grid.nx();
00166 
00167   const double * valx, * valy, * valxdy;
00168   valy=grid.valuePointer(startix, startiy);
00169   y2=gc.yr2s(y);
00170   for( ; y < stopy; ) {
00171     if(lp.terminated()) return;
00172     y1=y2;
00173     y += ddy;
00174     y2=gc.yr2s(y);
00175     dy=y1 - y2;
00176     valx=valy;
00177     valy += dmy;
00178     valxdy=valy;
00179     x2=gc.xr2s(startx);
00180     for(x=startx; x < stopx; valx += dmx, valxdy += dmx) {
00181       x1=x2;
00182       x += ddx;
00183       x2=gc.xr2s(x);
00184       dx=x2 - x1;
00185       limx=pal.index( *valx);
00186       limxdy=pal.index( *valxdy);
00187       dlim=limxdy - limx;
00188       if(dlim==0) p.fillRect (x1, y2, dx, dy, pal.color(limx) );
00189       else {
00190         coef=(( double) dy)/( *valx - *valxdy);
00191         yn2=y1;
00192         if(dlim > 0) {
00193           dlim=1;
00194           for(int lim=limx;lim < limxdy;lim += dlim) {
00195             yn1=yn2;
00196             yn2=(int) (coef * (pal.upperValue(lim) - *valx) ) + y1;
00197             if(yn1!=yn2)
00198               p.fillRect (x1, yn2, dx, yn1 - yn2, pal.color(lim) );
00199             else if(lim!=limx) dlim=dlim << 1;
00200           }
00201         } else {
00202           dlim=1;
00203           for(int lim=limx - 1;lim >= limxdy;lim -= dlim) {
00204             yn1=yn2;
00205             yn2=(int) (coef * (pal.upperValue(lim) - *valx) ) + y1;
00206             if(yn1!=yn2)
00207               p.fillRect (x1, yn2, dx, yn1 - yn2, pal.color(lim + 1) );
00208             else if(lim!=limx - 1) dlim=dlim << 1;
00209           }
00210         }
00211         if(yn2!=y2)
00212           p.fillRect (x1, y2, dx, yn2 - y2, pal.color(limxdy) );
00213       }
00214     }
00215   }
00216 }
00217 
00218 template <class ValueType>
00219 void GridPlot::drawGrid2DBlock(const Grid2D<ValueType>& grid, ColorPalette pal,
00220                                const LayerPainterRequest& lp, QPainter& p)
00221 {
00222   TRACE;
00223   const GraphContentOptions& gc=lp.options();
00224 
00225   double startx, ddx, stopx, x;
00226   double starty, ddy, stopy, y;
00227   int startix, startiy;
00228   int y1, y2, x1, x2, dy, dmx, dmy;
00229 
00230   ddx=grid.deltaX();
00231   ddy=grid.deltaY();
00232   startx=grid.origin().x() - ddx * 0.5;
00233   starty=grid.origin().y() - ddy * 0.5;
00234   stopx=startx + (double) grid.nx() * ddx;
00235   stopy=starty + (double) grid.ny() * ddy;
00236 
00237   // Find first x and stopx
00238   if(startx > gc.xVisMin()) {
00239     if(startx > gc.xVisMax()) return ;
00240     startix=0;
00241   } else {
00242     if(stopx < gc.xVisMin()) return ;
00243     startix=(int) floor(( gc.xVisMin() - startx)/ddx);
00244     startx += (double) startix * ddx;
00245   }
00246   stopx -= 0.5 * ddx;
00247   if(stopx > gc.xVisMax()) stopx=gc.xVisMax();
00248 
00249   // Find first starty and stopy
00250   if(starty > gc.yVisMin()) {
00251     if(starty > gc.yVisMax()) return ;
00252     y=starty;
00253     startiy=0;
00254   } else {
00255     if(stopy < gc.yVisMin()) return ;
00256     startiy=(int) floor(( gc.yVisMin() - starty)/ddy);
00257     y=starty + (double) startiy * ddy;
00258   }
00259   stopy -= 0.5 * ddy;
00260   if(stopy > gc.yVisMax()) stopy=gc.yVisMax();
00261 
00262   // Adjust ddx, increase it if less than a pixel
00263   if(fabs( gc.ax() * ddx) < 1.0) {
00264     dmx=(int) ceil(( double) 1.0/fabs(gc.ax() * ddx) );
00265     ddx *= (double) dmx;
00266   } else dmx=1;
00267 
00268   // Adjust ddy, increase it if less than a pixel
00269   if(fabs( gc.ay() * ddy) < 1.0) {
00270     dmy=(int) ceil(( double) 1.0/fabs(gc.ay() * ddy) );
00271     ddy *= (double) dmy;
00272     dmy *= grid.nx();
00273   } else dmy=grid.nx();
00274 
00275   const double * valx, *valy;
00276   valy=grid.valuePointer(startix, startiy);
00277   y2=gc.yr2s(y);
00278   for( ; y < stopy; ) {
00279     if(lp.terminated()) return;
00280     y1=y2;
00281     y += ddy;
00282     y2=gc.yr2s(y);
00283     dy=y2 - y1;
00284     valx=valy;
00285     valy += dmy;
00286     x2=gc.xr2s(startx);
00287     for(x=startx; x < stopx; valx += dmx) {
00288       x1=x2;
00289       x += ddx;
00290       x2=gc.xr2s(x);
00291       p.fillRect (x1, y1, x2 - x1, dy, pal.color( *valx) );
00292     }
00293   }
00294 }
00295 
00296 template <class ValueType>
00297 void GridPlot::drawGridLines(const Grid2D<ValueType>& grid,
00298                              const LayerPainterRequest& lp, QPainter& p) const
00299 {
00300   TRACE;
00301   const GraphContentOptions& gc=lp.options();
00302   int x, y;
00303   int x0=gc.xr2s(grid.west(0)), x1=gc.xr2s(grid.east(grid.nx()-1));
00304   for(int iy=grid.ny()-1; iy>=0; iy--) {
00305     y=gc.yr2s(grid.south(iy));
00306     p.drawLine(x0, y, x1, y);
00307   }
00308   y=gc.yr2s(grid.north(0));
00309   p.drawLine(x0, y, x1, y);
00310   int y0=gc.yr2s(grid.south(0)), y1=gc.yr2s(grid.north(grid.ny()-1));
00311   for(int ix=grid.nx()-1;ix >= 0;ix-- ) {
00312     x=gc.xr2s(grid.east(ix));
00313     p.drawLine(x, y0, x, y1);
00314   }
00315   x=gc.xr2s(grid.west(0));
00316   p.drawLine(x, y0, x, y1);
00317 }
00318 
00319 } // namespace SciFigs
00320 
00321 #endif // GRIDPLOT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines