Engauge Digitizer  2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ExportAlignLinear.cpp
Go to the documentation of this file.
1 /******************************************************************************************************
2  * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5  ******************************************************************************************************/
6 
7 #include "EngaugeAssert.h"
8 #include "ExportAlignLinear.h"
9 #include <qmath.h>
10 
11 const double EPSILON = 0.000001;
12 
14  double xMax) :
15  m_firstSimplestNumber (0)
16 {
17  ENGAUGE_ASSERT (xMin <= xMax);
18 
19  const int MAX_S = 7; // This algorithm is probably constrained to the 7 digits of precision of real numbers
20 
21  // Start by identifying the first digit D for the larger magnitude (=unsigned) of xMin and xMax. Examples
22  // are D=0 for 0.1 to 0.99..., D=1 for 1 to 9.99..., D=2 for 10 to 99.999...
23  double absMin = qAbs (xMin);
24  double absMax = qAbs (xMax);
25  int D = qFloor (log10 (qMax (absMin, absMax)) + EPSILON);
26 
27  // Number of significant digits S will start at 1 and then get increased until
28  // rounded(xMin) + 10^R <= xMax
29  // where rounded(xMin) is xMin rounded off to the the Rth digit, where R=D-S
30  int S = 1;
31  double roundedMin = 0.0;
32  while (S < MAX_S) {
33  int R = D - S + 1;
34  roundedMin = roundToDigit (xMin, R);
35  double nominalStep = qPow (10.0, R);
36 
37  if (xMin < 0 && xMin < roundedMin) {
38  // For negative xMin we often or always have to jump over by nominalStep to keep
39  // xMin in the range
40  roundedMin -= nominalStep;
41  }
42 
43  // Need at least one step between roundedMin and xMax, otherwise ranges
44  if (roundedMin + 2 * nominalStep <= xMax) {
45  break;
46  }
47 
48  S = S + 1;
49  }
50 
51  m_firstSimplestNumber = roundedMin;
52 }
53 
55 {
56  return m_firstSimplestNumber;
57 }
58 
59 double ExportAlignLinear::log10 (double in) const
60 {
61  return qLn (in) / qLn (10.0);
62 }
63 
64 double ExportAlignLinear::roundToDigit (double value,
65  int digit) const
66 {
67  double scale = qPow (10.0, digit);
68  int valueRoundedWithWrongScale = qFloor (value / scale + EPSILON);
69  double valueRounded = valueRoundedWithWrongScale * scale;
70 
71  return valueRounded;
72 }
ExportAlignLinear(double xMin, double xMax)
Single constructor.
double firstSimplestNumber() const
Result.
const double EPSILON
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) &amp;&amp; !defined(QT_FORCE_ASSERTS) define ENGAUGE...
Definition: EngaugeAssert.h:20