00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "xymcaar.h"
00011
00012
00013
00014 #define XCROSSLINE(x1,y1, x2,y2, x) ((((x-x1)*(y2-y1))/(x2-x1))+y1)
00015
00016
00017
00018 const char* xy_id_xymcaar_cpp="$Id: xymcaar.cpp,v 1.2 2000/09/18 17:42:15 clinio Exp $";
00019
00020
00021
00022 XYCartesianAreaMask::XYCartesianAreaMask (
00023 XYText* name,
00024 XYSeries* series,
00025 const XYAxis* x_axis,
00026 const XYAxis* y_axis,
00027 long color,
00028 xybool visible, double value ) :
00029 XYCartesianMask( name, series, x_axis, y_axis, color, visible ), _value(value)
00030 {
00031 }
00032
00033
00034
00035 XYCartesianAreaMask::XYCartesianAreaMask(
00036 XYSeries* series,
00037 const XYAxis* x_axis,
00038 const XYAxis* y_axis,
00039 long color,
00040 xybool visible, double value ) :
00041 XYCartesianMask( series, x_axis, y_axis, color, visible), _value(value)
00042 {
00043 }
00044
00045
00046
00047 void XYCartesianAreaMask::draw( void )
00048 {
00049 draw(_xmin, _ymin, _xmax, _ymax);
00050 }
00051
00052
00053
00054 xybool XYCartesianAreaMask::pick (int x, int y)
00055 {
00056 if (visible() == xyfalse) return xyfalse;
00057
00058 XYSeries* s = (XYSeries *) _series;
00059 int npoints = s -> numPoints();
00060
00061
00062 if ( (npoints <= 1) || (x < _xmin) ||
00063 (_xmax < x) || (y < _ymin) || (_ymax < y))
00064 return xyfalse;
00065
00066 setWindow (_x_axis -> transform(_x_axis -> min()),
00067 _x_axis -> transform(_x_axis -> max()),
00068 _y_axis -> transform(_y_axis -> min()),
00069 _y_axis -> transform(_y_axis -> max()));
00070 setViewport();
00071
00072
00073 int oldmode = cdClip(CD_CLIPON);
00074 int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00075 cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00076
00077
00078 cdClipArea(_xmin, _xmax, _ymin, _ymax);
00079
00080
00081 double px, py;
00082 wdCanvas2World (x, y, &px, &py);
00083
00084 double xt, yt;
00085
00086 int ifirst=0;
00087 while (!(s -> point(ifirst, xt, yt))) ifirst++;
00088
00089 double x1 = _x_axis -> transform(xt);
00090 double y1 = _y_axis -> transform(yt);
00091 int px1,py1;
00092 wdWorld2Canvas(x1, y1, &px1, &py1);
00093
00094
00095 int tol_dx,tol_dy;
00096 cdMM2Pixel(2.0, 2.0, &tol_dx, &tol_dy);
00097 double oldtol = mtTolerance((double)tol_dy);
00098
00099
00100 xybool hit = xyfalse;
00101 int iprevious = ifirst;
00102 for (int i = (ifirst+1); i < npoints; ++i)
00103 {
00104 int px2,py2,yint;
00105
00106 if (s -> point(i, xt, yt))
00107 {
00108 double x2 = _x_axis -> transform(xt);
00109 double y2 = _y_axis -> transform(yt);
00110 wdWorld2Canvas(x2, y2, &px2, &py2);
00111 yint = XCROSSLINE( px1, py1, px2, py2, x );
00112
00113 if ( x >= px1 && x <= px2 && y <= yint && (i==(iprevious+1)))
00114 {
00115 hit = xytrue;
00116 break;
00117 }
00118
00119 px1 = px2;
00120 py1 = py2;
00121 iprevious = i;
00122 }
00123 }
00124
00125
00126 cdClip(oldmode);
00127 cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00128 mtTolerance(oldtol);
00129
00130 return hit;
00131 }
00132
00133
00134
00135 xybool XYCartesianAreaMask::fence (int x2, int y2, int x3, int y3)
00136 {
00137 if (visible() == xyfalse) return xyfalse;
00138
00139
00140 int x0, y0, x1, y1;
00141 boundingBox (x0, y0, x1, y1);
00142
00143 return mtInclude (x0, y0, x1, y1, x2, y2, x3, y3);
00144 }
00145
00146
00147
00148 void XYCartesianAreaMask::drawIcon (int xmin, int ymin, int xmax, int ymax)
00149 const
00150 {
00151
00152 cdForeground(_color);
00153
00154 cdBox(xmin, ymin, xmax, ymax);
00155 }
00156
00157
00158
00159 void XYCartesianAreaMask::draw (int xmin, int , int xmax, int ) const
00160 {
00161 if (visible() == xyfalse) return;
00162
00163 XYSeries* s = (XYSeries *) _series;
00164
00165
00166
00167 double old_begin, old_end;
00168 s -> domain(&old_begin, &old_end);
00169 double old_xf, old_xl, old_yf, old_yl;
00170 s -> point(0, old_xf, old_yf);
00171 s -> point(s -> numPoints()-1, old_xl, old_yl);
00172
00173
00174 double begin, end;
00175
00176
00177
00178
00179 double wxmin = _x_axis -> transform(_x_axis -> min());
00180 double wymin = _y_axis -> transform(_y_axis -> min());
00181 double wxmax = _x_axis -> transform(_x_axis -> max());
00182 double wymax = _y_axis -> transform(_y_axis -> max());
00183
00184 setWindow (wxmin, wxmax, wymin, wymax);
00185 setViewport();
00186
00187
00188 wdCanvas2World (xmin, 0, &begin, 0);
00189 wdCanvas2World (xmax, 0, &end, 0);
00190
00191
00192
00193
00194 if ((begin > old_end) || (end < old_begin))
00195 return;
00196
00197 if (begin < old_begin) begin = old_begin;
00198 if (end > old_end) end = old_end;
00199
00200
00201 s -> domain(begin, end);
00202
00203
00204 int npoints = s -> numPoints();
00205
00206
00207
00208
00209 cdForeground(_color);
00210 cdWriteMode(CD_REPLACE);
00211
00212
00213 int mode = cdClip(CD_CLIPON);
00214
00215
00216 int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00217 cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00218
00219 cdClipArea(_xmin, _xmax, _ymin, _ymax);
00220
00221 double xt, yt;
00222 int ifirst=0;
00223 int iprevious=ifirst;
00224 while (!(s -> point(ifirst, xt, yt))) ifirst++;
00225
00226 double x1 = _x_axis -> transform(xt);
00227 double y1 = _y_axis -> transform(yt);
00228
00229 double x2, y2, yz;
00230
00231 if (old_xf < begin || old_xf > end )
00232 {
00233 if (s -> point((unsigned)-1, xt, yt))
00234 {
00235 x2 = _x_axis -> transform(xt);
00236 y2 = _y_axis -> transform(yt);
00237
00238
00239 x2 = _x_axis -> transform(xt);
00240 y2 = _y_axis -> transform(yt);
00241 yz = _y_axis -> transform(_value);
00242
00243
00244 wdBegin( CD_FILL );
00245 wdVertex( x1, yz );
00246 wdVertex( x2, yz );
00247 wdVertex( x2, y2 );
00248 wdVertex( x1, y1 );
00249 wdEnd();
00250 }
00251 }
00252
00253
00254 int i = 0;
00255 for (i = (ifirst+1); i < npoints; ++i)
00256 {
00257 if (s -> point(i, xt, yt))
00258 {
00259 x2 = _x_axis -> transform(xt);
00260 y2 = _y_axis -> transform(yt);
00261 yz = _y_axis -> transform(_value);
00262
00263
00264
00265 if (i == (iprevious+1))
00266 { wdBegin( CD_FILL );
00267 wdVertex( x1, yz );
00268 wdVertex( x2, yz );
00269 wdVertex( x2, y2 );
00270 wdVertex( x1, y1 );
00271 wdEnd();
00272 }
00273
00274 x1 = x2;
00275 y1 = y2;
00276 iprevious = i;
00277 }
00278 }
00279
00280 if ( old_xl < begin || old_xl > end )
00281 {
00282 if (s -> point(i, xt, yt))
00283 {
00284 x2 = _x_axis -> transform(xt);
00285 y2 = _y_axis -> transform(yt);
00286
00287
00288 yz = _y_axis -> transform(_value);
00289 wdBegin( CD_FILL );
00290 wdVertex( x1, yz );
00291 wdVertex( x2, yz );
00292 wdVertex( x2, y2 );
00293 wdVertex( x1, y1 );
00294 wdEnd();
00295 }
00296 }
00297
00298
00299 s -> domain(old_begin, old_end);
00300
00301 cdClip(mode);
00302
00303 cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00304 }
00305
00306
00307
00308 void XYCartesianAreaMask::boundingBox (int& bxmin, int& bymin, int& bxmax,
00309 int& bymax) const
00310 {
00311 if (visible() == xyfalse) return;
00312
00313 XYSeries* s = (XYSeries *) _series;
00314
00315
00316 int npoints = s -> numPoints();
00317
00318 double xt, yt;
00319
00320 s -> point(0, xt, yt);
00321 double x1 = _x_axis -> transform(xt);
00322 double y1 = _y_axis -> transform(yt);
00323
00324 s -> point(1, xt, yt);
00325 double x2 = _x_axis -> transform(xt);
00326 double y2 = _y_axis -> transform(yt);
00327
00328
00329 if (mtEqual(x1, x2)) x2 = x1;
00330 if (mtEqual(y1, y2)) y2 = y1;
00331
00332
00333 double txmin = MIN(x1, x2);
00334 double tymin = MIN(y1, y2);
00335 double txmax = MAX(x1, x2);
00336 double tymax = MAX(y1, y2);
00337
00338
00339 for (int i = 2; i < npoints; ++i)
00340 { x1 = x2;
00341 y1 = y2;
00342
00343 s -> point(i, xt, yt);
00344 x2 = _x_axis -> transform(xt);
00345 y2 = _y_axis -> transform(yt);
00346
00347
00348 if (mtEqual(x1, x2)) x2 = x1;
00349 if (mtEqual(y1, y2)) y2 = y1;
00350
00351 txmin = MIN(x2, txmin);
00352 tymin = MIN(y2, tymin);
00353 txmax = MAX(x2, txmax);
00354 tymax = MAX(y2, tymax);
00355 }
00356
00357 tymin = MIN(_y_axis->min(), tymin);
00358 tymax = MAX(_y_axis->min(), tymax);
00359
00360 wdWorld2Canvas(txmin, tymin, &bxmin, &bymin);
00361 wdWorld2Canvas(txmax, tymax, &bxmax, &bymax);
00362
00363
00364
00365 if (bxmin > _xmin) bxmin = _xmin;
00366 if (bxmax > _xmax) bxmax = _xmax;
00367 if (bymin > _ymin) bymin = _ymin;
00368 if (bymax > _ymax) bymax =_ymax;
00369 }
00370
00371
00372
00373
00374