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

xymcatxt.cpp

Go to the documentation of this file.
00001 /*
00002  * Módulo: xymcatxt.cpp                                                     
00003  * Autores: André Luiz Clinio                                               
00004  */
00005 
00006 // =======================================================================
00007 
00008 #include "xymcatxt.h"
00009 
00010 // =======================================================================
00011 
00012 const char* xy_id_xymcatxt_cpp="$Id: xymcatxt.cpp,v 1.8 2000/06/14 19:12:18 camilo Exp $";
00013                                                                 
00014 // =======================================================================
00015 
00016 XYCartesianMarkMask::XYCartesianMarkMask( XYText* name, XYSeries* series,
00017 const XYAxis* x_axis, const     XYAxis* y_axis, long color ) : 
00018 XYCartesianMask(name, series, x_axis, y_axis, color, xytrue) {
00019 }
00020 
00021 // .......................................................................
00022 
00023 void XYCartesianMarkMask::draw (void) {
00024    draw(_xmin, _ymin, _xmax, _ymax);
00025 }
00026 
00027 // .......................................................................
00028 
00029 xybool XYCartesianMarkMask::pick (int x, int y) {
00030    if (visible() == xyfalse)    return xyfalse;
00031 
00032    XYSeries* s = (XYSeries *)_series;
00033    int npoints = s->numPoints();
00034 
00035    // teste de inconsistência
00036    if ( (npoints < 1) || (x < _xmin) || (_xmax < x) || 
00037         (y < _ymin) || (_ymax < y) )
00038         return xyfalse;
00039 
00040    setWindow (_x_axis -> transform(_x_axis -> min()),
00041                    _x_axis -> transform(_x_axis -> max()),
00042                 _y_axis -> transform(_y_axis -> min()),
00043                 _y_axis -> transform(_y_axis -> max()));
00044 
00045    setViewport();
00046 
00047    // guarda o atual modo de clipping
00048    int mode = cdClip(CD_CLIPON);
00049 
00050    // guarda a região de clip corrente
00051    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00052    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00053    // define nova região de clip
00054    cdClipArea(_xmin, _xmax, _ymin, _ymax);
00055 
00056    // tolerância considerada por causa do desenho da marca que ocupa vários
00057    // pixels da tela
00058    int tol = _size;
00059 
00060    double xt, yt;
00061    double x1, y1;
00062    int px1, py1;
00063 
00064    // verifica uma série
00065    for (int i = 0; i < npoints; ++i) {
00066      if (s -> point(i, xt, yt)) {
00067          x1 = _x_axis -> transform(xt);
00068          y1 = _y_axis -> transform(yt);
00069 
00070          // converte coordenadas (x1, y1) do mundo para coordenadas em pixel
00071          wdWorld2Canvas (x1, y1, &px1, &py1);
00072 
00073          if (mtPointInMark(x, y, px1, py1, tol)) {
00074             cdClip(mode);
00075             // restaura a região de clip anterior
00076             cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00077             return xytrue;
00078          }
00079      }
00080    }
00081 
00082    // restaura a região de clip anterior
00083    cdClip(mode);
00084    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00085 
00086    return xyfalse;
00087 }
00088 
00089 // .......................................................................
00090 
00091 xybool XYCartesianMarkMask::fence (int x2, int y2, int x3, int y3) {
00092    if (visible() == xyfalse) return xyfalse;
00093 
00094    // limites da menor caixa que contém uma máscara
00095    int x0, y0, x1, y1;
00096    boundingBox (x0, y0, x1, y1);
00097 
00098    return mtInclude (x0, y0, x1, y1, x2, y2, x3, y3);
00099 }
00100 
00101 // .......................................................................
00102 
00103 void XYCartesianMarkMask::drawIcon (int xmin, int ymin, 
00104 int xmax, int ymax) const {
00105    int xmid = (int)((double)(xmax + xmin) / 2);
00106    int ymid = (int)((double)(ymax + ymin) / 2);
00107 
00108    // ativa estilo, tamanho e cor da marca usada para desenhar a série
00109    cdMarkType(_mark);
00110    wdMarkSize(_size*.25);
00111    cdForeground(_color);
00112 
00113    cdMark (xmid, ymid);
00114 }
00115 
00116 // .......................................................................
00117 
00118 void XYCartesianMarkMask::draw (int xmin, int /* ymin */, 
00119 int xmax, int /* ymax */) const {
00120    if (visible() == xyfalse)  return;
00121    XYSeries* s = (XYSeries *) _series;
00122 
00123    // define domínio da série nos limites da área a ser desenhada:
00124    // domínio original da série
00125    double old_begin, old_end;
00126    s -> domain(&old_begin, &old_end);
00127 
00128    // novo domínio
00129    double begin, end;
00130 
00131    // define os parâmetros de visualização para o domínio do eixos na
00132    // região de desenho das máscaras. Isto é necessário para se poder
00133    // calcular os novos limites do eixo X em coordenadas do mundo
00134    setWindow (_x_axis -> min(), _x_axis -> max(), _y_axis -> min(),
00135                   _y_axis -> max());
00136 
00137    setViewport();
00138 
00139    // calcula os novos limites no eixo X, em coordenadas do mundo
00140    wdCanvas2World (xmin, 0, &begin, 0);
00141    wdCanvas2World (xmax, 0, &end, 0);
00142 
00143    // calcula o novo domínio para a série que é o domínio que está dentro
00144    // da região que vai ser desenhada. Agora, se a área não intercepta o
00145    // domínio, então retorna porque não há nada para ser desenhado
00146    if ((begin > old_end) || (end < old_begin)) return;
00147 
00148    if (begin < old_begin) begin = old_begin;
00149    if (end > old_end) end = old_end;
00150         
00151    // define o novo domínio
00152    s->domain(begin, end);
00153 
00154    // número de pontos na série
00155    int npoints = s->numPoints();
00156 
00157    // teste de inconsistência
00158    if (npoints < 1) {
00159       // restaura valores originais do domínio da série
00160       s->domain(old_begin, old_end);
00161       return;
00162    }
00163 
00164    // começa a desenhar:
00165 
00166    // transforma coordenadas máximas e mínimas de acordo com o tipo dos eixos
00167    // ativos e usa esses valores para a nova window
00168    setWindow (_x_axis -> transform(_x_axis -> min()),
00169                   _x_axis -> transform(_x_axis -> max()),
00170                   _y_axis -> transform(_y_axis -> min()),
00171                   _y_axis -> transform(_y_axis -> max()));
00172 
00173    setViewport();
00174 
00175    // ativa estilo, tamanho e cor da marca usada para desenhar a série
00176    cdMarkType(_mark);
00177    wdMarkSize(_size*.25);
00178    cdForeground(_color);
00179 
00180    // guarda o atual modo de clipping
00181    int mode = cdClip(CD_CLIPON);
00182 
00183    // guarda a região de clip corrente
00184    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00185    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00186    // define nova região de clip
00187    cdClipArea(_xmin, _xmax, _ymin, _ymax);
00188 
00189    cdWriteMode(CD_REPLACE);
00190 
00191    double xt, yt;
00192    double x1, y1;
00193    int vx1, vy1;
00194 
00195    // desenha uma série
00196    for (int i = 0; i < npoints; ++i)
00197    {
00198       if (s -> point(i, xt, yt))
00199       { x1 = _x_axis -> transform(xt);
00200         y1 = _y_axis -> transform(yt);
00201 
00202         // calcula os novos valores em coordenadas da tela
00203         wdWorld2Canvas (x1, y1, &vx1, &vy1);
00204 
00205         // desenha marca da série
00206         cdMark (vx1, vy1);
00207       }
00208    }
00209 
00210    // restaura valores originais do domínio da série
00211    s -> domain(old_begin, old_end);
00212 
00213    cdClip(mode);
00214    // restaura a região de clip anterior
00215    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00216 }
00217 
00218 // .......................................................................
00219 
00220 void XYCartesianMarkMask::boundingBox (int& bxmin, int& bymin, int& bxmax,
00221                                        int& bymax) const
00222 {
00223    if (visible() == xyfalse)  // invisível!!!
00224       return;
00225 
00226    XYSeries* s = (XYSeries *) _series;
00227 
00228    // número de pontos na série
00229    int npoints = s -> numPoints();
00230 
00231    double xt, yt;
00232 
00233    s -> point(0, xt, yt);
00234    double x1 = _x_axis -> transform(xt);
00235    double y1 = _y_axis -> transform(yt);
00236 
00237    int vx1, vy1;
00238    // calcula os novos valores em coordenadas da tela
00239    wdWorld2Canvas (x1, y1, &vx1, &vy1);
00240 
00241    // inicializa boundingBox
00242    bxmin = vx1;
00243    bymin = vy1;
00244    bxmax = vx1;
00245    bymax = vy1;
00246 
00247    // calcula boundingBox
00248    for (int i = 1; i < npoints; ++i)
00249    {
00250       s -> point(i, xt, yt);
00251       x1 = _x_axis -> transform(xt);
00252       y1 = _y_axis -> transform(yt);
00253 
00254       // calcula os novos valores em coordenadas da tela
00255       wdWorld2Canvas (x1, y1, &vx1, &vy1);
00256 
00257       bxmin = MIN(vx1, bxmin);
00258       bymin = MIN(vy1, bymin);
00259       bxmax = MAX(vx1, bxmax);
00260       bymax = MAX(vy1, bymax);
00261    }
00262 
00263    // restringe a boundingBox a área de desenho da máscara,
00264    // caso ela a ultrapasse
00265 
00266    if (bxmin > _xmin)
00267       bxmin = _xmin;
00268 
00269    if (bxmax > _xmax)
00270       bxmax = _xmax;
00271 
00272    if (bymin > _ymin)
00273       bymin = _ymin;
00274 
00275    if (bymax > _ymax)
00276       bymax =_ymax;
00277 }
00278 

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group