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

xygraca.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /* Módulo: xygraca.cpp                                                        */
00003 /* Autores: Carlos Henrique Levy e Jaudênia Cavalcante                       */
00004 /* Data: 26 fev 96                                                           */
00005 /* Comentário:                                                               */
00006 /*    Implementação de métodos da classe especializada responsável pelo dese */
00007 /* nho de gráficos do tipo cartesiano que tem como principal característica  */
00008 /* pelo menos dois eixos, um na direção x (rotação 0) e outro na direção y   */
00009 /* (rotação 90).                                                             */
00010 /*****************************************************************************/
00011 
00012 #include <stdlib.h>
00013 #include <stdarg.h>
00014 
00015 #include "xygraca.h"
00016 #include "xymkca.h"
00017 
00018 const char* xy_id_xycart_cpp="$Id: xygraca.cpp,v 1.26 2002/01/23 16:12:20 clinio Exp $";
00019                                                                 
00020 #ifndef NOIUP
00021 XYCartesian::XYCartesian (Ihandle* canvas,
00022                           XYCoordinate x,
00023                           XYCoordinate y,
00024                           double width,
00025                           double height,
00026                                 XYGrid* gridh,
00027                                           XYGrid* gridv,
00028                                           xybool visible)
00029                                           : XYGraph(canvas, x, y, width, height,
00030                                                     visible),
00031                                             _gridh(gridh),
00032                                             _gridv(gridv)
00033 {
00034 }
00035 #endif
00036 
00037 XYCartesian::XYCartesian (cdCanvas* cdcanvas,
00038                           XYCoordinate x,
00039                           XYCoordinate y,
00040                           double width,
00041                           double height,
00042                                           XYGrid* gridh,
00043                                           XYGrid* gridv,
00044                                           xybool visible)
00045                                           : XYGraph(cdcanvas, x, y, width, height,
00046                                                     visible),
00047                                             _gridh(gridh),
00048                                             _gridv(gridv)
00049 {
00050 }
00051  
00052 XYCartesian::~XYCartesian (void)
00053 {
00054    // liberar grides alocados
00055 }
00056 
00057 void XYCartesian::setGridH (XYGrid *gridh)
00058 {
00059    _gridh = gridh;
00060 }
00061 
00062 XYGrid* XYCartesian::getGridH (void) const
00063 {
00064    return _gridh;
00065 }
00066 
00067 void XYCartesian::setGridV (XYGrid *gridv)
00068 {
00069    _gridv = gridv;
00070 }
00071 
00072 XYGrid* XYCartesian::getGridV (void) const
00073 {
00074    return _gridv;
00075 }
00076 
00077 XYObject* XYCartesian::markerCreate(int x0, int y0, const XYAxis* master)
00078 {
00079    XYCartesianMarker* marker = NULL;
00080 
00081    // consulta eixo de referência para a criação de um marcador
00082    if (master != NULL)
00083    {
00084       // define atributos do marcador a partir dos atributos do eixo
00085       double pos = master -> valueInPoint(x0, y0);
00086       long color = master -> color();
00087 
00088       // constrói novo marcador cartesiano
00089       marker = new XYCartesianMarker(master, pos, color, 2,
00090                                      XYObject::continuous);
00091 
00092             // define alcance do marcador a partir de sua posição sobre o eixo
00093             if (master -> rotation() == 0.0)
00094          marker -> limit(_ma_ymax - _ma_ymin);
00095             else
00096          marker -> limit(_ma_xmax - _ma_xmin);
00097    }
00098 
00099    // insere marcador criado na lista de marcadores do gráfico
00100    insert(marker);
00101 
00102    return (XYObject *) marker;
00103 }
00104 
00105 XYObject* XYCartesian::pick (int px, int py)
00106 {
00107    XYObject* obj;
00108 
00109    // verifica objetos gráficos
00110    obj = XYGraph::pick(px, py);
00111 
00112    if (obj != NULL) return obj;
00113 
00114    // testa grade horizontal
00115    if (_gridh != NULL)
00116       if (_gridh -> pick(px, py))       
00117          return _gridh;
00118 
00119    // testa grade vertical
00120    if (_gridv != NULL)
00121       if (_gridv -> pick(px, py))       
00122          return _gridv;
00123 
00124    return NULL;
00125 }
00126 
00127 XYList<XYObject>* XYCartesian::fence (int x0, int y0, int x1, int y1)
00128 {
00129    XYList<XYObject>* obj;
00130 
00131    obj = XYGraph::fence(x0, y0, x1, y1);
00132 
00133    // testa grade horizontal
00134    if (_gridh -> fence(x0, y0, x1, y1)) 
00135        obj -> insert(_gridh);
00136 
00137    // testa grade vertical
00138    if (_gridv -> fence(x0, y0,  x1, y1))        
00139       obj -> insert(_gridv);
00140 
00141    return obj;
00142 }
00143 
00144 void XYCartesian::calcMaskArea (void)
00145 {
00146    activateCanvas ();
00147 
00148    XYListIterator<XYAxis> in(&_axes);
00149 
00150    // inicializa coordenadas mínimas com valores máximos possíveis, coordenadas
00151    // máximas com valores mínimos possíveis
00152    _ma_xmin = 1.0;
00153    _ma_xmax = 0.0;
00154    _ma_ymin = 1.0;
00155    _ma_ymax = 0.0;
00156 
00157    XYAxis* cont;
00158 
00159    while (!in.End())
00160    {
00161       cont = in.Next();
00162       double x, y;
00163 
00164       // consulta posição e tamanho do eixo
00165       cont -> position(&x, &y);
00166       double size = cont -> size();
00167 
00168       // considera a rotação do eixo para calcular a região de desenho das
00169       // máscaras
00170       switch ((int) cont -> rotation())
00171       {
00172          case 0:   // eixo na horizontal - base
00173             if (x < _ma_xmin)
00174                _ma_xmin = x;
00175 
00176             if (x + size > _ma_xmax)
00177                _ma_xmax = x + size;
00178 
00179                   break;
00180 
00181          case 180: // eixo na horizontal - topo
00182             if (x > _ma_xmax)
00183                _ma_xmax = x;
00184 
00185             if (x - size < _ma_xmin)
00186                _ma_xmin = x - size;
00187 
00188                   break;
00189 
00190          case 90:  // eixo na vertical direita
00191             if (y < _ma_ymin)
00192                _ma_ymin = y;
00193 
00194             if (y + size > _ma_ymax)
00195                _ma_ymax = y + size;
00196 
00197                   break;
00198 
00199                case 270: // eixo na vertical esquerda
00200             if (y > _ma_ymax)
00201                _ma_ymax = y;
00202 
00203             if (y - size < _ma_ymin)
00204                _ma_ymin = y - size;
00205 
00206                   break;
00207       }
00208    }
00209 }
00210 
00211 void XYCartesian::propagateViewport (void) const
00212 {
00213    // define as áreas de desenho para todos os eixos e para todas as máscaras
00214    XYGraph::propagateViewport();
00215 
00216    int x1, x2, y1, y2;
00217    getViewport(x1, x2, y1, y2);
00218 
00219    if (_gridh)  // define área gráfica para a grade horizontal
00220    {
00221       _gridh -> position (_ma_xmin, _ma_ymin);
00222       _gridh -> size (_ma_xmax - _ma_xmin);
00223       _gridh -> limit (_ma_ymax - _ma_ymin);
00224       _gridh -> setViewport(x1, x2, y1, y2);
00225    }
00226 
00227    if (_gridv)  // define área gráfica para a grade vertical
00228    {
00229       _gridv -> position (_ma_xmin, _ma_ymin);
00230       _gridv -> size (_ma_ymax - _ma_ymin);
00231       _gridv -> limit (_ma_xmax - _ma_xmin);
00232       _gridv -> setViewport(x1, x2, y1, y2);
00233    }
00234 }
00235 
00236 void XYCartesian::draw(void)
00237 {
00238    if (visible() == xyfalse)    // invisível!!!
00239       return;
00240             
00241    activateCanvas();
00242    defineViewport();
00243      
00244    int x1, y1, x2, y2;
00245    getViewport (x1, x2, y1, y2);
00246 
00247    draw(x1, y1, x2, y2);
00248 }
00249 
00250 void XYCartesian::draw(int xmin, int ymin, int xmax, int ymax) const
00251 {
00252    if (visible() == xyfalse)    // invisível!!!
00253       return;
00254     
00255    activateCanvas();
00256    propagateViewport();
00257 
00258    XYGraph::maskAreaClear();
00259 
00260    int oldmode = cdClip(CD_CLIPON);
00261 
00262    // guarda a região de clip corrente
00263    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00264    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00265    
00266    // define nova região de clip
00267    cdClipArea(xmin, xmax, ymin, ymax);
00268 
00269    // desenha todos os "slices"
00270    XYListIterator<XYSlice> is(&_slices);
00271    XYSlice* scont;
00272    while (!is.End())
00273    { scont = is.Next();
00274      scont -> draw(xmin, ymin, xmax, ymax);
00275    }
00276 
00277    // desenha todas as areas
00278    XYListIterator<XYArea> ir(&_areas);
00279    XYArea* rcont;
00280    while (!ir.End())
00281    { rcont = ir.Next();
00282      rcont->draw(xmin, ymin, xmax, ymax);
00283    }
00284    
00285    int x1, y1, x2, y2;
00286    getMaskArea (x1, y1, x2, y2);
00287    cdClipArea(x1, x2, y1, y2);
00288    // desenha grids 
00289    if (_gridh)  _gridh -> draw (xmin, ymin, xmax, ymax);
00290    if (_gridv)  _gridv -> draw (xmin, ymin, xmax, ymax);
00291    cdClipArea(xmin, xmax, ymin, ymax);
00292 
00293    XYGraph::draw(xmin, ymin, xmax, ymax);
00294 
00295    cdClip(oldmode);
00296    // restaura a região de clip anterior
00297    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00298 
00299    if ( doubleBuffering()==xytrue ) XYGraph::flush();
00300 }
00301 
00302 void XYCartesian::drawMaskArea (void) const
00303 {
00304    activateCanvas();
00305    propagateViewport();
00306 
00307    int x1, y1, x2, y2;
00308    getMaskArea (x1, y1, x2, y2);
00309 
00310    drawMaskArea (x1, y1, x2, y2);
00311 }
00312 
00313 void XYCartesian::drawMaskArea (int xmin, int ymin, int xmax, int ymax) const
00314 {
00315    int mode = cdClip(CD_CLIPON);
00316 
00317    // guarda a região de clip corrente
00318    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00319    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00320    // define nova região de clip
00321    cdClipArea(xmin, xmax, ymin, ymax);
00322 
00323    // desenha todos os "slices"
00324    XYListIterator<XYSlice> is(&_slices);
00325    XYSlice* scont;
00326 
00327    while (!is.End())
00328    {
00329       scont = is.Next();
00330       scont -> draw(xmin, ymin, xmax, ymax);
00331    }
00332 
00333    if (_gridh)  // desenha grade horizontal
00334       _gridh -> draw (xmin, ymin, xmax, ymax);
00335 
00336    if (_gridv)  // desenha grade vertical
00337       _gridv -> draw (xmin, ymin, xmax, ymax);
00338 
00339    XYGraph::drawMaskArea(xmin, ymin, xmax, ymax);
00340 
00341    cdClip(mode);
00342    // restaura a região de clip anterior
00343    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00344 }
00345 

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group