00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "xymath.h"
00013 #include "xysdnm.h"
00014 #include "xyaxln.h"
00015
00016 const char* xy_id_xyscdtnm_cpp="$Id: xysdnm.cpp,v 1.16 2001/05/15 18:36:24 camilo Exp $";
00017
00018 XYNumericalScaleDecorator::XYNumericalScaleDecorator (char *format,
00019 XYRasterText* scale)
00020 : _format(strdup(format)),
00021 _scale(scale),
00022 _exp(1.)
00023 {
00024 }
00025
00026 XYNumericalScaleDecorator::XYNumericalScaleDecorator (char *format,
00027 double exp,
00028 XYRasterText* scale)
00029 : _format(strdup(format)),
00030 _scale(scale),
00031 _exp(exp)
00032 {
00033 }
00034
00035 XYNumericalScaleDecorator::~XYNumericalScaleDecorator (void)
00036 {
00037 }
00038
00039 void XYNumericalScaleDecorator::exp (double e)
00040 {
00041 _exp = e;
00042 }
00043
00044 double XYNumericalScaleDecorator::exp (void) const
00045 {
00046 return _exp;
00047 }
00048
00049 void XYNumericalScaleDecorator::format (char* f)
00050 {
00051 _format = strdup(f);
00052 }
00053
00054 char* XYNumericalScaleDecorator::format (void) const
00055 {
00056 return _format;
00057 }
00058
00059 void XYNumericalScaleDecorator::scale (XYRasterText* s)
00060 {
00061 _scale = s;
00062 }
00063
00064 XYRasterText* XYNumericalScaleDecorator::scale (void) const
00065 {
00066 return _scale;
00067 }
00068
00069 void XYNumericalScaleDecorator::draw (const XYAxis *axis, int ,
00070 int ) const
00071 {
00072
00073 double dx, dy;
00074 double rot_rad = axis -> rotation() * XY_PI / 180.0;
00075
00076 mtRotate ((axis -> step() * axis -> size()) / (axis -> max()
00077 - axis -> min()), 0.0, rot_rad, &dx, &dy);
00078
00079 double ex1, ey1, ex2, ey2;
00080 axis -> firstTick (ex1, ey1, ex2, ey2);
00081
00082
00083 int xmn, ymn, xmx, ymx;
00084 axis -> getViewport(xmn, xmx, ymn, ymx);
00085
00086
00087 _scale -> setViewport(xmn, xmx, ymn, ymx);
00088
00089 double tex2 = ex2;
00090 double tey2 = ey2;
00091
00092 int ftx1, ftx2, fty1, fty2;
00093 int ltx1, ltx2, lty1, lty2;
00094
00095
00096
00097
00098
00099
00100 char c[80];
00101 sprintf (c, _format, axis -> first()/_exp);
00102
00103 _scale -> text (c);
00104 _scale -> position (tex2, tey2);
00105 _scale -> boundingBox(ftx1, fty1, ftx2, fty2);
00106
00107
00108 int total = (int) floor ((axis -> max() - axis -> first()) / axis -> step());
00109
00110
00111 sprintf (c, _format, axis -> max()/_exp);
00112
00113 _scale -> text (c);
00114 _scale -> position (tex2 + dx * total, tey2 + dy * total);
00115 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00116
00117
00118
00119 double mor = ((ltx2 - ltx1) > (ftx2 - ftx1)) ? axis -> max()
00120 : axis -> first();
00121
00122
00123 sprintf (c, _format, mor/_exp);
00124
00125 _scale -> text (c);
00126 _scale -> position (tex2, tey2);
00127 _scale -> boundingBox(ftx1, fty1, ftx2, fty2);
00128
00129
00130 tex2 += dx;
00131 tey2 += dy;
00132
00133
00134 sprintf (c, _format, mor/_exp);
00135
00136 _scale -> text (c);
00137 _scale -> position (tex2, tey2);
00138 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00139
00140
00141 int test_intercept = 1;
00142
00143
00144
00145 while (mtIntercept (ftx1, fty1, ftx2, fty2, ltx1, lty1, ltx2, lty2) != 0)
00146 {
00147 ++test_intercept;
00148
00149
00150 tex2 += dx;
00151 tey2 += dy;
00152
00153
00154 sprintf (c, _format, mor/_exp);
00155
00156 _scale -> text (c);
00157 _scale -> position (tex2, tey2);
00158 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00159 }
00160
00161
00162 int ntick = 0;
00163
00164 for (double tick = axis -> first();
00165 mtLessEqual ( tick, axis -> max() );
00166 tick += axis -> step())
00167 {
00168
00169 sprintf (c, _format, tick/_exp);
00170
00171
00172 _scale -> text (c);
00173 _scale -> position (ex2, ey2);
00174
00175 if (ntick % test_intercept == 0)
00176
00177 _scale -> draw (xmn, ymn, xmx, ymx);
00178
00179
00180 ex2 += dx;
00181 ey2 += dy;
00182
00183 ++ntick;
00184 }
00185 }
00186
00187 void XYNumericalScaleDecorator::boundingBox (const XYAxis *axis, int& bxmin,
00188 int& bymin, int& bxmax,
00189 int& bymax) const
00190 {
00191
00192 double dx, dy;
00193 double rot_rad = axis -> rotation() * XY_PI / 180.0;
00194
00195 mtRotate ((axis -> step() * axis -> size()) / (axis -> max()
00196 - axis -> min()), 0, rot_rad, &dx, &dy);
00197
00198 double ex1, ey1, ex2, ey2;
00199 axis -> firstTick (ex1, ey1, ex2, ey2);
00200
00201
00202 int xmn, ymn, xmx, ymx;
00203 axis -> getViewport(xmn, xmx, ymn, ymx);
00204
00205
00206 _scale -> setViewport(xmn, xmx, ymn, ymx);
00207
00208 double tex2 = ex2;
00209 double tey2 = ey2;
00210
00211 int ftx1, ftx2, fty1, fty2;
00212 int ltx1, ltx2, lty1, lty2;
00213
00214
00215
00216
00217
00218
00219 char c[80];
00220 sprintf (c, _format, axis -> first()/_exp);
00221
00222 _scale -> text (c);
00223 _scale -> position (tex2, tey2);
00224 _scale -> boundingBox(ftx1, fty1, ftx2, fty2);
00225
00226
00227 int total = (int) floor ((axis -> max() - axis -> first())
00228 / axis -> step());
00229
00230
00231 sprintf (c, _format, axis -> max()/_exp);
00232
00233 _scale -> text (c);
00234 _scale -> position (tex2 + dx * total, tey2 + dy * total);
00235 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00236
00237
00238
00239 double mor = ((ltx2 - ltx1) > (ftx2 - ftx1)) ? axis -> max()
00240 : axis -> first();
00241
00242
00243 sprintf (c, _format, mor/_exp);
00244
00245 _scale -> text (c);
00246 _scale -> position (tex2, tey2);
00247 _scale -> boundingBox(ftx1, fty1, ftx2, fty2);
00248
00249
00250 tex2 += dx;
00251 tey2 += dy;
00252
00253
00254 sprintf (c, _format, mor/_exp);
00255
00256 _scale -> text (c);
00257 _scale -> position (tex2, tey2);
00258 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00259
00260
00261 int test_intercept = 1;
00262
00263
00264
00265 while (mtIntercept (ftx1, fty1, ftx2, fty2, ltx1, lty1, ltx2, lty2) != 0)
00266 {
00267 ++test_intercept;
00268
00269
00270 tex2 += dx;
00271 tey2 += dy;
00272
00273
00274 sprintf (c, _format, mor/_exp);
00275
00276 _scale -> text (c);
00277 _scale -> position (tex2, tey2);
00278 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00279 }
00280
00281
00282 double xmin = ex2;
00283 double xmax = ex2;
00284 double ymin = ey2;
00285 double ymax = ey2;
00286
00287 int x1, x2, y1, y2;
00288 double wx1, wy1, wx2, wy2;
00289
00290
00291 int ntick = 0;
00292
00293 for (double tick = axis -> first();
00294 tick <= axis -> max();
00295 tick += axis -> step())
00296 {
00297
00298 sprintf (c, _format, tick/_exp);
00299
00300
00301 _scale -> text (c);
00302 _scale -> position (ex2, ey2);
00303
00304 if ((ntick % test_intercept) == 0)
00305 {
00306
00307 _scale -> boundingBox (x1, y1, x2, y2);
00308
00309 wdCanvas2World (x1, y1, &wx1, &wy1);
00310 wdCanvas2World (x2, y2, &wx2, &wy2);
00311
00312
00313 xmin = MIN3 (xmin, wx1, wx2);
00314 xmax = MAX3 (xmax, wx1, wx2);
00315 ymin = MIN3 (ymin, wy1, wy2);
00316 ymax = MAX3 (ymax, wy1, wy2);
00317 }
00318
00319
00320 ex2 += dx;
00321 ey2 += dy;
00322
00323 ++ntick;
00324 }
00325
00326 wdWorld2Canvas (xmin, ymin, &bxmin, &bymin);
00327 wdWorld2Canvas (xmax, ymax, &bxmax, &bymax);
00328 }