00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdlib.h>
00011 #include <math.h>
00012 #include <stdio.h>
00013
00014 #include "xyaxlg.h"
00015 #include "xysdlg.h"
00016
00017 const char* xy_id_xyaxlg_cpp="$Id: xyaxlg.cpp,v 1.24 2003/01/03 16:10:34 clinio Exp $";
00018
00019 XYLogAxis::XYLogAxis (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, decorator,
00032 title, arrow, visible)
00033 {
00034 }
00035
00036 XYLogAxis::XYLogAxis (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, visible)
00046 {
00047 }
00048
00049 double XYLogAxis::transform (double e) const
00050 {
00051 if (fabs(e) <= 1e-50) return -1000.0;
00052 double value = log10(e);
00053 return value;
00054 }
00055
00056 double XYLogAxis::defineMinPoint(double value, int x0, int y0) const
00057 {
00058 setWindow();
00059 setViewport();
00060
00061 double dx0, dy0;
00062 wdCanvas2World(x0, y0, &dx0, &dy0);
00063
00064
00065 double rot_rad = _rot * XY_PI / 180.0;
00066
00067
00068 double x1, y1;
00069 position (&x1, &y1);
00070
00071
00072 double x2 = x1 + _size * cos (rot_rad);
00073 double y2 = y1 + _size * sin (rot_rad);
00074
00075 double min;
00076
00077 if (rot_rad == 0.0)
00078 min = _mx - (_mx - value) * _size / (x2 - dx0);
00079 else
00080 min = _mx - (_mx - value) * _size / (y2 - dy0);
00081
00082 return min;
00083 }
00084
00085 double XYLogAxis::defineMaxPoint(double value, int x0, int y0) const
00086 {
00087 setWindow();
00088 setViewport();
00089
00090 double dx0, dy0;
00091 wdCanvas2World(x0, y0, &dx0, &dy0);
00092
00093
00094 double rot_rad = _rot * XY_PI / 180.0;
00095
00096
00097 double x1, y1;
00098 position (&x1, &y1);
00099
00100 double max;
00101
00102 if (rot_rad == 0.0)
00103 max = _mn + (value - _mn) * size() / (dx0 - x1);
00104 else
00105 max = _mn + (value - _mn) * size() / (dy0 - y1);
00106
00107 return max;
00108 }
00109
00110 double XYLogAxis::valueInPoint(int x0, int y0) const
00111 {
00112
00113 double ow_xmin,ow_xmax,ow_ymin,ow_ymax;
00114 int oc_xmin, ov_xmax, ov_ymin, ov_ymax;
00115 wdGetWindow(&ow_xmin,&ow_xmax,&ow_ymin,&ow_ymax);
00116 wdGetViewport(&oc_xmin,&ov_xmax,&ov_ymin,&ov_ymax);
00117
00118 setWindow();
00119 setViewport();
00120
00121 double dx0, dy0;
00122 wdCanvas2World(x0, y0, &dx0, &dy0);
00123
00124
00125 double rot_rad = _rot * XY_PI / 180.0;
00126
00127
00128 double x1, y1;
00129 position (&x1, &y1);
00130
00131 double value;
00132
00133 if (rot_rad == 0.0)
00134 value = log10(_mn) + (dx0 - x1) * (log10(_mx) - log10(_mn)) / size();
00135 else
00136 value = log10(_mn) + (dy0 - y1) * (log10(_mx) - log10(_mn)) / size();
00137
00138 wdWindow(ow_xmin,ow_xmax,ow_ymin,ow_ymax);
00139 wdViewport(oc_xmin, ov_xmax, ov_ymin, ov_ymax);
00140
00141 return pow(10,value);
00142 }
00143
00144 double XYLogAxis::valueInPoint(double x0, double y0) const
00145 {
00146
00147 double ow_xmin,ow_xmax,ow_ymin,ow_ymax;
00148 int oc_xmin, ov_xmax, ov_ymin, ov_ymax;
00149 wdGetWindow(&ow_xmin,&ow_xmax,&ow_ymin,&ow_ymax);
00150 wdGetViewport(&oc_xmin,&ov_xmax,&ov_ymin,&ov_ymax);
00151
00152
00153 double rot_rad = _rot * XY_PI / 180.0;
00154
00155
00156 double x1, y1;
00157 position (&x1, &y1);
00158
00159 double value;
00160 if (rot_rad == 0.0)
00161 value = log10(_mn) + (x0 - x1) * ( log10(_mx) - log10(_mn) ) / size();
00162 else
00163 value = log10(_mn) + (y0 - y1) * ( log10(_mx) - log10(_mn) ) / size();
00164
00165 wdWindow(ow_xmin,ow_xmax,ow_ymin,ow_ymax);
00166 wdViewport(oc_xmin, ov_xmax, ov_ymin, ov_ymax);
00167
00168 return pow(10,value);
00169 }
00170
00171 void XYLogAxis::pointInValue(double value, int& x0, int& y0) const
00172 {
00173
00174 double ow_xmin,ow_xmax,ow_ymin,ow_ymax;
00175 int oc_xmin, ov_xmax, ov_ymin, ov_ymax;
00176 wdGetWindow(&ow_xmin,&ow_xmax,&ow_ymin,&ow_ymax);
00177 wdGetViewport(&oc_xmin,&ov_xmax,&ov_ymin,&ov_ymax);
00178
00179 setWindow();
00180 setViewport();
00181
00182
00183 double rot_rad = _rot * XY_PI / 180.0;
00184
00185
00186 double x1, y1;
00187 position (&x1, &y1);
00188
00189
00190 double dx0 = x1 + (log10(value) - log10(_mn)) * _size / (log10(_mx) - log10(_mn)) * cos (rot_rad);
00191 double dy0 = y1 + (log10(value) - log10(_mn)) * _size / (log10(_mx) - log10(_mn)) * sin (rot_rad);
00192
00193 wdWorld2Canvas(dx0, dy0, &x0, &y0);
00194
00195
00196
00197 wdWindow(ow_xmin,ow_xmax,ow_ymin,ow_ymax);
00198 wdViewport(oc_xmin, ov_xmax, ov_ymin, ov_ymax);
00199
00200 }
00201
00202 void XYLogAxis::pointInValue(double value, double& x0, double& y0) const
00203 {
00204
00205 double ow_xmin,ow_xmax,ow_ymin,ow_ymax;
00206 int oc_xmin, ov_xmax, ov_ymin, ov_ymax;
00207 wdGetWindow(&ow_xmin,&ow_xmax,&ow_ymin,&ow_ymax);
00208 wdGetViewport(&oc_xmin,&ov_xmax,&ov_ymin,&ov_ymax);
00209
00210
00211 double rot_rad = _rot * XY_PI / 180.0;
00212
00213
00214 double x1, y1;
00215 position (&x1, &y1);
00216
00217
00218 x0 = x1 + (log10(value) - log10(_mn)) * _size / (log10(_mx) - log10(_mn)) * cos (rot_rad);
00219 y0 = y1 + (log10(value) - log10(_mn)) * _size / (log10(_mx) - log10(_mn)) * sin (rot_rad);
00220
00221
00222
00223
00224 wdWindow(ow_xmin,ow_xmax,ow_ymin,ow_ymax);
00225 wdViewport(oc_xmin, ov_xmax, ov_ymin, ov_ymax);
00226 }
00227
00228 void XYLogAxis::draw (void)
00229 {
00230 draw (_xmin, _ymin, _xmax, _ymax);
00231 }
00232
00233 void XYLogAxis::draw (int xmin, int ymin, int xmax, int ymax) const
00234 {
00235 if (visible() == xyfalse) return;
00236
00237 int mode = cdClip(CD_CLIPON);
00238
00239
00240 int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00241 cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00242
00243 cdClipArea(xmin, xmax, ymin, ymax);
00244
00245
00246 double rot_rad = _rot * XY_PI / 180.0;
00247
00248
00249 double x1, y1;
00250 position (&x1, &y1);
00251
00252
00253 double x2 = x1 + _size * cos (rot_rad);
00254 double y2 = y1 + _size * sin (rot_rad);
00255
00256
00257 if (mtEqual(x1, x2)) x2 = x1;
00258 if (mtEqual(y1, y2)) y2 = y1;
00259
00260
00261
00262 cdLineWidth (2);
00263 cdLineStyle (continuous);
00264 cdForeground (_color);
00265
00266
00267 wdLine (x1, y1, x2, y2);
00268
00269
00270 if (_arrow == xytrue)
00271 {
00272 cdInteriorStyle (CD_SOLID);
00273 drawArrow(x1, y1, x2, y2);
00274 }
00275
00276
00277 if (_step > 0.0)
00278 {
00279 double xorigin, yorigin;
00280 position(&xorigin, &yorigin);
00281
00282 double decade_step;
00283 for( double val = _mn; val <= _mx; val += decade_step *_step )
00284 {
00285 int current_decade = mtDecade( val );
00286 decade_step = pow( 10, current_decade );
00287 double dx, dy;
00288 mtRotate( (log10(val)-log10(_mn))*_size / (log10(_mx)-log10(_mn)), 0.0,
00289 rot_rad, &dx, &dy);
00290
00291 double xtick = xorigin + dx;
00292 double ytick = yorigin + dy;
00293
00294 cdMarkType( CD_PLUS );
00295 wdMarkSize( 1.0 );
00296 wdMark(xtick, ytick);
00297
00298 }
00299
00300
00301 if (_decor)
00302 _decor -> draw(this, 0, 0 );
00303
00304 }
00305
00306
00307
00308 if (_title)
00309 {
00310
00311 int xmn, ymn, xmx, ymx;
00312 getViewport(xmn, xmx, ymn, ymx);
00313
00314
00315 _title -> setViewport(xmn, xmx, ymn, ymx);
00316 _title -> draw();
00317 }
00318
00319 cdClip(mode);
00320
00321 cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00322 }
00323
00324 void XYLogAxis::boundingBox (int& bxmin, int& bymin, int& bxmax, int& bymax)
00325 const
00326 {
00327
00328 double rot_rad = _rot * XY_PI / 180.0;
00329
00330
00331 double x1, y1;
00332 position (&x1, &y1);
00333
00334
00335 double x2 = x1 + _size * cos (rot_rad);
00336 double y2 = y1 + _size * sin (rot_rad);
00337
00338
00339 if (mtEqual(x1, x2))
00340 x2 = x1;
00341 if (mtEqual(y1, y2))
00342 y2 = y1;
00343
00344
00345 double xmin = MIN(x1, x2);
00346 double ymin = MIN(y1, y2);
00347 double xmax = MAX(x1, x2);
00348 double ymax = MAX(y1, y2);
00349
00350
00351 if (_arrow == xytrue)
00352 {
00353 double bx1, bx2, by1, by2;
00354 boxArrow(x1, y1, x2, y2, bx1, by1, bx2, by2);
00355
00356 xmin = MIN(bx1, xmin);
00357 xmax = MAX(bx2, xmax);
00358 ymin = MIN(by1, ymin);
00359 ymax = MAX(by2, ymax);
00360 }
00361
00362
00363
00364 if (_step > 0.0)
00365 {
00366
00367 double ex1, ey1, ex2, ey2;
00368 firstTick (ex1, ey1, ex2, ey2);
00369
00370 xmin = MIN3 (xmin, ex1, ex2);
00371 xmax = MAX3 (xmax, ex1, ex2);
00372 ymin = MIN3 (ymin, ey1, ey2);
00373 ymax = MAX3 (ymax, ey1, ey2);
00374
00375 int bex1, bey1, bex2, bey2;
00376
00377
00378 if (_decor)
00379 _decor -> boundingBox (this, bex1, bey1, bex2, bey2);
00380
00381 wdCanvas2World (bex1, bey1, &ex1, &ey1);
00382 wdCanvas2World (bex2, bey2, &ex2, &ey2);
00383
00384 xmin = MIN3 (xmin, ex1, ex2);
00385 xmax = MAX3 (xmax, ex1, ex2);
00386 ymin = MIN3 (ymin, ey1, ey2);
00387 ymax = MAX3 (ymax, ey1, ey2);
00388 }
00389
00390
00391 wdWorld2Canvas (xmin, ymin, &bxmin, &bymin);
00392 wdWorld2Canvas (xmax, ymax, &bxmax, &bymax);
00393 }
00394