00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdlib.h>
00014 #include <math.h>
00015 #include <stdio.h>
00016
00017 #include "xygrid.h"
00018
00019 const char* xy_id_xygrid_cpp="$Id: xygrid.cpp,v 1.16 1999/12/09 21:47:46 rborges Exp $";
00020
00021 XYGrid::XYGrid (double mn,
00022 double mx,
00023 double p,
00024 long color,
00025 double rot,
00026 double step,
00027 xybool visible)
00028 : XYAxis(mn, mx, 0., 0., color, 1.0, rot, step, xyfalse, visible),
00029 _limit(0.),
00030 _style(continuous)
00031 {
00032 referenceTick(p);
00033 }
00034
00035 XYGrid::XYGrid (double mn,
00036 double mx,
00037 double p,
00038 long color,
00039 int style,
00040 double rot,
00041 double step,
00042 xybool visible)
00043 : XYAxis(mn, mx, 0., 0., color, 1.0, rot, step, xyfalse, visible),
00044 _limit(0.),
00045 _style(style)
00046 {
00047 referenceTick(p);
00048 }
00049
00050 void XYGrid::limit (double h)
00051 {
00052 _limit = h;
00053 }
00054
00055 double XYGrid::limit (void) const
00056 {
00057 return _limit;
00058 }
00059
00060 void XYGrid::style (int s)
00061 {
00062 _style = s;
00063 }
00064
00065 int XYGrid::style (void) const
00066 {
00067 return _style;
00068 }
00069
00070 xybool XYGrid::pointInGrid (int px, int py, int x0, int y0, int x1, int y1)
00071 {
00072 if ((x0 == x1) && (x1 == px))
00073 if ((y0 <= py) && (py <= y1))
00074 return xytrue;
00075
00076 if ((y0 == y1) && (y1 == py))
00077 if ((x0 <= px) && (px <= x1))
00078 return xytrue;
00079
00080 return xyfalse;
00081 }
00082
00083 xybool XYGrid::pick (int px, int py)
00084 {
00085 if (visible() == xyfalse)
00086 return xyfalse;
00087
00088
00089 double rot_rad = _rot * XY_PI / 180.0;
00090
00091
00092 double f = (first() - _mn) * _size / (_mx - _mn);
00093
00094
00095 double s = _step * _size / (_mx - _mn);
00096
00097
00098 double dx;
00099 double dy;
00100 mtRotate (s, 0, rot_rad, &dx, &dy);
00101
00102
00103 double x0, y0;
00104 position (&x0, &y0);
00105
00106
00107
00108 double x1 = x0 + f * cos (rot_rad);
00109 double y1 = y0 + f * sin (rot_rad);
00110
00111
00112
00113 double x2 = x1 + limit() * sin (rot_rad);
00114 double y2 = y1 + limit() * cos (rot_rad);
00115
00116
00117 double first = this -> first();
00118
00119
00120 double q = _mx;
00121
00122 int px1, py1, px2, py2;
00123
00124 for (double p = first; p <= q; p += _step)
00125 {
00126
00127 if (mtEqual(x1, x2))
00128 x2 = x1;
00129 if (mtEqual(y1, y2))
00130 y2 = y1;
00131
00132
00133 wdWorld2Canvas (x1, y1, &px1, &py1);
00134 wdWorld2Canvas (x2, y2, &px2, &py2);
00135
00136
00137 if (pointInGrid(px, py, px1, py1, px2, py2))
00138 return xytrue;
00139
00140
00141 x1 += dx;
00142 x2 += dx;
00143 y1 += dy;
00144 y2 += dy;
00145 }
00146
00147 return xyfalse;
00148 }
00149
00150 int XYGrid::worldSize2PixelSize (double w) const
00151 {
00152
00153 double rot_rad = _rot * XY_PI / 180.0;
00154
00155 w = (transform(w) - transform(_mn)) * _size
00156 / (transform(_mx) - transform(_mn));
00157
00158
00159 double dx;
00160 double dy;
00161 mtRotate (w, 0, rot_rad, &dx, &dy);
00162
00163
00164 int pdx,pdy;
00165 wdWorld2Canvas (dx, dy, &pdx, &pdy);
00166
00167 return (int) mtDistance(pdx, 0, 0, pdy);
00168 }
00169
00170 void XYGrid::draw (void)
00171 {
00172 draw (_xmin, _ymin, _xmax, _ymax);
00173 }
00174
00175 void XYGrid::draw (int xmin, int ymin, int xmax, int ymax) const
00176 {
00177 if (visible() == xyfalse)
00178 return;
00179
00180
00181 double rot_rad = _rot * XY_PI / 180.0;
00182
00183
00184 double f = (first() - _mn) * _size / (_mx - _mn);
00185
00186
00187 double s = _step * _size / (_mx - _mn);
00188
00189
00190 if (s <= 0.01)
00191 return;
00192
00193 int mode = cdClip(CD_CLIPON);
00194
00195
00196 int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00197 cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00198
00199
00200 cdClipArea(xmin, xmax, ymin, ymax);
00201
00202
00203 double dx;
00204 double dy;
00205 mtRotate (s, 0, rot_rad, &dx, &dy);
00206
00207
00208 double x0, y0;
00209 position (&x0, &y0);
00210
00211
00212
00213 double x1 = x0 + f * cos (rot_rad);
00214 double y1 = y0 + f * sin (rot_rad);
00215
00216
00217
00218 double x2 = x1 + limit() * sin (rot_rad);
00219 double y2 = y1 + limit() * cos (rot_rad);
00220
00221
00222 double first = this -> first();
00223
00224
00225 double mx;
00226
00227
00228 double pxmin = (double) (xmin - _xmin) / (_xmax - _xmin);
00229 double pymin = (double) (ymin - _ymin) / (_ymax - _ymin);
00230 double pxmax = (double) (xmax - _xmin) / (_xmax - _xmin);
00231 double pymax = (double) (ymax - _ymin) / (_ymax - _ymin);
00232
00233
00234
00235 if (mtEqual(x1, x2))
00236 {
00237
00238
00239
00240 while (x1 < pxmin)
00241 {
00242
00243 x1 += dx;
00244
00245
00246 first += _step;
00247 }
00248
00249
00250 x2 = x1;
00251
00252
00253
00254
00255
00256
00257 mx = first;
00258
00259 while ((x1 < pxmax) && (mx < _mx) && !mtEqual(_mx, mx))
00260 {
00261
00262 x1 += dx;
00263
00264
00265 mx += _step;
00266 }
00267
00268
00269 x1 = x2;
00270
00271
00272
00273 if (y1 < pymin)
00274 y1 = pymin;
00275
00276 if (y2 > pymax)
00277 y2 = pymax;
00278 }
00279
00280
00281 else if (mtEqual(y1, y2))
00282 {
00283
00284
00285
00286 while (y1 < pymin)
00287 {
00288
00289 y1 += dy;
00290
00291
00292 first += _step;
00293 }
00294
00295
00296 y2 = y1;
00297
00298
00299
00300
00301
00302 mx = first;
00303
00304 while ((y1 < pymax) && (mx < _mx) && !mtEqual(_mx, mx))
00305 {
00306
00307 y1 += dy;
00308
00309
00310 mx += _step;
00311 }
00312
00313
00314 y1 = y2;
00315
00316
00317
00318 if (x1 < pxmin)
00319 x1 = pxmin;
00320
00321 if (x2 > pxmax)
00322 x2 = pxmax;
00323 }
00324
00325
00326
00327 cdLineWidth (1);
00328 cdLineStyle (_style);
00329 cdForeground (_color);
00330
00331
00332
00333 for (double p = first; mtLessEqual(p, _mx); p += _step)
00334 {
00335
00336 wdLine(x1, y1, x2, y2);
00337
00338
00339 x1 += dx;
00340 x2 += dx;
00341 y1 += dy;
00342 y2 += dy;
00343 }
00344
00345 cdClip(mode);
00346
00347
00348 cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00349 }
00350
00351 void XYGrid::boundingBox (int& xmin, int& ymin, int& xmax, int& ymax) const
00352 {
00353 if (visible() == xyfalse)
00354 return;
00355
00356
00357 double rot_rad = _rot * XY_PI / 180.0;
00358
00359
00360 double f = (first() - _mn) * _size / (_mx - _mn);
00361
00362
00363 double s = _step * _size / (_mx - _mn);
00364
00365
00366 if (s <= 0.01)
00367 return;
00368
00369
00370 double dx;
00371 double dy;
00372 mtRotate (s, 0, rot_rad, &dx, &dy);
00373
00374
00375 double x0, y0;
00376 position (&x0, &y0);
00377
00378
00379
00380 double x1 = x0 + f * cos (rot_rad);
00381 double y1 = y0 + f * sin (rot_rad);
00382
00383
00384
00385 double x2 = x1 + limit() * sin (rot_rad);
00386 double y2 = y1 + limit() * cos (rot_rad);
00387
00388 int bx1, by1, bx2, by2;
00389
00390
00391 wdWorld2Canvas (x1, y1, &bx1, &by1);
00392 wdWorld2Canvas (x2, y2, &bx2, &by2);
00393
00394
00395 xmin = MIN(bx1, bx2);
00396 ymin = MIN(by1, by2);
00397 xmax = MAX(bx1, bx2);
00398 ymax = MAX(by1, by2);
00399
00400
00401 for (double p = first(); p < _mx; p += _step)
00402 {
00403
00404 x1 += dx;
00405 x2 += dx;
00406 y1 += dy;
00407 y2 += dy;
00408
00409
00410 wdWorld2Canvas (x1, y1, &bx1, &by1);
00411 wdWorld2Canvas (x2, y2, &bx2, &by2);
00412
00413
00414 xmin = MIN3(bx1, bx2, xmin);
00415 ymin = MIN3(by1, by2, ymin);
00416 xmax = MAX3(bx1, bx2, xmax);
00417 ymax = MAX3(by1, by2, ymax);
00418 }
00419 }
00420