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

xymplln.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /* Módulo: xymplln.cpp                                                       */
00003 /* Autores: Camilo da Fonseca Freire                                         */
00004 /* Data: 10 jul 96                                                           */
00005 /* Comentário:                                                               */
00006 /*    Implementação de métodos da classe que representa através de segmentos */
00007 /* de retas conectados um conjunto de dados num gráfico polar.               */
00008 /*****************************************************************************/
00009 
00010 #include "xymplln.h"
00011 
00012 const char* xy_id_xymplln_cpp="$Id: xymplln.cpp,v 1.6 1999/12/09 21:47:46 rborges Exp $";
00013                                                                 
00014 XYPolarLineMask::XYPolarLineMask (XYText* name,
00015                                               XYSeries* series,
00016                                               const XYPolarAxis* axis,
00017                                               long color,
00018                                               int  width,
00019                                               LineStyle style,
00020                                               xybool  visible)
00021                                               : XYPolarMask(name, series, axis, color,
00022                                                                   visible),
00023                                                 _width(width),
00024                                                 _style(style)
00025 {
00026 }
00027 
00028 XYPolarLineMask::XYPolarLineMask (XYSeries* series,
00029                                               const XYPolarAxis* axis,
00030                                               long color,
00031                                               int  width,
00032                                               LineStyle style,
00033                                               xybool  visible)
00034                                               : XYPolarMask(series,     axis, color, visible),
00035                                                 _width(width),
00036                                                 _style(style)
00037 {
00038 }
00039 
00040 void XYPolarLineMask::width (int w)
00041 {
00042    _width = w;
00043 }
00044 
00045 int XYPolarLineMask::width (void) const
00046 {
00047    return _width;
00048 }
00049 
00050 void XYPolarLineMask::style (XYMask::LineStyle s)
00051 {
00052    _style = s;
00053 }
00054 
00055 int XYPolarLineMask::style (void) const
00056 {
00057    return _style;
00058 }
00059 
00060 void XYPolarLineMask::draw (void)
00061 {
00062    draw(_xmin, _ymin, _xmax, _ymax);
00063 }
00064 
00065 xybool XYPolarLineMask::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.0 milimetros  
00102    int tol_dx,tol_dy;
00103    cdMM2Pixel(2.0, 2.0, &tol_dx, &tol_dy); 
00104    tol_dy = _width > tol_dy ? _width : tol_dy; // coerente com largura da line
00105    double oldtol = mtTolerance((double)tol_dy);
00106    // define tolerância para 2 pixels calculado em relação ao y por causa da
00107    // função mtPointInLine
00108    //double oldtol;
00109    //oldtol = mtTolerance(2 * (2 * _axis -> max()) / (_ymax - _ymin + 1));
00110 
00111    double x2, y2;
00112 
00113    // verifica uma série
00114    for (int i = 1; i < npoints; ++i)
00115    {
00116       s -> point(i, a, r);
00117       _axis -> polar2cart(r, a, x2, y2);
00118 
00119       if (mtPointInLineEx(px, py, x1, y1, x2, y2))
00120             {
00121          cdClip(mode);
00122                      // restaura a região de clip anterior
00123          cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00124 
00125          mtTolerance(oldtol);
00126          return xytrue;
00127             }
00128 
00129       x1 = x2;
00130       y1 = y2;
00131    }
00132 
00133    cdClip(mode);
00134    // restaura a região de clip anterior
00135    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00136 
00137    mtTolerance(oldtol);
00138    return xyfalse;
00139 }
00140 
00141 xybool XYPolarLineMask::fence (int x2, int y2, int x3, int y3)
00142 {
00143    if (visible() == xyfalse)           // invisível!!!
00144       return xyfalse;
00145 
00146    // limites da menor caixa que contém uma máscara
00147    int x0, y0, x1, y1;
00148    boundingBox (x0, y0, x1, y1);
00149 
00150    return mtInclude (x0, y0, x1, y1, x2, y2, x3, y3);
00151 }
00152 
00153 void XYPolarLineMask::drawIcon (int xmin, int ymin, int xmax, int ymax) const
00154 {
00155    int ymid = (int)((double)(ymax + ymin) / 2);
00156 
00157    // ativa estilo, largura e cor da linha usada para desenhar a série
00158    cdLineStyle(_style);
00159    cdLineWidth(_width);
00160    cdForeground(_color);
00161 
00162    cdLine (xmin, ymid, xmax, ymid);
00163 }
00164 
00165 void XYPolarLineMask::draw (int xmin, int ymin, int xmax, int ymax) const
00166 {
00167    if (visible() == xyfalse)  // invisível!!!
00168       return;
00169 
00170    XYSeries* s = (XYSeries *) _series;
00171 
00172    // define domínio da série nos limites da área a ser desenhada:
00173 
00174    // domínio original da série
00175    double old_begin, old_end;
00176    s -> domain(&old_begin, &old_end);
00177 
00178    // novo domínio
00179    double begin, end;
00180 
00181    // define os parâmetros de visualização para o domínio do eixos na
00182    // região de desenho das máscaras. Isto é necessário para se poder
00183    // calcular os novos limites do eixo X em coordenadas do mundo
00184    setWindow (-_axis -> max(), _axis -> max(), -_axis -> max(), _axis -> max());
00185    setViewport();
00186 
00187    // calcula os novos limites no eixo X, em coordenadas do mundo
00188    wdCanvas2World (xmin, 0, &begin, 0);
00189    wdCanvas2World (xmax, 0, &end, 0);
00190 
00191    // calcula o novo domínio para a série que é o dominio que está dentro
00192    // da região que vai ser desenhada. Agora, se a área não intercepta o
00193    // domínio, então retorna porque não há nada para ser desenhado
00194    if ((begin > old_end) || (end < old_begin))
00195       return;
00196 
00197    if (begin < old_begin)
00198       begin = old_begin;
00199 
00200    if (end > old_end)
00201       end = old_end;
00202         
00203    // define o novo domínio
00204    s -> domain(begin, end);
00205 
00206    // número de pontos na série
00207    int npoints = s -> numPoints();
00208 
00209    // teste de inconsistência
00210    if (npoints <= 1)
00211    {
00212       // restaura valores originais do domínio da série
00213       s -> domain(old_begin, old_end);
00214       return;
00215    }
00216 
00217    // começa a desenhar:
00218 
00219    // ativa estilo, largura e cor da linha usada para desenhar a série
00220    cdLineStyle(_style);
00221    cdLineWidth(_width);
00222    cdForeground(_color);
00223 
00224    // guarda o atual modo de clipping
00225    int mode = cdClip(CD_CLIPON);
00226 
00227    // guarda a região de clip corrente
00228    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00229    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00230    // define nova região de clip
00231    cdClipArea(xmin, xmax, ymin, ymax);
00232 
00233    cdWriteMode(CD_REPLACE);
00234    wdBegin(CD_CLOSED_LINES);
00235 
00236    double r, a;
00237    s -> point(0, a, r);
00238 
00239    double x, y;
00240    _axis -> polar2cart(r, a, x, y);
00241    wdVertex(x, y);
00242 
00243    // desenha uma série
00244    for (int i = 1; i < npoints; ++i)
00245    {
00246       s -> point(i, a, r);
00247       _axis -> polar2cart(r, a, x, y);
00248       wdVertex(x, y);
00249    }
00250 
00251    wdEnd();
00252 
00253    // restaura valores originais do domínio da série
00254    s -> domain(old_begin, old_end);
00255 
00256    cdClip(mode);
00257    // restaura a região de clip anterior
00258    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00259 }
00260 
00261 void XYPolarLineMask::boundingBox (int& bxmin, int& bymin, int& bxmax,
00262                                    int& bymax) const
00263 {
00264    if (visible() == xyfalse)  // invisível!!!
00265       return;
00266 
00267    XYSeries* s = (XYSeries *) _series;
00268 
00269    // número de pontos na série
00270    int npoints = s -> numPoints();
00271 
00272    double r, a, x, y;
00273 
00274    s -> point(0, a, r);
00275    _axis -> polar2cart(r, a, x, y);
00276 
00277    // inicializa boundingBox
00278    double txmin = x;
00279    double tymin = y;
00280    double txmax = x;
00281    double tymax = y;
00282 
00283    // verifica uma série
00284    for (int i = 1; i < npoints; ++i)
00285    {
00286       s -> point(i, a, r);
00287       _axis -> polar2cart(r, a, x, y);
00288 
00289       txmin = MIN(x, txmin);
00290       tymin = MIN(y, tymin);
00291       txmax = MAX(x, txmax);
00292       tymax = MAX(y, tymax);
00293    }
00294 
00295    wdWorld2Canvas(txmin, tymin, &bxmin, &bymin);
00296    wdWorld2Canvas(txmax, tymax, &bxmax, &bymax);
00297 
00298    // restringe a boundingBox a área de desenho da máscara,
00299    // caso ela a ultrapasse
00300 
00301    if (bxmin > _xmin)
00302       bxmin = _xmin;
00303 
00304    if (bxmax > _xmax)
00305       bxmax = _xmax;
00306 
00307    if (bymin > _ymin)
00308       bymin = _ymin;
00309 
00310    if (bymax > _ymax)
00311       bymax =_ymax;
00312 }
00313 

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group