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

xymcamk.cpp

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

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group