LibreCAD
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tinysplinecpp.cpp
Go to the documentation of this file.
1 #include "tinysplinecpp.h"
2 #include <stdexcept>
3 
4 /********************************************************
5 * *
6 * DeBoorNet *
7 * *
8 ********************************************************/
10 {
12 }
13 
15 {
16  const tsError err = ts_deboornet_copy(&other.deBoorNet, &deBoorNet);
17  if (err < 0)
18  throw std::runtime_error(ts_enum_str(err));
19 }
20 
22 {
23  ts_deboornet_free(&deBoorNet);
24 }
25 
27 {
28  if (&other != this) {
29  const tsError err = ts_deboornet_copy(&other.deBoorNet, &deBoorNet);
30  if (err < 0)
31  throw std::runtime_error(ts_enum_str(err));
32  }
33  return *this;
34 }
35 
37 {
38  return deBoorNet.u;
39 }
40 
41 size_t ts::DeBoorNet::k() const
42 {
43  return deBoorNet.k;
44 }
45 
46 size_t ts::DeBoorNet::s() const
47 {
48  return deBoorNet.s;
49 }
50 
51 size_t ts::DeBoorNet::h() const
52 {
53  return deBoorNet.h;
54 }
55 
56 size_t ts::DeBoorNet::dim() const
57 {
58  return deBoorNet.dim;
59 }
60 
61 size_t ts::DeBoorNet::nPoints() const
62 {
63  return deBoorNet.n_points;
64 }
65 
66 std::vector<ts::rational> ts::DeBoorNet::points() const
67 {
68  const ts::rational* begin = deBoorNet.points;
69  const ts::rational* end = begin + deBoorNet.n_points*deBoorNet.dim;
70  return std::vector<ts::rational>(begin, end);
71 }
72 
73 std::vector<ts::rational> ts::DeBoorNet::result() const
74 {
75  const ts::rational* begin = deBoorNet.result;
76  const ts::rational* end = begin + deBoorNet.dim;
77  return std::vector<ts::rational>(begin, end);
78 }
79 
81 {
82  return &deBoorNet;
83 }
84 
85 #ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
87 {
88  ts_deboornet_default(&deBoorNet);
89  swap(other);
90 }
91 
93 {
94  if (&other != this) {
95  ts_deboornet_free(&deBoorNet);
96  swap(other);
97  }
98  return *this;
99 }
100 
102 {
103  if (&other != this) {
104  std::swap(deBoorNet.u, other.deBoorNet.u);
105  std::swap(deBoorNet.k, other.deBoorNet.k);
106  std::swap(deBoorNet.s, other.deBoorNet.s);
107  std::swap(deBoorNet.h, other.deBoorNet.h);
108  std::swap(deBoorNet.dim, other.deBoorNet.dim);
109  std::swap(deBoorNet.n_points, other.deBoorNet.n_points);
110  std::swap(deBoorNet.points, other.deBoorNet.points);
111  std::swap(deBoorNet.result, other.deBoorNet.result);
112  }
113 }
114 #endif
115 
116 
117 /********************************************************
118 * *
119 * BSpline *
120 * *
121 ********************************************************/
123 {
124  ts_bspline_default(&bspline);
125 }
126 
128 {
129  const tsError err = ts_bspline_copy(&other.bspline, &bspline);
130  if (err < 0)
131  throw std::runtime_error(ts_enum_str(err));
132 }
133 
134 ts::BSpline::BSpline(const size_t deg, const size_t dim, const size_t nCtrlp,
135  const tsBSplineType type)
136 {
137  const tsError err = ts_bspline_new(deg, dim, nCtrlp, type, &bspline);
138  if (err < 0)
139  throw std::runtime_error(ts_enum_str(err));
140 }
141 
142 ts::BSpline::BSpline(const std::vector<ts::rational> points, const size_t dim)
143 {
144  if (dim == 0)
145  throw std::runtime_error(ts_enum_str(TS_DIM_ZERO));
146  if (points.size() % dim != 0)
147  throw std::runtime_error("#points % dim == 0 failed");
148  const tsError err = ts_bspline_interpolate(
149  points.data(), points.size()/dim, dim, &bspline);
150  if (err < 0)
151  throw std::runtime_error(ts_enum_str(err));
152 }
153 
155 {
156  ts_bspline_free(&bspline);
157 }
158 
160 {
161  if (&other != this) {
162  const tsError err = ts_bspline_copy(&other.bspline, &bspline);
163  if (err < 0)
164  throw std::runtime_error(ts_enum_str(err));
165  }
166  return *this;
167 }
168 
170 {
171  return evaluate(u);
172 }
173 
174 size_t ts::BSpline::deg() const
175 {
176  return bspline.deg;
177 }
178 
179 size_t ts::BSpline::order() const
180 {
181  return bspline.order;
182 }
183 
184 size_t ts::BSpline::dim() const
185 {
186  return bspline.dim;
187 }
188 
189 size_t ts::BSpline::nCtrlp() const
190 {
191  return bspline.n_ctrlp;
192 }
193 
194 size_t ts::BSpline::nKnots() const
195 {
196  return bspline.n_knots;
197 }
198 
199 std::vector<ts::rational> ts::BSpline::ctrlp() const
200 {
201  const ts::rational* begin = bspline.ctrlp;
202  const ts::rational* end = begin + bspline.n_ctrlp*bspline.dim;
203  return std::vector<ts::rational>(begin, end);
204 }
205 
206 std::vector<ts::rational> ts::BSpline::knots() const
207 {
208  const ts::rational* begin = bspline.knots;
209  const ts::rational* end = begin + bspline.n_knots;
210  return std::vector<ts::rational>(begin, end);
211 }
212 
214 {
215  return &bspline;
216 }
217 
219 {
220  DeBoorNet deBoorNet;
221  const tsError err = ts_bspline_evaluate(&bspline, u, deBoorNet.data());
222  if (err < 0)
223  throw std::runtime_error(ts_enum_str(err));
224  return deBoorNet;
225 }
226 
227 void ts::BSpline::setCtrlp(const std::vector<ts::rational> ctrlp)
228 {
229  if (ctrlp.size() != nCtrlp() * dim()) {
230  throw std::runtime_error("The number of values must be equals to the"
231  " spline's number of control points multiplied by the dimension"
232  " of each control point.");
233  }
234  const tsError err = ts_bspline_set_ctrlp(&bspline, ctrlp.data(), &bspline);
235  if (err < 0)
236  throw std::runtime_error(ts_enum_str(err));
237 }
238 
239 void ts::BSpline::setKnots(const std::vector<ts::rational> knots)
240 {
241  if (knots.size() != nKnots()) {
242  throw std::runtime_error("The number of values must be equals to the"
243  " spline's number of knots.");
244  }
245  const tsError err = ts_bspline_set_knots(&bspline, knots.data(), &bspline);
246  if (err < 0)
247  throw std::runtime_error(ts_enum_str(err));
248 }
249 
251  const ts::rational min, const ts::rational max) const
252 {
253  ts::BSpline bs;
254  const tsError err = ts_bspline_setup_knots(
255  &bspline, type, min, max, &bs.bspline);
256  if (err < 0)
257  throw std::runtime_error(ts_enum_str(err));
258  return bs;
259 }
260 
261 ts::BSpline ts::BSpline::insertKnot(const ts::rational u, const size_t n) const
262 {
263  ts::BSpline bs;
264  size_t k;
265  const tsError err = ts_bspline_insert_knot(&bspline, u, n, &bs.bspline, &k);
266  if (err < 0)
267  throw std::runtime_error(ts_enum_str(err));
268  return bs;
269 }
270 
271 ts::BSpline ts::BSpline::resize(const int n, const int back) const
272 {
273  ts::BSpline bs;
274  const tsError err = ts_bspline_resize(&bspline, n, back, &bs.bspline);
275  if (err < 0)
276  throw std::runtime_error(ts_enum_str(err));
277  return bs;
278 }
279 
281 {
282  ts::BSpline bs;
283  size_t k;
284  const tsError err = ts_bspline_split(&bspline, u, &bs.bspline, &k);
285  if (err < 0)
286  throw std::runtime_error(ts_enum_str(err));
287  return bs;
288 }
289 
291 {
292  ts::BSpline bs;
293  const tsError err = ts_bspline_buckle(&bspline, b, &bs.bspline);
294  if (err < 0)
295  throw std::runtime_error(ts_enum_str(err));
296  return bs;
297 }
298 
300 {
301  ts::BSpline bs;
302  const tsError err = ts_bspline_to_beziers(&bspline, &bs.bspline);
303  if (err < 0)
304  throw std::runtime_error(ts_enum_str(err));
305  return bs;
306 }
307 
309 {
310  ts::BSpline bs;
311  const tsError err = ts_bspline_derive(&bspline, &bs.bspline);
312  if (err < 0)
313  throw std::runtime_error(ts_enum_str(err));
314  return bs;
315 }
316 
317 #ifndef TINYSPLINE_DISABLE_CXX11_FEATURES
319 {
320  ts_bspline_default(&bspline);
321  swap(other);
322 }
323 
325 {
326  if (&other != this) {
327  ts_bspline_free(&bspline);
328  swap(other);
329  }
330  return *this;
331 }
332 
334 {
335  if (&other != this) {
336  std::swap(bspline.deg, other.bspline.deg);
337  std::swap(bspline.order, other.bspline.order);
338  std::swap(bspline.dim, other.bspline.dim);
339  std::swap(bspline.n_ctrlp, other.bspline.n_ctrlp);
340  std::swap(bspline.n_knots, other.bspline.n_knots);
341  std::swap(bspline.ctrlp, other.bspline.ctrlp);
342  std::swap(bspline.knots, other.bspline.knots);
343  }
344 }
345 #endif
346 
347 
348 /********************************************************
349 * *
350 * Utils *
351 * *
352 ********************************************************/
354 {
355  return ts_fequals(x, y) == 1;
356 }
357 
358 std::string ts::Utils::enum_str(const tsError err)
359 {
360  return std::string(ts_enum_str(err));
361 }
362 
363 tsError ts::Utils::str_enum(const std::string str)
364 {
365  return ts_str_enum(str.c_str());
366 }
static bool fequals(const rational x, const rational y)
size_t dim
Definition: tinyspline.h:76
tsError ts_bspline_interpolate(const tsRational *points, const size_t n, const size_t dim, tsBSpline *bspline)
tsError ts_bspline_set_knots(const tsBSpline *bspline, const tsRational *knots, tsBSpline *result)
void setKnots(const std::vector< rational > knots)
size_t dim() const
size_t s() const
BSpline toBeziers() const
size_t deg() const
static std::string enum_str(const tsError err)
tsError ts_bspline_derive(const tsBSpline *original, tsBSpline *derivative)
tsError ts_str_enum(const char *str)
size_t nKnots() const
DeBoorNet evaluate(const rational u) const
tsError ts_bspline_set_ctrlp(const tsBSpline *bspline, const tsRational *ctrlp, tsBSpline *result)
void swap(BSpline &other)
tsRational * ctrlp
Definition: tinyspline.h:95
tsError ts_bspline_new(const size_t deg, const size_t dim, const size_t n_ctrlp, const tsBSplineType type, tsBSpline *bspline)
BSpline & operator=(const BSpline &other)
size_t order() const
tsRational * result
Definition: tinyspline.h:79
DeBoorNet operator()(const rational u) const
BSpline insertKnot(const rational u, const size_t n) const
std::vector< rational > result() const
size_t dim
Definition: tinyspline.h:92
void ts_bspline_free(tsBSpline *bspline)
static tsError str_enum(const std::string str)
void setCtrlp(const std::vector< rational > ctrlp)
tsRational * points
Definition: tinyspline.h:78
size_t nPoints() const
tsError ts_bspline_setup_knots(const tsBSpline *original, const tsBSplineType type, const tsRational min, const tsRational max, tsBSpline *result)
size_t order
Definition: tinyspline.h:89
tsRational * knots
Definition: tinyspline.h:96
tsRational rational
Definition: tinysplinecpp.h:9
rational u() const
tsError ts_bspline_copy(const tsBSpline *original, tsBSpline *copy)
BSpline derive() const
tsDeBoorNet * data()
tsError ts_deboornet_copy(const tsDeBoorNet *original, tsDeBoorNet *copy)
size_t n_ctrlp
Definition: tinyspline.h:93
size_t nCtrlp() const
tsError ts_bspline_insert_knot(const tsBSpline *bspline, const tsRational u, const size_t n, tsBSpline *result, size_t *k)
size_t h() const
size_t k() const
std::vector< rational > ctrlp() const
BSpline setupKnots(const tsBSplineType type, const rational min, const rational max) const
tsError ts_bspline_buckle(const tsBSpline *original, const tsRational b, tsBSpline *buckled)
tsDeBoorNet deBoorNet
Definition: tinysplinecpp.h:41
size_t k
Definition: tinyspline.h:73
int ts_fequals(const tsRational x, const tsRational y)
BSpline buckle(const rational b) const
size_t h
Definition: tinyspline.h:75
BSpline split(const rational u) const
size_t dim() const
void swap(DeBoorNet &other)
size_t n_points
Definition: tinyspline.h:77
DeBoorNet & operator=(const DeBoorNet &other)
std::vector< rational > knots() const
tsBSpline * data()
char * ts_enum_str(const tsError err)
std::vector< rational > points() const
size_t n_knots
Definition: tinyspline.h:94
tsError ts_bspline_split(const tsBSpline *bspline, const tsRational u, tsBSpline *split, size_t *k)
BSpline resize(const int n, const int back) const
void ts_deboornet_default(tsDeBoorNet *deBoorNet)
size_t deg
Definition: tinyspline.h:88
tsError ts_bspline_resize(const tsBSpline *bspline, const int n, const int back, tsBSpline *resized)
void ts_bspline_default(tsBSpline *bspline)
tsBSpline bspline
Definition: tinysplinecpp.h:92
tsError ts_bspline_to_beziers(const tsBSpline *bspline, tsBSpline *beziers)
void ts_deboornet_free(tsDeBoorNet *deBoorNet)
tsRational u
Definition: tinyspline.h:72
tsError
Definition: tinyspline.h:41
tsBSplineType
Definition: tinyspline.h:61
size_t s
Definition: tinyspline.h:74
tsError ts_bspline_evaluate(const tsBSpline *bspline, const tsRational u, tsDeBoorNet *deBoorNet)