📄 qwt_autoscl.cpp
字号:
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** * Qwt Widget Library * Copyright (C) 1997 Josef Wilgen * Copyright (C) 2002 Uwe Rathmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the Qwt License, Version 1.0 *****************************************************************************/#include "qwt_math.h"#include "qwt_autoscl.h"static const double MinEps=1.0e-10;//! CtorQwtAutoScale::QwtAutoScale (){ d_autoScale = TRUE; d_scaleOpt = None; d_minValue = 0.0; d_maxValue = 0.0; d_scaleMin = 0.0; d_scaleMax = 0.0; d_loMargin = 0.0; d_hiMargin = 0.0; d_step = 0.0; d_maxMajor = 8; d_maxMinor = 5; d_reset = 1; d_autoRebuild = TRUE;}//! DtorQwtAutoScale::~QwtAutoScale (){}/*! \return \c TRUE if auto-scaling is active \sa QwtAutoScale::setAutoScale()*/bool QwtAutoScale::autoScale() const { return d_autoScale; }/*! \return the margin at the lower end of the scale \sa QwtAutoScale::setMargins()*/double QwtAutoScale::loMargin() const { return d_loMargin; }/*! \return the margin at the upper end of the scale \sa QwtAutoScale::setMargins()*/double QwtAutoScale::hiMargin() const { return d_hiMargin; }/*! \return the maximum number of major tickmarks \sa QwtAutoScale::setMaxMajor()*/int QwtAutoScale::maxMajor() const { return d_maxMajor; }/*! \return the maximum number of minor scale ticks \sa QwtAutoScale::setMaxMinor()*/int QwtAutoScale::maxMinor() const { return d_maxMinor; }/*! \brief Adjust the scale to include a given array of input values. This member function extends the boundaries of the scale and re-calculates the step size if necessary in order to include all values in the array. If the reset parameter has nonzero value, the previous state will be cleared. \param x Array of input values \param num Array size \param reset If != 0 reset the scale's contents*/void QwtAutoScale::adjust(double *x, int num, int reset){ if (d_reset || reset) d_minValue = d_maxValue = x[0]; for (int i = 0; i < num; i++) { if (x[i] > d_maxValue) d_maxValue = x[i]; if (x[i] < d_minValue) d_minValue = x[i]; } d_reset = 0; if (d_autoRebuild) build();}/*! \brief Adjust the scale to include a given array of input values. This member function extends the boundaries of the scale and re-calculates the step size if necessary in order to include all values in the array. If the reset parameter has nonzero value, the previous state will be cleared. \param x QwtArray<double> of input values \param reset If != 0 reset the scale's contents*/void QwtAutoScale::adjust(const QwtArray<double> &x, int reset){ adjust(x.data(), x.size(), reset);}/*! \brief Adjust the scale to include a specified interval This member function extends the boundaries of the scale and re-calculates the step size if necessary in order to include a specified interval. If the reset parameter has nonzero value, the previous state will be cleared. \param vmin lower border of the specified interval \param vmax upper border of the specified interval \param reset if nonzero, reset the scale. Defaults to 0.*/void QwtAutoScale::adjust(double vmin, double vmax, int reset){ double mxv = qwtMax(vmin,vmax); double mnv = qwtMin(vmin,vmax); if (d_reset || reset) { d_minValue = mnv; d_maxValue = mxv; } else { if (d_minValue > mnv) d_minValue = mnv; if (d_maxValue < mxv) d_maxValue = mxv; } d_reset = 0; if (d_autoRebuild) build();}/*! \brief Re-build the scale*/void QwtAutoScale::build() { if (d_reset) return; if (d_autoScale) { if (d_scaleOpt & Logarithmic) buildLogScale(); else buildLinScale(); } else { double start, stop, step; if (d_scaleOpt & Inverted) { start = d_scaleMax; stop = d_scaleMin; step = -d_step; } else { start = d_scaleMin; stop = d_scaleMax; step = d_step; } d_scldiv.rebuild(start, stop, d_maxMajor, d_maxMinor, bool(d_scaleOpt & Logarithmic), step, FALSE); }}/*! \brief Build a linear scale*/void QwtAutoScale::buildLinScale (){ double delta; const double ticks = double (d_maxMajor); // // If in Autoscale Mode, adjust minval and maxval according to // the active scale options, and add the margins // if (!d_autoScale) return; double minval = d_minValue; // scale boundaries are based on the double maxval = d_maxValue; // data. // // add / subtract margins // if (d_loMargin > 0.0) minval -= d_loMargin; if (d_hiMargin > 0.0) maxval += d_hiMargin; // // Correct minval / maxval according to the scale options // if (d_scaleOpt & Symmetric) { delta = qwtMax(qwtAbs(d_ref - maxval), qwtAbs(d_ref - minval)); maxval = d_ref + delta; minval = d_ref - delta; } else if (d_scaleOpt & IncludeRef) { if (maxval < d_ref) maxval = d_ref; else if (minval > d_ref) minval = d_ref; } // // first approximation of d_scaleMin and d_scaleMax // setRange(minval, maxval); delta = d_scaleMax - d_scaleMin; // dec := maximal power of ten which fits into the interval // [d_scaleMin,d_scaleMax] const double dec = pow (10.0, floor (log10 (delta))); // // The following magic line calculates the step size such that // - The number of subintervals will not exceed the maximum // as specified by the user // - The step size fits {1,2,5}*10^n with a natural number n // double step = qwtCeil125(delta * 0.999999 / dec / ticks) * dec; // // determine he final values of scaleMin and scaleMax // if (! (d_scaleOpt & Floating) ) { // adjust of d_scaleMin and d_scaleMax such that both are integer // multiples of the step size. d_scaleMin = step * floor ((d_scaleMin + MinEps * step) / step); d_scaleMax = step * ceil ((d_scaleMax - MinEps * step) / step); } if (d_scaleOpt & Inverted) { step = -step; d_scldiv.rebuild(d_scaleMax, d_scaleMin, d_maxMajor, d_maxMinor, FALSE, step, FALSE); } else { d_scldiv.rebuild(d_scaleMin, d_scaleMax, d_maxMajor, d_maxMinor, FALSE, step, TRUE); }}/*! \brief build a logarithmic scale*/void QwtAutoScale::buildLogScale (){ if (!d_autoScale) return; double minval = d_minValue; // the calculation of scale divisions double maxval = d_maxValue; // is based on the input data. if (d_loMargin > 0.0) minval /= pow(10.0, d_loMargin); if (d_hiMargin > 0.0) maxval *= pow(10.0, d_hiMargin); if (d_scaleOpt & Symmetric) { const double delta = qwtMax(maxval / d_lref, d_lref / minval); maxval = d_lref * delta; minval = d_lref / delta; } else if (d_scaleOpt & IncludeRef) { if (maxval < d_lref) maxval = d_lref; else if (minval > d_lref) minval = d_lref; } const double ticks = (d_maxMajor > 0) ? double(d_maxMajor) : 1; setRange(minval, maxval); // decades included in the interval const double decades = qwtAbs(log10 (d_scaleMax / d_scaleMin)); // calculate step size in decades double step; if ((decades > 1.0) && (decades > ticks)) { double ipart; // One interval contains more than one decade. // The number of decades in an interval is adjusted // to be a multiple of 2,3,5, or 10. double fpart = modf (log10 (ceil (decades * 0.999999 / ticks)), &ipart); if (fpart < MinEps) fpart = 1.0; else if ((fpart - LOG10_2) < MinEps) fpart = 2.0; else if ((fpart - LOG10_3) < MinEps) fpart = 3.0; else if ((fpart - LOG10_5) < MinEps) fpart = 5.0; else fpart = 10.0; step = pow (10.0, ipart) * fpart; } else // The minimal step size is one decade. { step = 1.0; } if (!(d_scaleOpt & Floating)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -