Engauge Digitizer 2
Loading...
Searching...
No Matches
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
17using namespace std;
18
22
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
45double 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
146void 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
176double 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}
QList< Point > Points
Definition Points.h:13
Model for DlgSettingsCoords and CmdSettingsCoords.
Model for DlgSettingsGeneral and CmdSettingsGeneral.
Highest-level wrapper around other Formats classes.
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...
double polygonAreaForSimplyConnected(const QVector< QPointF > &points) const
Area in polygon using Shoelace formula, which only works if polygon is simply connected.
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...
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.
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.
void calculatePositionsGraph(const Points &points, const Transformation &transformation, QVector< QPointF > &positionsGraph) const
Convert screen positions to graph positions.
double functionArea(const QVector< QPointF > &positionsGraph) const
Use trapezoidal approximation to compute area under the function. Does not apply to relation.
Model for DlgSettingsMainWindow.
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition Point.h:26
QPointF posScreen() const
Accessor for screen position.
Definition Point.cpp:404
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition SplinePair.h:14
double y() const
Get method for y.
double x() const
Get method for x.
Cubic interpolation given independent and dependent value vectors.
Definition Spline.h:30
SplinePair interpolateCoeff(double t) const
Return interpolated y for specified x.
Definition Spline.cpp:233
Affine transformation between screen and graph coordinates, based on digitized axis points.
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.