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

xymcabr.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /* Módulo: xymcabr.cpp                                                       */
00003 /* Autores: Camilo da Fonseca Freire                                         */
00004 /* Data: 27 jun 96                                                           */
00005 /* Comentário:                                                               */
00006 /*    Implementação de métodos da classe que representa através de barras um */
00007 /* conjunto de dados num gráfico cartesiano.                                 */
00008 /*****************************************************************************/
00009 
00010 #include "xymcabr.h"
00011 
00012 const char* xy_id_xymcabr_cpp="$Id: xymcabr.cpp,v 1.9 1999/12/09 21:47:46 rborges Exp $";
00013                                                                 
00014 XYCartesianBarMask::XYCartesianBarMask (XYText* name,
00015                                                           XYSeries* series,
00016                                                           const XYAxis* x_axis,
00017                                                           const XYAxis* y_axis,
00018                                                           long color,
00019                                                           InteriorStyle style,
00020                                                           HatchStyle hstyle,
00021                                                           xybool border,
00022                                                           long bcolor,
00023                                                           double displacement,
00024                                                           double width,
00025                                                           xybool visible)
00026                                                           : XYCartesianMask(name, series, x_axis,
00027                                                                                   y_axis, color,
00028                                                                                       visible),
00029                                                                   _style(style),
00030                                                                   _hstyle(hstyle),
00031                                                             _border(border),
00032                                                             _bcolor(bcolor),
00033                                                             _displacement(displacement),
00034                                                             _width(width)
00035 {
00036 }
00037 
00038 XYCartesianBarMask::XYCartesianBarMask (XYSeries* series,
00039                                                           const XYAxis* x_axis,
00040                                                           const XYAxis* y_axis,
00041                                                           long color,
00042                                                           InteriorStyle style,
00043                                                           HatchStyle hstyle,
00044                                                           xybool border,
00045                                                           long bcolor,
00046                                                           double displacement,
00047                                                           double width,
00048                                                           xybool visible)
00049                                                           : XYCartesianMask(series, x_axis,
00050                                                                             y_axis, color,
00051                                                                             visible),
00052                                                             _style(style),
00053                                                             _hstyle(hstyle),
00054                                                             _border(border),
00055                                                             _bcolor(bcolor),
00056                                                             _displacement(displacement),
00057                                                             _width(width)
00058 {
00059 }
00060 
00061 void XYCartesianBarMask::style (XYMask::InteriorStyle s)
00062 {
00063    _style = s;
00064 }
00065 
00066 int XYCartesianBarMask::style (void) const
00067 {
00068    return _style;
00069 }
00070 
00071 void XYCartesianBarMask::hstyle (HatchStyle hs)
00072 {
00073    _hstyle = hs;
00074 }
00075 
00076 int XYCartesianBarMask::hstyle (void) const
00077 {
00078    return _hstyle;
00079 }
00080 
00081 void XYCartesianBarMask::bcolor (long bc)
00082 {
00083    _bcolor = bc;
00084 }
00085 
00086 long XYCartesianBarMask::bcolor (void) const
00087 {
00088    return _bcolor;
00089 }
00090 
00091 void XYCartesianBarMask::displacement (double d)
00092 {
00093    _displacement = d;
00094 }
00095 
00096 double XYCartesianBarMask::displacement (void) const
00097 {
00098    return _displacement;
00099 }
00100 
00101 void XYCartesianBarMask::width (double w)
00102 {
00103    _width = w;
00104 }
00105 
00106 double XYCartesianBarMask::width (void) const
00107 {
00108    return _width;
00109 }
00110 
00111 void XYCartesianBarMask::border (xybool b)
00112 {
00113    _border = b;
00114 }
00115 
00116 xybool XYCartesianBarMask::border (void) const
00117 {
00118    return _border;
00119 }
00120 
00121 void XYCartesianBarMask::draw (void)
00122 {
00123    draw(_xmin, _ymin, _xmax, _ymax);
00124 }
00125 
00126 xybool XYCartesianBarMask::pick (int x, int y)
00127 {
00128    if (visible() == xyfalse)    // invisível!!!
00129       return xyfalse;
00130 
00131    XYSeries* s = (XYSeries *) _series;
00132 
00133    int npoints = s -> numPoints();
00134 
00135    // teste de inconsistência
00136    if ((npoints < 1) || (x <= _xmin) || (_xmax <= x) || (y <= _ymin) ||
00137        (_ymax <= y))
00138       return xyfalse;
00139 
00140    setWindow (_x_axis -> transform(_x_axis -> min()),
00141                   _x_axis -> transform(_x_axis -> max()),
00142                   _y_axis -> transform(_y_axis -> min()),
00143                   _y_axis -> transform(_y_axis -> max()));
00144 
00145    setViewport();
00146 
00147    // guarda o atual modo de clipping
00148    int mode = cdClip(CD_CLIPON);
00149 
00150    // guarda a região de clip corrente
00151    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00152    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00153    // define nova região de clip
00154    cdClipArea(_xmin, _xmax, _ymin, _ymax);
00155 
00156    // converte coordenadas (x, y) em pixels para coordenadas do mundo
00157    double px, py;
00158    wdCanvas2World (x, y, &px, &py);
00159 
00160    double xt, yt, x1, y1, x2, y2;
00161    // verifica uma série
00162    for (int i = 0; i < npoints; ++i)
00163    {
00164       s -> point(i, xt, yt);
00165 
00166       x1 = _x_axis -> transform(xt) - _width / 2.;
00167       y1 = _x_axis -> transform(_y_axis -> min());
00168       x2 = _x_axis -> transform(xt) + _width / 2.;
00169       y2 = _y_axis -> transform(yt);
00170 
00171       if (mtPointInRect(px, py, x1, y1, x2, y2))
00172          return xytrue;
00173    }
00174 
00175    cdClip(mode);
00176    // restaura a região de clip anterior
00177    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00178    return xyfalse;
00179 }
00180 
00181 xybool XYCartesianBarMask::fence (int x2, int y2, int x3, int y3)
00182 {
00183    if (visible() == xyfalse)           // invisível!!!
00184       return xyfalse;
00185 
00186    // limites da menor caixa que contém uma máscara
00187    int x0, y0, x1, y1;
00188    boundingBox (x0, y0, x1, y1);
00189 
00190    return mtInclude (x0, y0, x1, y1, x2, y2, x3, y3);
00191 }
00192 
00193 void XYCartesianBarMask::drawIcon (int xmin, int ymin, int xmax, int ymax)
00194                                                const
00195 {
00196    int ymid = (int)((double)(ymax + ymin) /2);
00197 
00198    // ativa estilo, largura e cor da linha usada para desenhar a série
00199    cdLineStyle(_style);
00200    cdLineWidth((int)_width);
00201    cdForeground(_color);
00202 
00203    cdLine (xmin, ymid, xmax, ymid);
00204 }
00205 
00206 void XYCartesianBarMask::draw (int xmin, int /* ymin */, int xmax, int /* ymax */) const
00207 {
00208    if (visible() == xyfalse)  // invisível!!!
00209       return;
00210 
00211    XYSeries* s = (XYSeries *) _series;
00212 
00213    // define domínio da série nos limites da área a ser desenhada:
00214 
00215    // domínio original da série
00216    double old_begin, old_end;
00217    s -> domain(&old_begin, &old_end);
00218 
00219    // novo domínio
00220    double begin, end;
00221 
00222    // define os parâmetros de visualização para o domínio do eixos na
00223    // região de desenho das máscaras. Isto é necessário para se poder
00224    // calcular os novos limites do eixo X em coordenadas do mundo
00225    setWindow (_x_axis -> min(), _x_axis -> max(), _y_axis -> min(),
00226                   _y_axis -> max());
00227 
00228    setViewport();
00229 
00230    // calcula os novos limites no eixo X, em coordenadas do mundo
00231    wdCanvas2World (xmin, 0, &begin, 0);
00232    wdCanvas2World (xmax, 0, &end, 0);
00233 
00234    // calcula o novo domínio para a série que é o domínio que está dentro
00235    // da região que vai ser desenhada. Agora, se a área não intercepta o
00236    // domínio, então retorna porque não há nada para ser desenhado
00237    if ((begin > old_end) || (end < old_begin))
00238       return;
00239 
00240    if (begin < old_begin)
00241       begin = old_begin;
00242 
00243    if (end > old_end)
00244       end = old_end;
00245         
00246    // define o novo domínio
00247    s -> domain(begin, end);
00248 
00249    // número de pontos na série
00250    int npoints = s -> numPoints();
00251 
00252    // teste de inconsistência
00253    if (npoints <= 0)
00254    {
00255       // restaura valores originais do domínio da série
00256       s -> domain(old_begin, old_end);
00257       return;
00258    }
00259 
00260    // começa a desenhar:
00261 
00262    // transforma coordenadas máximas e mínimas de acordo com o tipo dos eixos
00263    // ativos e usa esses valores para a nova window
00264    setWindow (_x_axis -> transform(_x_axis -> min()),
00265                   _x_axis -> transform(_x_axis -> max()),
00266                   _y_axis -> transform(_y_axis -> min()),
00267                   _y_axis -> transform(_y_axis -> max()));
00268 
00269    setViewport();
00270 
00271    // ativa estilo de interior usado para desenhar a série
00272    cdHatch(_hstyle);
00273    cdInteriorStyle(_style);
00274 
00275    // guarda o atual modo de clipping
00276    int mode = cdClip(CD_CLIPON);
00277 
00278    // guarda a região de clip corrente
00279    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00280    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00281    // define nova região de clip
00282    cdClipArea(_xmin, _xmax, _ymin, _ymax);
00283 
00284    cdWriteMode(CD_REPLACE);
00285 
00286    double xt, yt, x1, x2, y1, y2;
00287 
00288    // desenha uma série
00289    for (int i = 0; i < npoints; ++i)
00290    {
00291       s -> point(i, xt, yt);
00292 
00293       x1 = _x_axis -> transform(xt) - _width / 2.;
00294       y1 = _y_axis -> transform(_y_axis -> min());
00295       x2 = _x_axis -> transform(xt) + _width / 2.;
00296       y2 = _y_axis -> transform(yt);
00297 
00298       // controle de ponto flutuante
00299       //if (mtEqual(x1, x2))
00300       //   x2 = x1;
00301       //if (mtEqual(y1, y2))
00302       //   y2 = y1;
00303 
00304       // cor da barra
00305       cdForeground(_color);
00306 
00307       // desenha barra para cada ponto da série
00308       wdBox (x1, x2, y1, y2);
00309 
00310       if (_border == xytrue)
00311       {
00312          // cor da fronteira
00313          cdForeground(_bcolor);
00314 
00315          // desenha fronteira da barra
00316          wdBegin(CD_CLOSED_LINES);
00317          wdVertex(x1,y1);
00318          wdVertex(x2,y1);
00319                wdVertex(x2,y2);
00320                wdVertex(x1,y2);
00321                wdEnd();
00322       }
00323 
00324       cdFlush();
00325    }
00326 
00327    // restaura valores originais do domínio da série
00328    s -> domain(old_begin, old_end);
00329 
00330    cdClip(mode);
00331    // restaura a região de clip anterior
00332    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00333 }
00334 
00335 void XYCartesianBarMask::boundingBox (int& bxmin, int& bymin, int& bxmax,
00336                                       int& bymax) const
00337 {
00338    if (visible() == xyfalse)  // invisível!!!
00339       return;
00340 
00341    XYSeries* s = (XYSeries *) _series;
00342 
00343    // número de pontos na série
00344    int npoints = s -> numPoints();
00345 
00346    double xt, yt, x1, x2, y1, y2;
00347 
00348    s -> point(0, xt, yt);
00349 
00350    x1 = _x_axis -> transform(xt) - _width / 2.;
00351    y1 = _y_axis -> transform(_y_axis -> min());
00352    x2 = _x_axis -> transform(xt) + _width / 2.;
00353    y2 = _y_axis -> transform(yt);
00354 
00355    // controle de ponto flutuante
00356    //if (mtEqual(x1, x2))
00357    //   x2 = x1;
00358    //if (mtEqual(y1, y2))
00359    //   y2 = y1;
00360 
00361    // inicializa boundingBox
00362    double txmin = MIN(x1, x2);
00363    double tymin = MIN(y1, y2);
00364    double txmax = MAX(x1, x2);
00365    double tymax = MAX(y1, y2);
00366 
00367    // verifica uma série
00368    for (int i = 1; i < npoints; ++i)
00369    {
00370       s -> point(i, xt, yt);
00371 
00372       x1 = _x_axis -> transform(xt) - _width / 2.;
00373       y1 = _y_axis -> transform(_y_axis -> min());
00374       x2 = _x_axis -> transform(xt) + _width / 2.;
00375       y2 = _y_axis -> transform(yt);
00376 
00377       // controle de ponto flutuante
00378       //if (mtEqual(x1, x2))
00379       //   x2 = x1;
00380       //if (mtEqual(y1, y2))
00381       //   y2 = y1;
00382 
00383       txmin = MIN3(x1, x2, txmin);
00384       tymin = MIN3(y1, y2, tymin);
00385       txmax = MAX3(x1, x2, txmax);
00386       tymax = MAX3(y1, y2, tymax);
00387                                 
00388       cdFlush();
00389    }
00390 
00391    wdWorld2Canvas(txmin, tymin, &bxmin, &bymin);
00392    wdWorld2Canvas(txmax, tymax, &bxmax, &bymax);
00393 
00394    // restringe a boundingBox a área de desenho da máscara,
00395    // caso ela a ultrapasse
00396 
00397    if (bxmin > _xmin)
00398       bxmin = _xmin;
00399 
00400    if (bxmax > _xmax)
00401       bxmax = _xmax;
00402 
00403    if (bymin > _ymin)
00404       bymin = _ymin;
00405 
00406    if (bymax > _ymax)
00407       bymax =_ymax;
00408 }
00409 

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group