TinySpline
Spline Library for a Multitude of Programming Languages
v0.3.0

#include <tinyspline.h>
Public Attributes  
struct tsDeBoorNetImpl *  pImpl 
Represents the output of De Boor's algorithm. De Boor's algorithm is used to evaluate a spline at given knot value 'u' by iteratively computing a net of intermediate values until the result is available:
https://en.wikipedia.org/wiki/De_Boor%27s_algorithm https://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/deBoor.html
All points of a net are stored in 'points'. The resulting point is the last point in 'points' and, for the sake of convenience, may be accessed with 'result':
tsDeBoorNet net = ... // evaluate an arbitrary spline and store // the resulting net of points in 'net' ts_deboornet_result(...) // use 'result' to access the resulting point
Two dimensional points are stored as follows:
[x_0, y_0, x_1, y_1, ..., x_n1, y_n1]
Tree dimensional points are stored as follows:
[x_0, y_0, z_0, x_1, y_1, z_1, ..., x_n1, y_n1, z_n1]
... and so on. The output also supports homogeneous coordinates described above.
There is a special case in which the evaluation of a knot value 'u' returns two results instead of one. It occurs when the multiplicity of 'u' ( s(u) ) is equals to a spline's order, indicating that the spline is discontinuous at 'u'. This is common practice for BSplines (and NURBS) consisting of connected Bezier curves where the endpoint of curve 'c_i' is equals to the start point of curve 'c_i+1'. The end point of 'c_i' and the start point of 'c_i+1' may still be completely different though, yielding to a spline having a (real and visible) gap at 'u'. Consequently, De Boor's algorithm must return two results if 's(u) == order' in order to give access to the desired points. In such case, 'points' stores only the two resulting points (there is no net to calculate) and 'result' points to the first point in 'points'. Since having (real) gaps in splines is unusual, both points in 'points' are generally equals, making it easy to handle this special case by accessing 'result' as already shown above for regular cases:
tsDeBoorNet net = ... // evaluate a spline which is discontinuous at // the given knot value, yielding to a net with // two results ts_deboornet_result(...) // use 'result' to access the resulting point
However, you can access both points if necessary:
tsDeBoorNet net = ... // evaluate a spline which is discontinuous at // the given knot value, yielding to a net with // two results ts_deboornet_result(...)[0] ... // stores the first component of // the first point ts_deboornet_result(...)[dim(spline)] // stores the first component of // the second point
As if this wasn't complicated enough, there is an exception for this special case, yielding to exactly one result (just like the regular case) even if 's(u) == order'. It occurs when 'u' is the lower or upper bound of a spline's domain. For instance, if 'b' is a spline with domain [0, 1] and is evaluated at 'u = 0' or 'u = 1' then 'result' is always a single point regardless of the multiplicity of 'u'. Hence, handling this exception is straightforward:
tsDeBoorNet net = ... // evaluate a spline at the lower or upper // bound of its domain, for instance, 0 or 1 ts_deboornet_result(...) // use 'result' to access the resulting point
In summary, we have three different types of evaluation. 1) The regular case returning all points of the net we used to calculate the resulting point. 2) The special case returning exactly two points which is required for splines with (real) gaps. 3) The exception of 2) returning exactly one point even if 's(u) == order'. All in all this looks quite complex (and actually it is) but for most applications you do not have to deal with it. Just use 'result' to access the outcome of De Boor's algorithm.
struct tsDeBoorNetImpl* tsDeBoorNet::pImpl 
The actual implementation.