FotoSHOCK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
HermiteCurve.h
1 /*
2  * Copyright 2011, 2012 Lukas Jirkovsky
3  *
4  * This file is part of FotoSHOCK.
5  *
6  * FotoSHOCK is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, version 3 of the License.
9  *
10  * FotoSHOCK is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FotoSHOCK. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef HERMITECURVE_H
20 #define HERMITECURVE_H
21 
22 #include <QVector>
23 #include <QPoint>
24 
25 #include <stdint.h>
26 
27 class QHermiteControlPoint : public QPoint {
28  public:
30  m_f1 = 0;
31  m_f2 = 0;
32  m_f3 = 0;
33  m_f4 = 0;
34  }
35  QHermiteControlPoint(const QPoint& point) : QPoint(point) {
36  m_f1 = 0;
37  m_f2 = 0;
38  m_f3 = 0;
39  m_f4 = 0;
40  }
41  inline const float f1() const { return m_f1; }
42  inline const float f2() const { return m_f2; }
43  inline const float f3() const { return m_f3; }
44  inline const float f4() const { return m_f4; }
45 
46  protected:
47  friend class HermiteCurve;
48 
49  // values of M.X for the curve beginning in this point
50  float m_f1;
51  float m_f2;
52  float m_f3;
53  float m_f4;
54 };
55 
56 class HermiteCurve {
57  public:
58  HermiteCurve();
59  HermiteCurve(const HermiteCurve& other);
60  HermiteCurve(int xDimension);
61  ~HermiteCurve();
62 
63  HermiteCurve& operator=(const HermiteCurve& other);
64 
66  void setFloatMax(double max);
67  void setIntMax(unsigned long max);
68 
69  void update();
70 
71  std::size_t size() const;
72  void insert(int pos, const QHermiteControlPoint& point);
73  QHermiteControlPoint& operator[](std::size_t n);
74  const QHermiteControlPoint& operator[](std::size_t n) const;
75  void removeAt(std::size_t n);
76 
78  const std::size_t findX0(int x) const;
79 
80  const uint8_t getY(uint8_t x) const;
81  template <typename T>
82  const T getY(T x) const;
83  const float getY(float x) const;
84  const double getY(double x) const;
85  private:
86  // directly addressed table used to obtain the index of the control point in the m_ctrlPoints
87  int* m_ctrlPointLUT;
88  std::size_t m_ctrlPointLutSize;
89 
90  QVector<QHermiteControlPoint> m_ctrlPoints;
91  std::size_t m_ctrlPointsSize;
92 
93  // the factor used to normalize values to [0,1]
94  int m_xDimension;
95  float fscaleFactor;
96  double dscaleFactor;
97  float fnormalizeFactor;
98  double dnormalizeFactor;
99  unsigned long m_max;
100 
101  // returns the value for (M_h * X)
102  // ie. the the value for hermite functions with given parameters
103  inline void hermite(float y0, float y1, float dy0, float dy1, QHermiteControlPoint& point);
104 };
105 
106 template <typename T>
107 const T HermiteCurve::getY(T x) const {
108  if (m_ctrlPointsSize == 2) {
109  double slope = (double)(m_ctrlPoints[1].y() - m_ctrlPoints[0].y()) / (double)(m_ctrlPoints[1].x() - m_ctrlPoints[0].x());
110  return ((x * dscaleFactor - m_ctrlPoints[0].x()) * slope + m_ctrlPoints[0].y()) * dnormalizeFactor;
111  }
112  else {
113  double scaledX = dscaleFactor * x;
114  std::size_t x0pos = findX0(scaledX);
115  QHermiteControlPoint x0 = m_ctrlPoints[x0pos];
116  QHermiteControlPoint x1 = m_ctrlPoints[x0pos+1];
117 
118  double u = (double)(scaledX - x0.x()) / (double)(x1.x() - x0.x());
119  double u2 = u * u;
120  double u3 = u2 * u;
121 
122  return (u3 * x0.f1() + u2 * x0.f2() + u * x0.f3() + x0.f4()) * dnormalizeFactor;
123  }
124 }
125 
126 #endif // HERMITECURVE_H