Closed msteinbeck closed 8 years ago
Documentation is moving ahead. Currently I'm missing:
Yes, improve documentation.
I cannot figure out what I need to do in order to input my 2D data into tinyspline and have it return the interpolated points including and between the points that I gave into tinyspline.
In the following I'm assuming you are using the C interface.
If you want to interpolate a set/list of points [x0, y0, x1, y1, x2, y2, ..., x_n, y_n] you need to use the function ts_bspline_interpolate. Let's say you have 10 points in 2D arranged as described above, then call:
float *points = .... // your points in 2D arranged as [x0, y0, x1, y1, x2, y2, ..., x_9, y_9]
tsBSpline spline; // create the spline storing the result
tsError err = ts_bspline_interpolate(
points, // your points
10, // the number of points
2, // the dimension of each point
&spline
);
if (err < 0) ... // error handling
Afterwards spline
represents the interpolated spline. Use ts_bspline_evaluate to evaluate spline
at any points t
with 0 <= t <= 1
. You will find another example in interpolation.c.
If you are using C++ or any of the bindings, call the constructor instead.
ts_bspline_evaluate says it saves to some type tsDeBoorNet.
It's a struct (https://github.com/retuxx/tinyspline/blob/master/library/tinyspline.h#L55), but which variables represent the "y-values" and which ones "x-values" for the spline?
Given the example above you can evaluate spline
at any t
with 0 <= t <= 1
by:
tsDeBoorNet net; // the net to store the result.
tsError err = tsError ts_bspline_evaluate(&spline, t, &net); // with 0 <= t <= 1
if (err < 0)... // error handling
net.result; // stores the resulting point arranged as [x0, y0]
Edit: Fixed [x0, x1]
to [x0, y0]
Why is the range [0,1] and not [0, len(input points)] or similar?
Why is the range [0,1] and not [0, len(input points)]?
Sorry, but I don't understand this question. Which range should be [0, len(input points)]
?
If I'm inputting data that has say 1000 [x,y] points then the length of the data is 1000 (or more if one uses max(x) to determine the length of the data).
It would be reasonable if I could then have the spline function return max(x) or similar amount of points so that I can iterate over integers that correspond to the x-values in the input data and not decimals in range [0,1].
How do I know what x-value in the input data some x' in [0,1] corresponds to?
Ok, I see your problem here. You misunderstand the usage of splines. First of all a spline is parameterized over a variable t
. Usually the range of t
is 0 <= t <= 1
but actually the range can be anything as long as min(t) < max(t)
. Evaluating a spline s
at any t
(with respect to t
's range) returns the point p
(in your case 2D) on s
at t
.
Wikipedia describes a B-Spline
as follows:
"A B-spline of order n is a piecewise polynomial function of degree <n in a variable x. It is defined over a domain t 0 ≤ x ≤ tm, m = n. The points where x = t j are known as knots or break-points." (As you can see, Wikipedia uses another range for t
but that doesn't matter here)
So, you want to interpolate a set/list of points where each x
value maps to exactly one y
value representing a function and afterwards you want to evaluate the spline s
at any x
, right?
In order to create such a function your points arranged as [x0, y0, x1, y1, x2, y2, ..., x_n, y_n]
needs to be strictly monotonically increasing, such that for each value x_{n}
and x_{n+1}
the following equation applies: x{n} < x_{n+1}
. For example:
[0, 1, 1, 1, 2, 1, 3, 1,...]
<<< you see each x
value is smaller than its successor.
If your points are not strictly monotonically increasing in x
the resulting spline is not a function but a relation instead (you know, each x
value may have many y
values).
So how do we get the mapped y
value of any x
value for a spline s
? The only (as far as I know) and fastest way is to perform the Bisection method (a binary search in continuous space). First, we begin to evaluation s
at 0.5
(by using ts_bspline_evaluate
) and check if net.result[0]
(the x
value at 0.5
) is smaller, greater or equals to given x
value. If net.result[0]
is greater than x
, evaluate s
at 0.25
(mid(0, 0.5)) and if net.result[0]
is smaller than x
, evaluate s
at 0.75
(mid(0.5, 1)). Stop this iteration if net.result[0]
is equals to x
. IMPORTANT: the type of points is float
. Comparing floats using == isn't a smart idea in general. Though (f0 + f1) / 2
is either f0
or f1
at some point (due to imprecision of floats) the usage of ts_fequals is recommended. Finally net.result[1]
is the mapping (y
) of the given x
.
Edit: Fixed min(t) > max(t)
to min(t) < max(t)
, x{n} > x_{n+1}
to x{n} < x_{n+1}
How do I know what x-value in the input data some x' in [0,1] corresponds to?
It's the same question as finding the y
value for any x
value. Use the bisection method until you find t
such that net.result[0]
is equal enough to the given x
value.
If I want all points then is there a way to iterate "over t"?
If I want all points then is there a way to iterate "over t"?
Returning all points of a continuous function is very hard to achieve because the function has an infinite number of points :). You are free to iterate over t
in discrete steps like:
for (float t = 0.f; t <= 1.f; t += 0.01) // use a discretization of 0.01, adjust to your needs
{/* evaluate spline at t */}
You will find an example iterating over t
in nurbs.c
Note: TinySpline uses the name u
instead of t
because when I started to learn things about splines I read: http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve.html.
@Mviljamaa I've just pushed a lot of commits, one of them fixing interpolation for points in 2D.
So, you want to interpolate a set/list of points where each x value maps to exactly one y value representing a function and afterwards you want to evaluate the spline s at any x, right?
In order to create such a function your points arranged as [x0, y0, x1, y1, x2, y2, ..., x_n, yn] needs to be strictly monotonically increasing, such that for each value x{n} and x{n+1} the following equation applies: x{n} < x{n+1}.
This is confusing. How am I going to reinterpret the order, if I need to pass the points in an ordered way?
What I'm trying to do is merely is something like be able to draw this kind of graphs, given some points (such as the red dots) to interpolate between: http://profmsaeed.org/wp-content/uploads/2011/03/CubicSpline_01.png
To do that I need a way to return all [x,y]s that such graph consists of. Or all that are required for drawing in sufficient precision.
See how this Spline library does it, very simple: http://kluge.in-chemnitz.de/opensource/spline/
One merely calls s(x) with x: printf("spline at %f is %f\n", x, s(x));
What I'm trying to do is merely is something like be able to draw this kind of graphs, given some points (such as the red dots) to interpolate between
To draw the graph you only need to evaluate the graph at every (discrete) t/u
like:
tsBSpline spline;
ts_bspline_interpolate(points /*the points to interpolate*/, num_points, 2 /* 2D */, &spline);
// error handling if you want/need to
// draw the graph
tsDeBoorNet net;
for (float u = 0.f; u <= 1.f; u += 0.01) /* increase/decrease u */
{
ts_bspline_evaluate(&spline, u, &net);
// error handling if you want/need to
// call some sort of draw method, net.result[0] is `x` and net.result[1] is `y`
// prevent memory leeks
ts_deboornet_free(&net);
}
Thats it!
To do that I need a way to return all [x,y]s that such graph consists of. Or all that are required for drawing in sufficient precision.
Increase u
in lower steps to get higher precision.
If your graphics library (I don't know what you are using) provides methods to draw cubic Bézier curves (usually they do) drawing interpolated splines is very easy. Actually an interpolated spline is a set of piecewise connected Bézier curves. The only thing you need to do is to pass the control point of each Bézier curve to the drawing function:
tsBSpline spline;
ts_bspline_interpolate(points /*the points to interpolate*/, num_points, 2 /* 2D */, &spline);
for (int i = 0; i < n-1 /* the total number of Bézier curves */, i++) // i is the i'th Bézier curve of the spline
{
draw_bezier_curve( // the name of the function your graphics library provides to draw Bézier curves
spline.ctrlp[i*4], // the first control point of the i'th Bézier curve
spline.ctrlp[i*4 + 1], // the second control point of the i'th Bézier curve
spline.ctrlp[i*4 + 2], // the third control point of the i'th Bézier curve
spline.ctrlp[i*4 + 3], // the forth control point of the i'th Bézier curve
);
}
Note: You don't need to check the number of control points returned by ts_bspline_interpolate
because (according to the documentation) the number of control points will always be (n-1)*4
.
See how this Spline library does it, very simple
Did you see the TODO: "sort input vector, implement an efficient algorithm to evaluate spline(X) where X is a vector, ..."?
Though this is very nice library, it always requires a sorted (strictly monotonically increasing) input in x
(TinySpline does not). As already mentioned, this is an important property in order to ensure that each x
value maps to exactly one y
value. Have a look at http://kluge.in-chemnitz.de/opensource/spline/spline.h line 292-295 and the evaluating function double spline::operator() (double x) const
beginning at line 375 which uses std::lower_bound (The documentation of this function says: "The elements in the range shall already be sorted according to this same criterion (operator< or comp), or at least partitioned with respect to val.")
The drawback of this library is, that it is 'only' able to interpolate function like cubic splines while TinySpline is able to interpolate any kind of cubic spline, for instance, splines like: http://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf page 11 (DD 11)
If you want to, I can add the bisection method to the interface of TinySpline in order to enhance the usability in case of x
to y
mapping.
ts_bspline_interpolate(points /the points to interpolate/, num_points, 2 /* 2D */, &spline);
Since points is a const float *, then how are the 2D points arranged in it? In pairs of two?
Let's say x_{i}
is the i'th x value and y_{i}
the i'th y value of the spline to interpolate, for instance, x_{0}, y_{0}
is the first point, x_{1}, y_{1}
is the second point and so on. The function ts_bspline_interpolate
expects the parameter points
to be structured as follows: [x_{0}, y_{0}, x{1}, y_{1}, ... x_{n-1}, y_{n-1}]
.
So, let's say you have some points (1, 2), (4, 7), (8, -5) and (16, -25) where x_{0} = 1, y_{0} = 2, x_{1} = 4, y_{1} = 7 ...
then points must be [1, 2, 4, 7, 8, -5, 16, -25]
.
Note: All arrays of TinySpline are structured this way with respect the the spline's dimension (actually the dimension of each points). If you, for instance, use points in 3D then points
looks like: [x_{0}, y_{0}, z_{0}, x_{1}, y_{1}, z_{1}, ..., x_{n-1}, y_{n-1}, z_{n-1}].
ts_bspline_interpolate and ts_bspline_evaluate seem to be only in the C version. The CPP version looks different. Do the CPP files work or why are you giving examples in the C style?
Do the CPP files work
Yes, they are fully working ( except of bugs I don't know about yet :D ).
or why are you giving examples in the C style?
I didn't had the time yet to provide examples for every language but in the future I will. Thanks to @mkv123 so far for providing short examples for Python which I will add to the project some day :).
ts_bspline_interpolate and ts_bspline_evaluate seem to be only in the C version.
The function ts_bspline_interpolate
is wrapped by this constructor. Instead of a float*
you have to use a std::vector. The second parameter n
is not required because a std::vector provides the method size returning the number of values contained in a std::vector. Due to the nature of constructors returning an object (in this case an object of type TsBSpline
, the wrapper class of the struct tsBSpline
) the output parameter bspline
is not required as well.
The function ts_bspline_evaluate
is wrapped by this method. Instead of using the out parameter deBoorNet
it returns an instance of TsDeBoorNet
, the wrapper class for the struct tsDeBoorNet
. The operator TsDeBoorNet operator()(const float u) const is just a convenience method for TsDeBoorNet evaluate(const float u) const
(similar to http://kluge.in-chemnitz.de/opensource/spline/).
Note: The error handling of the C interface has been wrapped to exceptions (std::runtime_error).
Where's the result (x,y) in the tinysplinecpp.h? And how is it structured?
TsDeBoorNet::result() returns the vector containing the result of an evaluation, for instance:
TsBSpline b(points, 2); // create a spline (2D) interpolating the given points
std::vector vec = b(0.5f).result(); // evaluate b at t=0.5f and store result in 'vec'
vec[0] // the x value at t=0.5f
vec[1] // the y value at t=0.5f
Lets just check.
Does this library produce the missing values if I give the TsBSpline constructor e.g. 1024 points (so since it's in 2D then the vector length is 2048) so that it contains y=0 for all other points but, say, three points. I'd expect the library then generate the missing "envelopes" from 0 to the first y≠0 value and then from this to the second y≠0 value and then from this to the third y≠0 value and finally from this back to y=0?
Does this library produce the missing values if I give the TsBSpline constructor e.g. 1024 points (so since it's in 2D then the vector length is 2048)
TinySpline provides a function (namely ts_bspline_interpolate or rather this constructor) to create a spline interpolating a given list of points. Interpolation means the resulting spline 'goes through' the given points in a smooth way. You can evaluate the resulting spline at any t
with 0 <= t <= 1
. By concept some of the t
values will result in exactly points you have used to interpolate the spline (otherwise the interpolated spline would not go through your points).
so that it contains y=0 for all other points but, say, three points. I'd expect the library then generate the missing "envelopes" from 0 to the first y≠0 value and then from this to the second y≠0 value and then from this to the third y≠0 value and finally from this back to y=0?
The library does not explicitly generate these points. You have to generate them by iterating over t
(from 0
to 1
in small, discrete steps). So yes, TinySpline should fulfill your requirements.
So do I need to give it some other points than zeroes and few non-zero values? Or merely pass points in small steps to have the library generate points in place of the zeroes?
E.g. could I give it linear interpolated "three point envelope" and it would change to follow e.g. spline interpolation?
So do I need to give it some other points than zeroes and few non-zero values? Or merely pass points in small steps to have the library generate points in place of the zeroes?
Sorry but I don't understand. Maybe you could add a simple example showing the points you want to interpolate.
Here's precisely what I currently have:
int s = 0;
int maks = 256;
for(int n=0; n<num_points; ++n) {
float r = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));
for(s; s<maks-1; s++) {
envelope.push_back(s);
envelope.push_back(0.0);
}
envelope.push_back(maks-1);
envelope.push_back(r);
s += 1;
maks = s+256;
}
for(s; s<maks; s++) {
envelope.push_back(s);
envelope.push_back(0.0);
}
So what it does is:
Specifies how many "control points" in num_points. Fills a vector so that every num_point is 256 x-points apart from each other, the "betweens" are filled with (0,0)s: -255 (0,0)s before the first control point -255 (0,0)s between the first and second control point and so on.
So since there are now three non-(0,0) points in the vector, then can your library generate points that connect (0,0)s to the non-(0,0)s so that the vector contains an envelope passing through those three points?
Essentially I'm trying to create this kind of envelope, where the control point locations are known, but the "envelopes" connecting them are "simulated": https://www.image-line.com/support/FLHelp/html/img_plug/Harmor_env.jpg
I'm sorry but I'm not completely sure what you are trying to do :D. Nonetheless, interpolating a single spline as shown at https://www.image-line.com/support/FLHelp/html/img_plug/Harmor_env.jpg is not possible. The (cubic) spline interpolation creates a spline that is C^2 continuous at every point (at every t
to be more precise). That is, the interpolated spline is 'curvy' at every point The spline shown at your figure is c^0 continuous (maybe even discontinuous) at some points, for instance the point annotated with 'Point (right-click for menu)'. That is, the spline is 'edged' at these points. Actually, you can express such a spline with a single B-Spline by inserting knots and, thus, decreasing the continuity of the spline at the desired points but I would suggest to interpolate a set of splines. So, let's say you want to create the spline shown at your figure. Then, you could interpolate the first three points, afterwards the next three points (where the last point of the first spline is the first point of the second spline) and so on. The last spline (the one moving on x = 0
to the first point of the first spline) is interpolated by only two points resulting in a (simple) line.
Note: You don't have to interpolate the suggested line, if your spline must not be a closed shape.
It seems like when passing the above described vector (it has three (x,y), y≠0 points and other points (x,0)) to tsBSpline, then net.result seems to return only points of the form (x,0). So it seems like it doesn't generate the points "between" the zero (x,0)s in the vector and (three) non-zero (x,y)s.
So I'm still a bit confused about what kind of point set should I pass to tsBSpline.
Also even if my domain was, say, x in [0,200]
, then do I need to scale this to the range [0,1]
(i.e. map [0,200]
to [0,1]
) where tsBSpline seems to operate?(*)
I would like to control "how many points I get out". E.g. a power of two number of points.
The above (*) seems like, no I don't have to scale the domain to [0,1]
, tinyspline does it.
However, can I control it so that if I e.g. give it the domain (of x) [0,127]
, then I could get back exactly 128 (x,y) points?
Can you use tinyspline in a "generative" way?
What I mean is, can one call tinyspline with just one or two or few time units (e.g. two samples per call) and a "hop size" and have it "generate" the curve as new samples are passed to it? Rather than pass it all the num_points for a longer time period (e.g. 1024 samples) at the same time?
You can use the resize function to increase the number of control points step by step. Afterwards you have to assign the added control points to the desired coordinates. Note: This function does not interpolate the added control points and may invalidate the knot vector (you have to use this fucntion to make the knot vector valid). If you want to generate an interpolated spline stepwise, you have to use the interpolation function with all control points of the last step plus the new control points and, thus, create a new spline for each step.
I want to find a set of Beziers that I can used to represent the smoothed outline of a polygon. I have say a dozen 2D points representing my polygon and want to get eleven Bezier segments to submit to a graphics drawing primitive.
Some tips on how to use tinyspline to achieve that would be great.
Which interface are you using C, C++, Python, ... ?
An example in C would be good.
I am actually working on Android and Windows. Ideally I want to replicate Windows GDI's DrawCurvedPath (which has a selectable tension) on Android. My polygon is a closed Convex Hull.
Hope that helps. On 22 Apr 2016 12:45, "Marcel" notifications@github.com wrote:
Which interface are you using C, C++, Python, ... ?
— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/retuxx/tinyspline/issues/6#issuecomment-213390470
Should have written drawclosedcurve
I want the knots to lie on the spline and need the pairs of Bezier control points between each knot.
Ok, maybe I can help you. I will write a short example later this day.
That would be very kind.
On Fri, Apr 22, 2016 at 3:17 PM, Marcel notifications@github.com wrote:
Ok, maybe I can help you. I will write a short example later this day.
— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/retuxx/tinyspline/issues/6#issuecomment-213445343
Hi @bill-chadwick, I had some time to think about your request and I have to say that I'm a bit confused. Actually, a sequence of lines connecting the points of your polygon already is the best fitting sequence of Bezier curves because every line is a Bezier curve (all control points of a Bezier curve are collinear and, thus, form a line). Why do you need to use a sequence of Bezier curves? Does the sequence need to have a specific degree (a sequence of cubic spline for example)? Do you have an example image of the result you need?
Maybe the cubic spline interpolation is what you are looking for. It creates a smooth line connecting each successive point of your polygon. On the other hand, connecting the points with a smooth spline may lead to bad approximations.
A smoothed curve around my polygon points is what I want. It will be used to indicate the approximate area of a small group of things on a map. Such a grouping looks much nicer as a smooth curve than a straight sided polygon, especially when several such groupings are shown at the same time.
So my closed polygon vertices are knots and I want pairs of bezier spline control points between each knot.
I Hope that explanation is clearer.
Thanks again.
Bill On 22 Apr 2016 22:02, "Marcel" notifications@github.com wrote:
Maybe the cubic spline interpolation is what you are looking for. It creates smooth line connecting each successive point of your polygon. On the other hand, connecting the points with a smooth line may lead to bad approximations.
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/retuxx/tinyspline/issues/6#issuecomment-213587846
After hours of reading math about splines and interpolation, I finally got what you are looking for. What you need is a periodic spline interpolatoin
. This kind of interpolation ensures that the first and second derivative of the first and last control points are equal. Currently, TinySpline supports variational spline interpolation
only (I'm not sure if this is the correct name but MathWorks uses it and it sounds OK to me). Unlike the periodic interpolation, the variational interpolation does not create a spline with this property. Actually, it creates a spline where the second derivate of the endpoints are zero. Thus, connecting the last control point with the first one does not fit your needs. However, I think I know how to implement this feature. If you give me some time (should be finished within some days) I will add it and give a short example.
Thanks very much Marcel. Handling closed paths will be a good addition to TS. On 23 Apr 2016 13:27, "Marcel" notifications@github.com wrote:
After hours of reading math about splines and interpolation, I finally got what you are looking for. What you need is a periodic spline interpolatoin. This kind of interpolation ensures that the first and second derivative of the first and last control points are equal. Currently, TinySpline supports variational spline interpolation only (I'm not sure if this is the correct name but MathWorks http://de.mathworks.com/help/curvefit/csape.html uses it and it sounds OK to me). Unlike the periodic interpolation, the variational interpolation does not create a spline with this property. Actually, it creates a spline where the second derivate of the endpoints are zero. Thus, connecting the last control point with the first one does not fit your needs. However, I think I know how to implement this feature. If you give me some time (should be finished within some days) I will add it and give a short example.
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/retuxx/tinyspline/issues/6#issuecomment-213732447
Hey @bill-chadwick. I'm sorry for the missing progress of the requested feature. I'm currently in a rush and have not much time to add features for TinySpline. Nonetheless, I'm looking forward to accomplish the task. I will create a new issue for your request since this is not the right place.
Marcel,
No worries.
I found a solution on codeproject.
http://www.codeproject.com/Articles/33776/Draw-Closed-Smooth-Curve-with-Bezier-Spline
Bill
On Thu, May 19, 2016 at 9:50 AM, Marcel notifications@github.com wrote:
Hey @bill-chadwick https://github.com/bill-chadwick. I'm sorry for the missing progress of the requested feature. I'm currently in a rush and have not much time to add features for TinySpline. Nonetheless, I'm looking forward to accomplish the task. I will create a new issue for your request since this is not the right place.
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/retuxx/tinyspline/issues/6#issuecomment-220264766
Hi Marcel
I'm looking at your very interesting library. I have a similar case as described by mviljamaa. I'm getting the points and everything. But what I don't understand is the result
vector. The description says, that it contains a pointer to the last point in points. I want to get the resulting spline at any t
with 0 <= t <= 1
, but what are the ranges?
For example, if I have a vector with 4 points, is t=0
at the very beginning and t=1
at the end of all 4 points? Or is it between two points? If so, how do I jump to the next segment? To iterate in a certain step size from p0
to p3
, do I have to use the result
or the points
vector?
Thanks a lot in advance, Renato
Hi Renato,
But what I don't understand is the result vector. The description says, that it contains a pointer to the last point in points.
It's very simple once you got the concept of De Boor's algorithm. Let's have a look at this figure. As you can see, you have to calculate the points P_{1,0}, P_{2,0}, ..., P_{2,1}, P_{3,1}, ..., P_{3, 2}, ...
to eventually get the point P_{4,3}
, which is the result of a spline evaluation at t
within the spline's domain---usually 0 <= t <= 1
. Have a look at this tutorial to read more about the algorithm.
Now, the struct tsDeBoorNet
stores all points (from P_{1,0}
to P_{4,3}
) in points
. However, usually you want to access the result of an evaluation rather than all points that were necessary to calculate the deboor net. Thus, the field result
points to the last point in points
which, in our scenario, is P_{4,3}
.
I want to get the resulting spline at any t with 0 <= t <= 1, but what are the ranges?
Actually, this depends on the knot vector of your spline. In case of clamped splines, knots[0]
is the very beginning of your spline and knots[n_knots-1]
is the end of your spline. Nonetheless, in case of opened splines, knots[0]
and knots[n_knots-1]
are outside the spline's domain. Have a look at this introduction to read more about clamped and opened splines.
If you have further questions, feel free to ask :).
Hi Marcel
Thanks a lot for the quick answer. I really appreciate it!
If I understand the theory right and find the correct words, this means that if I want all points bilding the generated curve from the 4 control points P_0
to P_3
, I have to call the method evalute multiple times with different t
. The resulting point is stored in the result
vector.
And yes, my demo program shows this kind of behavior!!!! =)
Thanks a lot!
This is how it looks like now
If I understand the theory right and find the correct words, this means that if I want all points bilding the generated curve from the 4 control points P_0 to P_3, I have to call the method evalute multiple times with different t. The resulting point is stored in the result vector.
You got it :). By the way, if you would draw all points in points
you would see some something like this. The green dots are the points from the first column of the deboor net, the blue dots are the points from the second column and the black dot is the resulting point of the evaluation.
Thanks a lot!
You are welcome.
Closing this issue as it became something like a discussion forum.
Currently the interface of TinySpline is not very well documented. I really need to fix this.