fw4spl
bspline.hpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #ifndef __FWRENDERQT_BSPLINE_HPP__
8 #define __FWRENDERQT_BSPLINE_HPP__
9 
10 #include <cmath>
11 #include <iostream>
12 #include <list>
13 #include <vector>
14 
15 #define DEFAULT_PRECISION 40
16 
17 struct point
18 {
19  float x;
20  float y;
21 
22  point(float _x = 0.f, float _y = 0.f) :
23  x(_x),
24  y(_y)
25  {
26  }
27  point(const point& _which)
28  {
29  this->x = _which.x;
30  this->y = _which.y;
31  }
32  ~point()
33  {
34  }
35 
36  //------------------------------------------------------------------------------
37 
38  point& operator = (const point& _which)
39  {
40  this->x = _which.x;
41  this->y = _which.y;
42  return *this;
43  }
44 };
45 
47 {
48 public:
49  point_list()
50  {
51  }
52  point_list(const point_list& _which)
53  {
54  this->m_list = _which.m_list;
55  }
56  ~point_list()
57  {
58  for (unsigned int i = 0; i < m_list.size(); i++)
59  {
60  delete m_list[i];
61  }
62  }
63 
64  //------------------------------------------------------------------------------
65 
66  point& get_point(int which)
67  {
68  point* pt = m_list.at(which);
69  return *pt;
70  }
71 
72  //------------------------------------------------------------------------------
73 
74  void add_point(point* _which)
75  {
76  m_list.push_back(_which);
77  }
78 
79  std::vector<point*> m_list;
80 };
81 
82 class cat_curve
83 {
84 public:
85  cat_curve(const point_list& _which) :
86  m_plist(new point_list(_which)),
87  m_curve_point(nullptr),
88  m_nb_curve_point(0),
89  m_nb_point(m_plist->m_list.size()),
90  m_precision(DEFAULT_PRECISION),
91  m_draw_number(true)
92  {
93  }
94 
95  ~cat_curve()
96  {
97  if (m_curve_point != nullptr)
98  {
99  delete[] m_curve_point;
100  }
101  }
102 
103  //------------------------------------------------------------------------------
104 
105  void compute()
106  {
107  if (m_curve_point != nullptr)
108  {
109  delete[] m_curve_point;
110  }
111  m_curve_point = new point[m_precision+1];
112  m_nb_curve_point = m_precision+1;
113 
114  float t = 1.0f, p = (float)(m_nb_point-3)/(float)m_precision;
115 
116  int i;
117  float ti;
118  for(int k = 0; k < m_nb_curve_point; k++)
119  {
120  i = (int)floor(t);
121  ti = (float)i;
122  if (i < m_nb_point-2)
123  {
124  m_curve_point[k].x =
125  (3.0f*m_plist->m_list[i]->x-3.0f*m_plist->m_list[i+1]->x+
126  m_plist->m_list[i+2]->x-m_plist->m_list[i-1]->x)*pow(t-ti, 3)/2.0f+
127  ( 2.0f*m_plist->m_list[i-1]->x - 5.0f*m_plist->m_list[i]->x +
128  4.0f*m_plist->m_list[i+1]->x - m_plist->m_list[i+2]->x)*pow(t-ti, 2)/2.0f+
129  ( m_plist->m_list[i+1]->x - m_plist->m_list[i-1]->x ) *(t-ti)/2.0f + m_plist->m_list[i]->x;
130 
131  m_curve_point[k].y =
132  (3.0f*m_plist->m_list[i]->y-3.0f*m_plist->m_list[i+1]->y+
133  m_plist->m_list[i+2]->y-m_plist->m_list[i-1]->y)*pow(t-ti, 3)/2.0f+
134  ( 2.0f*m_plist->m_list[i-1]->y - 5.0f*m_plist->m_list[i]->y +
135  4.0f*m_plist->m_list[i+1]->y - m_plist->m_list[i+2]->y)*pow(t-ti, 2)/2.0f+
136  ( m_plist->m_list[i+1]->y - m_plist->m_list[i-1]->y ) *(t-ti)/2.0f + m_plist->m_list[i]->y;
137  }
138  else if(i < m_nb_point)
139  {
140  m_curve_point[k].x = m_plist->m_list[i]->x;
141  m_curve_point[k].y = m_plist->m_list[i]->y;
142  }
143 
144  t += p;
145  }
146  }
147 
148  point* m_curve_point;
149  int m_nb_curve_point;
150 
151  point_list* m_plist;
152  int m_nb_point;
153 
154  int m_precision;
155  bool m_draw_number;
156 };
157 
158 #endif //__FWRENDERQT_BSPLINE_HPP__
159