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