Engauge Digitizer  2
GridLineLimiter.cpp
1 /******************************************************************************************************
2  * (C) 2016 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 "CallbackBoundingRects.h"
8 #include "Document.h"
9 #include "DocumentModelCoords.h"
10 #include "DocumentModelGridDisplay.h"
11 #include "DocumentModelGridRemoval.h"
12 #include "GridLineLimiter.h"
13 #include "MainWindowModel.h"
14 #include <qmath.h>
15 #include "Transformation.h"
16 
17 const int DEFAULT_MAXIMUM_GRID_LINES = 25;
18 
20 {
21 }
22 
23 QRectF GridLineLimiter::documentBounds (const Document &document,
24  const Transformation &transformation) const
25 {
26  // Get graph coordinate bounds
27  CallbackBoundingRects ftor (transformation);
28 
29  Functor2wRet<const QString &, const Point &, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
31  document.iterateThroughCurvePointsAxes (ftorWithCallback);
32  document.iterateThroughCurvesPointsGraphs (ftorWithCallback);
33 
34  bool isEmpty;
35  QRectF boundingRectGraph = ftor.boundingRectGraph(isEmpty);
36 
37  return boundingRectGraph;
38 }
39 
41  const Transformation &transformation,
42  const DocumentModelCoords &modelCoords,
43  const MainWindowModel &modelMainWindow,
44  const DocumentModelGridDisplay &modelGrid,
45  double &startX,
46  double &stepX) const
47 {
48  startX = modelGrid.startX();
49  double stopX = modelGrid.stopX();
50  stepX = modelGrid.stepX();
51 
52  if (modelCoords.coordScaleXTheta() == COORD_SCALE_LINEAR) {
53 
54  // Linear
55  bool needNewStep = (stepX <= 0); // Prevent divide-by-zero in next computation
56  if (!needNewStep) {
57  double count = 1.0 + (stopX - startX) / stepX;
58  needNewStep = ((int) count > modelMainWindow.maximumGridLines());
59  }
60 
61  if (needNewStep) {
62 
63  // Adjust step so maximum grid lines limit is met
64  stepX = (stopX - startX) / (modelMainWindow.maximumGridLines() - 1);
65 
66  }
67 
68  } else {
69 
70  // Log
71  if (startX <= 0) {
72 
73  // Start value is invalid so override both start and step
74  QRectF boundingRectGraph = documentBounds (document,
75  transformation);
76 
77  // Override lower bound
78  startX = boundingRectGraph.left ();
79  }
80 
81  bool needNewStep = (stepX <= 1); // Prevent divide-by-zero in next computation
82  if (!needNewStep) {
83  double count = 1.0 + (qLn (stopX) - qLn (startX)) / qLn (stepX);
84  needNewStep = ((int) count > modelMainWindow.maximumGridLines());
85  }
86 
87  if (needNewStep) {
88 
89  // Adjust step so maximum grid lines limit is met
90  stepX = qExp ((qLn (stopX) - qLn (startX)) / (modelMainWindow.maximumGridLines() - 1));
91 
92  }
93  }
94 }
95 
97  const Transformation &transformation,
98  const DocumentModelCoords &modelCoords,
99  const MainWindowModel &modelMainWindow,
100  const DocumentModelGridDisplay &modelGrid,
101  double &startY,
102  double &stepY) const
103 {
104  startY = modelGrid.startY();
105  double stopY = modelGrid.stopY();
106  stepY = modelGrid.stepY();
107 
108  if (modelCoords.coordScaleYRadius() == COORD_SCALE_LINEAR) {
109 
110  // Linear
111  bool needNewStep = (stepY <= 0); // Prevent divide-by-zero in next computation
112  if (!needNewStep) {
113  double count = 1.0 + (stopY - startY) / stepY;
114  needNewStep = ((int) count > modelMainWindow.maximumGridLines());
115  }
116 
117  if (needNewStep) {
118 
119  // Adjust step so maximum grid lines limit is met
120  stepY = (stopY - startY) / (modelMainWindow.maximumGridLines() - 1);
121 
122  }
123 
124  } else {
125 
126  // Log
127  if (startY <= 0) {
128 
129  // Start value is invalid so override both start and step
130  QRectF boundingRectGraph = documentBounds (document,
131  transformation);
132 
133  // Override lower bound
134  startY = boundingRectGraph.top ();
135  }
136 
137  bool needNewStep = (stepY <= 1); // Prevent divide-by-zero in next computation
138  if (!needNewStep) {
139  double count = 1.0 + (qLn (stopY) - qLn (startY)) / qLn (stepY);
140  needNewStep = ((int) count > modelMainWindow.maximumGridLines());
141  }
142 
143  if (needNewStep) {
144 
145  // Adjust step so maximum grid lines limit is met
146  stepY = qExp ((qLn (stopY) - qLn (startY)) / (modelMainWindow.maximumGridLines() - 1));
147 
148  }
149  }
150 }
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
Model for DlgSettingsGridDisplay and CmdSettingsGridDisplay.
void iterateThroughCurvePointsAxes(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for the axes curve.
Definition: Document.cpp:416
Affine transformation between screen and graph coordinates, based on digitized axis points...
GridLineLimiter()
Single constructor.
Model for DlgSettingsMainWindow.
int maximumGridLines() const
Maximum number of grid lines.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
double stopY() const
Get method for y grid line upper bound (inclusive).
double stopX() const
Get method for x grid line upper bound (inclusive).
Model for DlgSettingsCoords and CmdSettingsCoords.
void limitForYRadius(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid, double &startY, double &stepY) const
Limit step value for y/range coordinate. This is a noop if the maximum grid line limit in MainWindowM...
Storage of one imported image and the data attached to that image.
Definition: Document.h:41
double startY() const
Get method for y grid line lower bound (inclusive).
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
QRectF boundingRectGraph(bool &isEmpty) const
Graph coordinate bounding rectangle.
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
Definition: Document.cpp:439
double stepY() const
Get method for y grid line increment.
double startX() const
Get method for x grid line lower bound (inclusive).
void limitForXTheta(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid, double &startX, double &stepX) const
Limit step value for x/theta coordinate. This is a noop if the maximum grid line limit in MainWindowM...
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
double stepX() const
Get method for x grid line increment.