Engauge Digitizer  2
 All Classes Functions Variables Typedefs Enumerations Friends Pages
FittingCurve.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 "FittingCurveCoefficients.h"
8 #include "FittingCurve.h"
9 #include "Logger.h"
10 #include <qmath.h>
11 #include <QPainterPath>
12 #include <QPen>
13 #include "Transformation.h"
14 
15 FittingCurve::FittingCurve (const FittingCurveCoefficients &fittingCoef,
16  double xMin,
17  double xMax,
18  bool isLogXTheta,
19  bool isLogYRadius,
20  const Transformation &transformation)
21 {
22  const int NUM_POINTS = 1000; // Use so many points that spline interpolation is not needed for smoothness
23  const double Z_LINE = 500; // More than the z value for lines since this line takes priority, and user can hide it
24 
25  setZValue (Z_LINE);
26  setPen (QPen (QColor (Qt::red)));
27 
28  QPainterPath path;
29 
30  if (transformation.transformIsDefined()) {
31 
32  for (int i = 0; i < NUM_POINTS; i++) {
33 
34  // Compute (x,y) point in graph coordinates
35  double s = double (i) / double (NUM_POINTS - 1);
36  double x = xMin + s * (xMax - xMin);
37  double y = yFromCoefficientsAndX (fittingCoef,
38  x);
39 
40  // The coefficients were computed assuming the x and y values were transformed if they were log scale base 10, so
41  // we must compensate here in the same way
42  if (isLogXTheta) {
43  x = qPow (10.0, x);
44  }
45  if (isLogYRadius) {
46  y = qPow (10.0, y);
47  }
48 
49  // Convert to screen coordinates
50  QPointF posGraph (x, y);
51  QPointF posScreen;
52  transformation.transformRawGraphToScreen (posGraph,
53  posScreen);
54 
55  // Add point to line
56  if (i == 0) {
57  path.moveTo (posScreen);
58  } else {
59  path.lineTo (posScreen);
60  }
61  }
62  }
63 
64  setPath (path);
65 }
66 
67 FittingCurve::~FittingCurve()
68 {
69 }
70 
71 double FittingCurve::yFromCoefficientsAndX (const FittingCurveCoefficients &fittingCoef,
72  double x) const
73 {
74  double sum = 0;
75 
76  for (int order = 0; order < fittingCoef.size(); order++) {
77  sum += fittingCoef [order] * qPow (x, order);
78  }
79 
80  return sum;
81 }
FittingCurve(const FittingCurveCoefficients &fittingCoef, double xMin, double xMax, bool isLogXTheta, bool isLogYRadius, const Transformation &transformation)
Single constructor.
Affine transformation between screen and graph coordinates, based on digitized axis points...
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
void transformRawGraphToScreen(const QPointF &pointRaw, QPointF &pointScreen) const
Transform from raw graph coordinates to linear cartesian graph coordinates, then to screen coordinate...