Engauge Digitizer  2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GeometryStrategyAbstractBase.cpp
Go to the documentation of this file.
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 "EngaugeAssert.h"
8 #include "FormatCoordsUnits.h"
10 #include <qmath.h>
11 #include <QPointF>
12 #include "Spline.h"
13 #include "SplinePair.h"
14 #include "Transformation.h"
15 #include <vector>
16 
17 using namespace std;
18 
20 {
21 }
22 
24 {
25 }
26 
28  const Transformation &transformation,
29  QVector<QPointF> &positionsGraph) const
30 {
31  positionsGraph.clear();
32 
33  for (int i = 0; i < points.size(); i++) {
34  const Point &pointScreen = points [i];
35  QPointF posScreen = pointScreen.posScreen ();
36  QPointF posGraph;
37 
38  transformation.transformScreenToRawGraph (posScreen,
39  posGraph);
40 
41  positionsGraph.push_back (posGraph);
42  }
43 }
44 
45 double GeometryStrategyAbstractBase::functionArea (const QVector<QPointF> &positionsGraph) const
46 {
47  // Integrate using trapezoidal approximation to get the area under the function
48  double sum = 0, xLast = 0, yLast = 0;
49  for (int i = 1; i < positionsGraph.size (); i++) {
50  double x = positionsGraph [i].x();
51  double y = positionsGraph [i].y();
52  double area = 0.5 * (y + yLast) * (x - xLast);
53  sum += area;
54  xLast = x;
55  yLast = y;
56  }
57 
58  return sum;
59 }
60 
62  const QVector<QPointF> &positionsGraph,
63  QVector<QPointF> &positionsGraphWithSubintervals,
64  QVector<QString> &distanceGraphForward,
65  QVector<QString> &distancePercentForward,
66  QVector<QString> &distanceGraphBackward,
67  QVector<QString> &distancePercentBackward) const
68 {
69  if (positionsGraph.size () > 0) {
70 
71  int i;
72 
73  // Fit splines to the points
74  vector<double> t;
75  vector<SplinePair> xy;
76  for (int i = 0; i < positionsGraph.size (); i++) {
77  t.push_back (double (i));
78  xy.push_back (SplinePair (positionsGraph [i].x(),
79  positionsGraph [i].y()));
80  }
81 
82  Spline spline (t,
83  xy);
84 
85  // Loop over the original points, with one original point per original interval
86  QVector<double> distanceGraphDouble;
87  double xLast = 0, yLast = 0, distance = 0;
88  for (i = 0; i < positionsGraph.size(); i++) {
89 
90  // In the interval i-1 to i we insert points to create smaller subintervals
91  for (int subinterval = 0; subinterval < subintervalsPerInterval; subinterval++) {
92 
93  // Go from i-1 (exclusive) to i (inclusive)
94  double t = double (i - 1.0) + double (subinterval + 1) / double (subintervalsPerInterval);
95 
96  SplinePair splinePair = spline.interpolateCoeff (t);
97 
98  double x = splinePair.x ();
99  double y = splinePair.y ();
100 
101  // All points from intervals where i>0, and last point from interval i=0
102  if (i > 0 || subinterval == subintervalsPerInterval - 1) {
103 
104  // Insert one of several new points for each original point
105  positionsGraphWithSubintervals.push_back (QPointF (x, y));
106 
107  }
108 
109  if (i > 0) {
110 
111  // Add to cumulative distance
112  distance += qSqrt ((x - xLast) * (x - xLast) + (y - yLast) * (y - yLast));
113 
114  }
115 
116  xLast = x;
117  yLast = y;
118  }
119 
120  // Insert one distance entry for each original point
121  distanceGraphDouble.push_back (distance);
122  }
123 
124  // Compute distance columns
125  double dTotal = qMax (1.0, distanceGraphDouble [distanceGraphDouble.size() - 1]); // qMax prevents divide by zero
126  for (i = 0; i < distanceGraphDouble.size (); i++) {
127  double d = distanceGraphDouble [i];
128  distanceGraphForward.push_back (QString::number (d));
129  distancePercentForward.push_back (QString::number (100.0 * d / dTotal));
130  distanceGraphBackward.push_back (QString::number (dTotal - d));
131  distancePercentBackward.push_back (QString::number (100.0 * (dTotal - d) / dTotal));
132  }
133  }
134 }
135 
137  QVector<QString> & /* y */,
138  const Transformation & /* transformation */,
139  QVector<bool> &isPotentialExportAmbiguity) const
140 {
141  for (int i = 0; i < x.size(); i++) {
142  isPotentialExportAmbiguity.append (false);
143  }
144 }
145 
146 void GeometryStrategyAbstractBase::loadXY (const QVector<QPointF> &positionsGraph,
147  const DocumentModelCoords &modelCoords,
148  const DocumentModelGeneral &modelGeneral,
149  const MainWindowModel &modelMainWindow,
150  const Transformation &transformation,
151  QVector<QString> &x,
152  QVector<QString> &y) const
153 {
154  FormatCoordsUnits formatCoordsUnits;
155 
156  for (int i = 0; i < positionsGraph.size(); i++) {
157 
158  double xI = positionsGraph [i].x();
159  double yI = positionsGraph [i].y();
160 
161  QString xFormatted, yFormatted;
162  formatCoordsUnits.unformattedToFormatted (xI,
163  yI,
164  modelCoords,
165  modelGeneral,
166  modelMainWindow,
167  xFormatted,
168  yFormatted,
169  transformation);
170  x.push_back (xFormatted);
171  y.push_back (yFormatted);
172 
173  }
174 }
175 
176 double GeometryStrategyAbstractBase::polygonAreaForSimplyConnected (const QVector<QPointF> &points) const
177 {
178  // Shoelace formula
179  int N = points.size ();
180 
181  double sum = 0.0;
182  if (N > 0) {
183 
184 
185  for (int i = 0; i < N - 1; i++) {
186  sum += points [i].x() * points [i + 1].y() - points [i + 1].x() * points [i].y();
187  }
188 
189  sum += points [N - 1].x() * points [0].y() - points [0].x() * points [N - 1].y ();
190  }
191 
192  return qAbs (sum) / 2.0;
193 }
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
void calculatePositionsGraph(const Points &points, const Transformation &transformation, QVector< QPointF > &positionsGraph) const
Convert screen positions to graph positions.
SplinePair interpolateCoeff(double t) const
Return interpolated y for specified x.
Definition: Spline.cpp:233
Model for DlgSettingsGeneral and CmdSettingsGeneral.
Cubic interpolation given independent and dependent value vectors.
Definition: Spline.h:29
virtual void loadPotentialExportVector(QVector< QString > &x, QVector< QString > &y, const Transformation &transformation, QVector< bool > &isPotentialExportAmbiguity) const
Load isPotentialExportAmbiguity vector. Default in base class is to load false values since there are...
double functionArea(const QVector< QPointF > &positionsGraph) const
Use trapezoidal approximation to compute area under the function. Does not apply to relation...
double y() const
Get method for y.
Definition: SplinePair.cpp:88
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:25
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:404
void unformattedToFormatted(double xThetaUnformatted, double yRadiusUnformatted, const DocumentModelCoords &modelCoords, const DocumentModelGeneral &modelGeneral, const MainWindowModel &mainWindowModel, QString &xThetaFormatted, QString &yRadiusFormatted, const Transformation &transformation) const
Convert unformatted numeric value to formatted string. Transformation is used to determine best resol...
Affine transformation between screen and graph coordinates, based on digitized axis points...
Model for DlgSettingsMainWindow.
void loadXY(const QVector< QPointF > &positionsGraph, const DocumentModelCoords &modelCoords, const DocumentModelGeneral &modelGeneral, const MainWindowModel &modelMainWindow, const Transformation &transformation, QVector< QString > &x, QVector< QString > &y) const
Load x and y coordinate vectors.
Model for DlgSettingsCoords and CmdSettingsCoords.
Highest-level wrapper around other Formats classes.
QList< Point > Points
Definition: Points.h:13
double x() const
Get method for x.
Definition: SplinePair.cpp:83
GeometryStrategyAbstractBase()
Single constructor.
void insertSubintervalsAndLoadDistances(int subintervalsPerInterval, const QVector< QPointF > &positionsGraph, QVector< QPointF > &positionsGraphWithSubintervals, QVector< QString > &distanceGraphForward, QVector< QString > &distancePercentForward, QVector< QString > &distanceGraphBackward, QVector< QString > &distancePercentBackward) const
Insert the specified number of subintervals into each interval.
double polygonAreaForSimplyConnected(const QVector< QPointF > &points) const
Area in polygon using Shoelace formula, which only works if polygon is simply connected.
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition: SplinePair.h:13