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 = 100;
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,
47  double &stopX) const
48 {
49  startX = modelGrid.startX();
50  stopX = modelGrid.stopX();
51  stepX = modelGrid.stepX();
52  int countX = modelGrid.countX();
53 
54  bool needReduction = (countX > modelMainWindow.maximumGridLines());
55 
56  if (modelCoords.coordScaleXTheta() == COORD_SCALE_LINEAR) {
57 
58  // Linear
59  if (!needReduction) {
60  if (stepX <= 0) {
61  stepX = 0;
62  needReduction = true;
63  } else {
64  countX = 1.0 + (stopX - startX) / stepX;
65  needReduction = (countX > modelMainWindow.maximumGridLines());
66  }
67  }
68 
69  if (needReduction) {
70  stopX = startX + stepX * (modelMainWindow.maximumGridLines() - 1);
71  }
72 
73  } else {
74 
75  // Log
76  if (startX <= 0) {
77 
78  // Start value is invalid so override both start and step
79  QRectF boundingRectGraph = documentBounds (document,
80  transformation);
81 
82  // Override lower bound
83  startX = boundingRectGraph.left ();
84  }
85 
86  if (!needReduction) {
87  if (stepX <= 1) {
88  stepX = 1;
89  needReduction = true;
90  } else {
91  countX = 1.0 + (qLn (stopX) - qLn (startX)) / qLn (stepX);
92  needReduction = (countX > modelMainWindow.maximumGridLines());
93  }
94  }
95 
96  if (needReduction) {
97  stopX = qExp (qLn (startX) + qLn (stepX) * (modelMainWindow.maximumGridLines() - 1));
98  }
99  }
100 }
101 
103  const Transformation &transformation,
104  const DocumentModelCoords &modelCoords,
105  const MainWindowModel &modelMainWindow,
106  const DocumentModelGridDisplay &modelGrid,
107  double &startY,
108  double &stepY,
109  double &stopY) const
110 {
111  startY = modelGrid.startY();
112  stopY = modelGrid.stopY();
113  stepY = modelGrid.stepY();
114  int countY = modelGrid.countY();
115 
116  bool needReduction = (countY > modelMainWindow.maximumGridLines());
117 
118  if (modelCoords.coordScaleYRadius() == COORD_SCALE_LINEAR) {
119 
120  // Linear
121  if (!needReduction) {
122  if (stepY <= 0) {
123  stepY = 0;
124  needReduction = true;
125  } else {
126  countY = 1.0 + (stopY - startY) / stepY;
127  needReduction = (countY > modelMainWindow.maximumGridLines());
128  }
129  }
130 
131  if (needReduction) {
132  stopY = startY + stepY * (modelMainWindow.maximumGridLines() - 1);
133  }
134 
135  } else {
136 
137  // Log
138  if (startY <= 0) {
139 
140  // Start value is invalid so override both start and step
141  QRectF boundingRectGraph = documentBounds (document,
142  transformation);
143 
144  // Override lower bound
145  startY = boundingRectGraph.top ();
146  }
147 
148  if (!needReduction) {
149  if (stepY <= 1) {
150  stepY = 1;
151  needReduction = true;
152  } else {
153  countY = 1.0 + (qLn (stopY) - qLn (startY)) / qLn (stepY);
154  needReduction = (countY > modelMainWindow.maximumGridLines());
155  }
156  }
157 
158  if (needReduction) {
159  stopY = qExp (qLn (startY) + qLn (stepY) * (modelMainWindow.maximumGridLines() - 1));
160  }
161  }
162 }
void limitForXTheta(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid, double &startX, double &stepX, double &stopX) const
Limit step value for x/theta coordinate. This is a noop if the maximum grid line limit in MainWindowM...
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
Model for DlgSettingsGridDisplay and CmdSettingsGridDisplay.
unsigned int countX() const
Get method for x grid line count.
void iterateThroughCurvePointsAxes(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for the axes curve.
Definition: Document.cpp:443
unsigned int countY() const
Get method for y grid line count.
Affine transformation between screen and graph coordinates, based on digitized axis points...
GridLineLimiter()
Single constructor.
Model for DlgSettingsMainWindow.
void limitForYRadius(const Document &document, const Transformation &transformation, const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const DocumentModelGridDisplay &modelGrid, double &startY, double &stepY, double &stopY) const
Limit step value for y/range coordinate. This is a noop if the maximum grid line limit in MainWindowM...
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.
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:466
double stepY() const
Get method for y grid line increment.
double startX() const
Get method for x grid line lower bound (inclusive).
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.