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

xymplmk.cpp

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

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group