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