TinySpline
0.7.0
Spline Library for a Multitude of Programming Languages

#include <stddef.h>
Go to the source code of this file.
Classes  
struct  tsStatus 
struct  tsFrame 
struct  tsBSpline 
struct  tsDeBoorNet 
Macros  
Deprecation  
The macro  
Library Export/Import  
If TinySpline is built for Windows, the macros https://docs.microsoft.com/enus/cpp/cpp/dllexportdllimport If TinySpline is built to the ELF (most Unix like environments) or Mach (OS X) object format, If none of the above applies, Depending on whether TinySpline is compiled as shared library or linked against as shared library, If you consume TinySpline as shared library built for Windows, all you need is to define  
Predefined Constants  
The following constants have been adjusted to maintain internal consistency and should only be changed with great caution! The values chosen should be suitable for most environments and can be used with float (single) and double precision (see tsReal). If changes are necessary, please read the documentation of the constants in advance.  
#define  TS_PI 3.14159265358979323846 
#define  TS_MAX_NUM_KNOTS 10000 
#define  TS_DOMAIN_DEFAULT_MIN 0.0f 
#define  TS_DOMAIN_DEFAULT_MAX 1.0f 
#define  TS_KNOT_EPSILON 1e4f 
#define  TS_POINT_EPSILON 1e5f 
#define  TS_LENGTH_ZERO 1e4f 
Typedefs  
API Configuration  
In the following section, different aspects of TinySpline's API can be configured (compiletime). It is recommended to configure the API by supplying the corresponding preprocessor definition(s). That said, there is nothing wrong with editing the source code directly.  
typedef double  tsReal 
Enumerations  
Utility Structs and Enums  
enum  tsBSplineType { TS_OPENED = 0 , TS_CLAMPED = 1 , TS_BEZIERS = 2 } 
Functions  
BSpline Data  
The internal state of tsBSpline is protected using the PIMPL design pattern (see https://en.cppreference.com/w/cpp/language/pimpl for more details). The data of an instance can be accessed with the functions listed in this section.  
size_t TINYSPLINE_API  ts_bspline_degree (const tsBSpline *spline) 
size_t TINYSPLINE_API  ts_bspline_order (const tsBSpline *spline) 
size_t TINYSPLINE_API  ts_bspline_dimension (const tsBSpline *spline) 
size_t TINYSPLINE_API  ts_bspline_len_control_points (const tsBSpline *spline) 
size_t TINYSPLINE_API  ts_bspline_num_control_points (const tsBSpline *spline) 
size_t TINYSPLINE_API  ts_bspline_sof_control_points (const tsBSpline *spline) 
const tsReal TINYSPLINE_API *  ts_bspline_control_points_ptr (const tsBSpline *spline) 
tsError TINYSPLINE_API  ts_bspline_control_points (const tsBSpline *spline, tsReal **ctrlp, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_control_point_at_ptr (const tsBSpline *spline, size_t index, const tsReal **ctrlp, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_set_control_points (tsBSpline *spline, const tsReal *ctrlp, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_set_control_point_at (tsBSpline *spline, size_t index, const tsReal *ctrlp, tsStatus *status) 
size_t TINYSPLINE_API  ts_bspline_num_knots (const tsBSpline *spline) 
size_t TINYSPLINE_API  ts_bspline_sof_knots (const tsBSpline *spline) 
const tsReal TINYSPLINE_API *  ts_bspline_knots_ptr (const tsBSpline *spline) 
tsError TINYSPLINE_API  ts_bspline_knots (const tsBSpline *spline, tsReal **knots, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_knot_at (const tsBSpline *spline, size_t index, tsReal *knot, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_set_knots (tsBSpline *spline, const tsReal *knots, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_set_knots_varargs (tsBSpline *spline, tsStatus *status, tsReal knot0, double knot1,...) 
tsError TINYSPLINE_API  ts_bspline_set_knot_at (tsBSpline *spline, size_t index, tsReal knot, tsStatus *status) 
BSpline Initialization  
The following functions are used to create and release tsBSpline instances as well as to copy and move the internal data of a tsBSpline instance to another instance. Note: It is recommended to initialize an instance with ts_bspline_init. This way, ts_bspline_free can be called in ::TS_CATCH and ::TS_FINALLY blocks (see Section Error Handling for more details) without further checking. For example: tsBSpline spline = ts_bspline_init(); TS_TRY(...) ... TS_FINALLY ts_bspline_free(&spline); TS_END_TRY  
tsBSpline TINYSPLINE_API  ts_bspline_init (void) 
tsError TINYSPLINE_API  ts_bspline_new (size_t num_control_points, size_t dimension, size_t degree, tsBSplineType type, tsBSpline *spline, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_new_with_control_points (size_t num_control_points, size_t dimension, size_t degree, tsBSplineType type, tsBSpline *spline, tsStatus *status, double first,...) 
tsError TINYSPLINE_API  ts_bspline_copy (const tsBSpline *src, tsBSpline *dest, tsStatus *status) 
void TINYSPLINE_API  ts_bspline_move (tsBSpline *src, tsBSpline *dest) 
void TINYSPLINE_API  ts_bspline_free (tsBSpline *spline) 
De Boor Net Data  
The internal state of tsDeBoorNet is protected using the PIMPL design pattern (see https://en.cppreference.com/w/cpp/language/pimpl for more details). The data of an instance can be accessed with the functions listed in this section.  
tsReal TINYSPLINE_API  ts_deboornet_knot (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_index (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_multiplicity (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_num_insertions (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_dimension (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_len_points (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_num_points (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_sof_points (const tsDeBoorNet *net) 
const tsReal TINYSPLINE_API *  ts_deboornet_points_ptr (const tsDeBoorNet *net) 
tsError TINYSPLINE_API  ts_deboornet_points (const tsDeBoorNet *net, tsReal **points, tsStatus *status) 
size_t TINYSPLINE_API  ts_deboornet_len_result (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_num_result (const tsDeBoorNet *net) 
size_t TINYSPLINE_API  ts_deboornet_sof_result (const tsDeBoorNet *net) 
const tsReal TINYSPLINE_API *  ts_deboornet_result_ptr (const tsDeBoorNet *net) 
tsError TINYSPLINE_API  ts_deboornet_result (const tsDeBoorNet *net, tsReal **result, tsStatus *status) 
De Boor Net Initialization  
The following functions are used to create and release tsDeBoorNet instances as well as to copy and move the internal data of a tsDeBoorNet instance to another instance. Note: It is recommended to initialize an instance with ts_deboornet_init. This way, ts_deboornet_free can be called in ::TS_CATCH and ::TS_FINALLY blocks (see Section Error Handling for more details) without further checking. For example: tsDeBoorNet net = ts_deboornet_init(); TS_TRY(...) ... TS_FINALLY ts_deboornet_free(&net); TS_END_TRY  
tsDeBoorNet TINYSPLINE_API  ts_deboornet_init (void) 
tsError TINYSPLINE_API  ts_deboornet_copy (const tsDeBoorNet *src, tsDeBoorNet *dest, tsStatus *status) 
void TINYSPLINE_API  ts_deboornet_move (tsDeBoorNet *src, tsDeBoorNet *dest) 
void TINYSPLINE_API  ts_deboornet_free (tsDeBoorNet *net) 
Interpolation and Approximation Functions  
Given a set (or a sequence) of points, interpolate/approximate a spline that follows these points. Note: Approximations have not yet been implemented. Pull requests are welcome.  
tsError TINYSPLINE_API  ts_bspline_interpolate_cubic_natural (const tsReal *points, size_t num_points, size_t dimension, tsBSpline *spline, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_interpolate_catmull_rom (const tsReal *points, size_t num_points, size_t dimension, tsReal alpha, const tsReal *first, const tsReal *last, tsReal epsilon, tsBSpline *spline, tsStatus *status) 
Query Functions  
Functions for querying different kinds of data from splines.  
tsError TINYSPLINE_API  ts_bspline_eval (const tsBSpline *spline, tsReal knot, tsDeBoorNet *net, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_eval_all (const tsBSpline *spline, const tsReal *knots, size_t num, tsReal **points, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_sample (const tsBSpline *spline, size_t num, tsReal **points, size_t *actual_num, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_bisect (const tsBSpline *spline, tsReal value, tsReal epsilon, int persnickety, size_t index, int ascending, size_t max_iter, tsDeBoorNet *net, tsStatus *status) 
void TINYSPLINE_API  ts_bspline_domain (const tsBSpline *spline, tsReal *min, tsReal *max) 
tsError TINYSPLINE_API  ts_bspline_is_closed (const tsBSpline *spline, tsReal epsilon, int *closed, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_compute_rmf (const tsBSpline *spline, const tsReal *knots, size_t num, int has_first_normal, tsFrame *frames, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_chord_lengths (const tsBSpline *spline, const tsReal *knots, size_t num, tsReal *lengths, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_sub_spline (const tsBSpline *spline, tsReal knot0, tsReal knot1, tsBSpline *sub, tsStatus *status) 
void TINYSPLINE_API  ts_bspline_uniform_knot_seq (const tsBSpline *spline, size_t num, tsReal *knots) 
tsError TINYSPLINE_API  ts_bspline_equidistant_knot_seq (const tsBSpline *spline, size_t num, tsReal *knots, size_t num_samples, tsStatus *status) 
Transformation Functions  
Transformations modify the internal state of a spline—e.g., the number of control points, the structure of the knot vector, the degree, and so on. Some transformations modify the state without changing the shape of the spline (e.g., ts_bspline_elevate_degree). All transformations specify at least three parameters: i) an input spline (the spline to be transformed), ii) an output spline (the spline which receives the result of the transformation), and iii) a tsStatus object (output parameter for error handling). Along with these parameters, additional parameters may be necessary to i) calculate the transformation (such as ts_bspline_tension) and ii) store additional results (such as ts_bspline_insert_knot). Unless stated otherwise, the order of the parameters of a transformation function, t(input, [additional_input], output, [additional_output], status) Note: Transformation functions do not releases the memory of the output spline before assigning the result of the transformation to it. Thus, when using the same output spline multiple times, make sure to release its memory before each call (after the first one). If not, severe memory leaks are to be expected: tsBSpline in = ... // an arbitrary spline tsBSpline out = ts_bspline_init(); // stores the result ts_bspline_to_beziers(&in, &out); // first transformation ... // some code ts_bspline_free(&out); // avoid memory leak. ts_bspline_tension(&in, 0.85, &out); // next transformation It is possible to pass a spline as input and output argument at the same time. In this case, the called transformation uses a temporary buffer to store the working data. If the transformation succeeds, the memory of the supplied spline is released and the result is assigned to it. So even if a transformation fails, the internal state of the supplied splines stays intact (i.e., it remains unchanged). Note: It is not necessary to release the memory of a spline which is passed as input and output argument at the same time before calling the next transformation (in fact that would fail due to a null pointer): tsBSpline spline = ... // an arbitrary spline ts_bspline_to_beziers(&spline, &spline); // first transformation ts_bspline_tension(&spline, 0.85, &spline); // next transformation  
tsError TINYSPLINE_API  ts_bspline_derive (const tsBSpline *spline, size_t n, tsReal epsilon, tsBSpline *deriv, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_insert_knot (const tsBSpline *spline, tsReal knot, size_t num, tsBSpline *result, size_t *k, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_split (const tsBSpline *spline, tsReal knot, tsBSpline *split, size_t *k, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_tension (const tsBSpline *spline, tsReal beta, tsBSpline *out, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_to_beziers (const tsBSpline *spline, tsBSpline *beziers, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_elevate_degree (const tsBSpline *spline, size_t amount, tsReal epsilon, tsBSpline *elevated, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_align (const tsBSpline *s1, const tsBSpline *s2, tsReal epsilon, tsBSpline *s1_out, tsBSpline *s2_out, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_morph (const tsBSpline *origin, const tsBSpline *target, tsReal t, tsReal epsilon, tsBSpline *out, tsStatus *status) 
Serialization and Persistence  
The following functions can be used to serialize and persist (i.e., store the serialized data in a file) splines. There are also functions to load serialized splines.  
tsError TINYSPLINE_API  ts_bspline_to_json (const tsBSpline *spline, char **json, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_parse_json (const char *json, tsBSpline *spline, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_save (const tsBSpline *spline, const char *path, tsStatus *status) 
tsError TINYSPLINE_API  ts_bspline_load (const char *path, tsBSpline *spline, tsStatus *status) 
Vector Math  
Vector math is a not insignificant part of TinySpline, and so it's not surprising that some utility functions around vectors are needed. Because these functions might be useful for others, they are part of TinySpline's public API. However, note that the code is not highly optimized (with, for example, instruction set extensions like SSE). If high performance vector math is needed, other libraries should be used instead.  
void TINYSPLINE_API  ts_vec2_init (tsReal *out, tsReal x, tsReal y) 
void TINYSPLINE_API  ts_vec3_init (tsReal *out, tsReal x, tsReal y, tsReal z) 
void TINYSPLINE_API  ts_vec4_init (tsReal *out, tsReal x, tsReal y, tsReal z, tsReal w) 
void TINYSPLINE_API  ts_vec2_set (tsReal *out, const tsReal *x, size_t dim) 
void TINYSPLINE_API  ts_vec3_set (tsReal *out, const tsReal *x, size_t dim) 
void TINYSPLINE_API  ts_vec4_set (tsReal *out, const tsReal *x, size_t dim) 
void TINYSPLINE_API  ts_vec_add (const tsReal *x, const tsReal *y, size_t dim, tsReal *out) 
void TINYSPLINE_API  ts_vec_sub (const tsReal *x, const tsReal *y, size_t dim, tsReal *out) 
tsReal TINYSPLINE_API  ts_vec_dot (const tsReal *x, const tsReal *y, size_t dim) 
tsReal TINYSPLINE_API  ts_vec_angle (const tsReal *x, const tsReal *y, tsReal *buf, size_t dim) 
void TINYSPLINE_API  ts_vec3_cross (const tsReal *x, const tsReal *y, tsReal *out) 
void TINYSPLINE_API  ts_vec_norm (const tsReal *x, size_t dim, tsReal *out) 
tsReal TINYSPLINE_API  ts_vec_mag (const tsReal *x, size_t dim) 
void TINYSPLINE_API  ts_vec_mul (const tsReal *x, size_t dim, tsReal val, tsReal *out) 
Chord Length Method  
Functions for processing the cumulative chord lengths of a spline as computed by ts_bspline_chord_lengths.  
tsError TINYSPLINE_API  ts_chord_lengths_length_to_knot (const tsReal *knots, const tsReal *lengths, size_t num, tsReal len, tsReal *knot, tsStatus *status) 
tsError TINYSPLINE_API  ts_chord_lengths_t_to_knot (const tsReal *knots, const tsReal *lengths, size_t num, tsReal t, tsReal *knot, tsStatus *status) 
tsError TINYSPLINE_API  ts_chord_lengths_equidistant_knot_seq (const tsReal *knots, const tsReal *lengths, size_t num, size_t num_knot_seq, tsReal *knot_seq, tsStatus *status) 
Utility Functions  
int TINYSPLINE_API  ts_knots_equal (tsReal x, tsReal y) 
void TINYSPLINE_API  ts_arr_fill (tsReal *arr, size_t num, tsReal val) 
tsReal TINYSPLINE_API  ts_distance (const tsReal *x, const tsReal *y, size_t dim) 
Error Handling  
There are three types of error handling in TinySpline.
 
#define  TS_TRY(label, error, status) 
#define  TS_CALL(label, error, call) 
#define  TS_CATCH(error) } if ((error)) { 
#define  TS_FINALLY } { 
#define  TS_END_TRY 
#define  TS_END_TRY_RETURN(error) TS_END_TRY return (error); 
#define  TS_END_TRY_ROE(error) TS_END_TRY if ((error)) return error; 
#define  TS_CALL_ROE(error, call) 
#define  TS_RETURN_SUCCESS(status) 
#define  TS_RETURN_0(status, error, msg) 
#define  TS_RETURN_1(status, error, msg, arg1) 
#define  TS_RETURN_2(status, error, msg, arg1, arg2) 
#define  TS_RETURN_3(status, error, msg, arg1, arg2, arg3) 
#define  TS_RETURN_4(status, error, msg, arg1, arg2, arg3, arg4) 
#define  TS_THROW_0(label, error, status, val, msg) 
#define  TS_THROW_1(label, error, status, val, msg, arg1) 
#define  TS_THROW_2(label, error, status, val, msg, arg1, arg2) 
#define  TS_THROW_3(label, error, status, val, msg, arg1, arg2, arg3) 
#define  TS_THROW_4(label, error, status, val, msg, arg1, arg2, arg3, arg4) 
enum  tsError { TS_SUCCESS = 0 , TS_MALLOC = 1 , TS_DIM_ZERO = 2 , TS_DEG_GE_NCTRLP = 3 , TS_U_UNDEFINED = 4 , TS_MULTIPLICITY = 5 , TS_KNOTS_DECR = 6 , TS_NUM_KNOTS = 7 , TS_UNDERIVABLE = 8 , TS_LCTRLP_DIM_MISMATCH = 10 , TS_IO_ERROR = 11 , TS_PARSE_ERROR = 12 , TS_INDEX_ERROR = 13 , TS_NO_RESULT = 14 , TS_NUM_POINTS = 15 } 
#define TS_CALL  (  label,  
error,  
call  
) 
#define TS_CALL_ROE  (  error,  
call  
) 
#define TS_DOMAIN_DEFAULT_MAX 1.0f 
The maximum of the domain of newly created splines. Must be greater than TS_DOMAIN_DEFAULT_MIN. This constant is used only when creating new splines. After creation, the domain of a spline can be adjusted as needed.
#define TS_DOMAIN_DEFAULT_MIN 0.0f 
The minimum of the domain of newly created splines. Must be less than TS_DOMAIN_DEFAULT_MAX. This constant is used only when creating new splines. After creation, the domain of a spline can be adjusted as needed.
#define TS_END_TRY 
#define TS_KNOT_EPSILON 1e4f 
If the distance between two knots falls below this threshold, they are considered equal. Must be positive ( > 0 ). This constant is strongly related to TS_MAX_NUM_KNOTS in that the more precise TS_KNOT_EPSILON is (i.e., knots with smaller distance are considered equal), the less TS_MAX_NUM_KNOTS has to be. Likewise, the larger TS_MAX_NUM_KNOTS is, the less precise TS_KNOT_EPSILON has to be (i.e., knots with greater distance are considered equal). By default, the relation between TS_KNOT_EPSILON and TS_MAX_NUM_KNOTS is as follows:
TS_KNOT_EPSILON = 1 / TS_MAX_NUM_KNOTS
It is recommended that TS_KNOT_EPSILON is aligned to the span of TS_DOMAIN_DEFAULT_MIN and TS_DOMAIN_DEFAULT_MAX. That is, adjacent floating point values in the domain [TS_DOMAIN_DEFAULT_MIN, TS_DOMAIN_DEFAULT_MAX] should not be equal according to TS_KNOT_EPSILON. This is in particular recommended when TS_KNOT_EPSILON and TS_MAX_NUM_KNOTS are related to each other as described above.
#define TS_LENGTH_ZERO 1e4f 
If the length of an element (e.g., a vector) is less than this threshold, the length is considered 0
. Must be positive ( > 0 ).
#define TS_MAX_NUM_KNOTS 10000 
The maximum number of knots a spline can have. This constant is strongly related to TS_KNOT_EPSILON in that the larger TS_MAX_NUM_KNOTS is, the less precise TS_KNOT_EPSILON has to be (i.e., knots with greater distance are considered equal). Likewise, the more precise TS_KNOT_EPSILON is (i.e., knots with smaller distance are considered equal), the less TS_MAX_NUM_KNOTS has to be. By default, the relation between TS_MAX_NUM_KNOTS and TS_KNOT_EPSILON is as follows:
TS_MAX_NUM_KNOTS = 1 / TS_KNOTS_EPSILON
#define TS_PI 3.14159265358979323846 
The mathematical constant pi.
#define TS_POINT_EPSILON 1e5f 
If the distance between two (control) points is less than or equal to this threshold, they are considered equal. This constant is not used directly by the C interface. Rather, it serves as a viable default value for functions requiring an epsilon environment to decide whether two (control) points are equal or not. The C++ interface, for example, uses this as default value for optional parameters.
#define TS_RETURN_0  (  status,  
error,  
msg  
) 
#define TS_RETURN_1  (  status,  
error,  
msg,  
arg1  
) 
#define TS_RETURN_2  (  status,  
error,  
msg,  
arg1,  
arg2  
) 
#define TS_RETURN_3  (  status,  
error,  
msg,  
arg1,  
arg2,  
arg3  
) 
#define TS_RETURN_4  (  status,  
error,  
msg,  
arg1,  
arg2,  
arg3,  
arg4  
) 
#define TS_RETURN_SUCCESS  (  status  ) 
#define TS_THROW_0  (  label,  
error,  
status,  
val,  
msg  
) 
#define TS_THROW_1  (  label,  
error,  
status,  
val,  
msg,  
arg1  
) 
#define TS_THROW_2  (  label,  
error,  
status,  
val,  
msg,  
arg1,  
arg2  
) 
#define TS_THROW_3  (  label,  
error,  
status,  
val,  
msg,  
arg1,  
arg2,  
arg3  
) 
#define TS_THROW_4  (  label,  
error,  
status,  
val,  
msg,  
arg1,  
arg2,  
arg3,  
arg4  
) 
#define TS_TRY  (  label,  
error,  
status  
) 
typedef double tsReal 
TinySpline uses its own typedef for floating point numbers. Supported are floats (single precision) and doubles (double precision). By default, doubles are used. Note that this typedef affects the entire API (i.e., types are not mixed; all structs and functions rely only on tsReal). Float precision is primarily used in combination with GLUT because GLUT's API doesn't support doubles:
https://www.glprogramming.com/red/chapter12.html
Generally, double precision is the right choice. Floats are mainly supported for legacy reasons. Yet, floats are not considered deprecated! If necessary, tsReal can also be typedefed to any other floating point representation. In this case, make sure to adjust TS_MAX_NUM_KNOTS and TS_KNOT_EPSILON (cf. Section "Predefined Constants").
enum tsBSplineType 
Describes the structure of the knot vector. More details can be found at:
www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bspline/bsplinecurve.html
enum tsError 
Defines different error codes.
Fills the given array arr
with val
.
[in]  arr  The array to be filled. 
[in]  num  Fill length. 
[in]  val  The value to fill into arr . 
tsError TINYSPLINE_API ts_bspline_align  (  const tsBSpline *  s1, 
const tsBSpline *  s2,  
tsReal  epsilon,  
tsBSpline *  s1_out,  
tsBSpline *  s2_out,  
tsStatus *  status  
) 
Modifies the splines s1
and s2
such that they have same the degree and number of control points/knots (without modifying the shape of s1
and s2
). The resulting splines are stored in s1_out
and s2_out
. If s1
!= s1_out
, the internal state of s1
is not modified, that is, s1_out
is a new, independent tsBSpline instance. The same is true for s2
and s2_out
.
[in]  s1  The spline which is to be aligned with s2 . 
[in]  s2  The spline which is to be aligned with s1 . 
[in]  epsilon  Spline alignment relies on degree elevation. This parameter is used in ts_bspline_elevate_degree to check whether two control points, p1 and p2 , are "equal", that is, the distance between p1 and p2 is less than or equal to epsilon . A viable default value is TS_POINT_EPSILON. 
[out]  s1_out  The aligned version of s1 . 
[out]  s2_out  The aligned version of s2 . 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_bisect  (  const tsBSpline *  spline, 
tsReal  value,  
tsReal  epsilon,  
int  persnickety,  
size_t  index,  
int  ascending,  
size_t  max_iter,  
tsDeBoorNet *  net,  
tsStatus *  status  
) 
Tries to find a point P on spline
such that:
ts_distance(P[index], value, 1) <= fabs(epsilon)
This function is using the bisection method to determine P. Accordingly, it is expected that the control points of spline
are sorted at component index
either in ascending order (if ascending
!= 0) or in descending order (if ascending
== 0). If the control points of spline
are not sorted at component index
, the behaviour of this function is undefined. For the sake of failsafeness, the distance of P[index] and value
is compared with the absolute value of epsilon
(using fabs).
The bisection method is an iterative approach which minimizes the error (epsilon
) with each iteration step until an "optimum" was found. However, there may be no point P satisfying the distance condition. Thus, the number of iterations must be limited (max_iter
). Depending on the domain of the control points of spline
at component index
and epsilon
, max_iter
ranges from 7 to 50. In most cases max_iter
== 30 should be fine though. The parameter persnickety
allows to define the behaviour of this function is case no point was found after max_iter
iterations. If enabled (!= 0), TS_NO_RESULT is returned. If disabled (== 0), the best fitting point is returned.
[in]  spline  The spline to evaluate 
[in]  value  The value (point at component index ) to find. 
[in]  epsilon  The maximum distance (inclusive). 
[in]  persnickety  Indicates whether TS_NO_RESULT should be returned if there is no point P satisfying the distance condition (!= 0 to enable, == 0 to disable). If disabled, the best fitting point is returned. 
[in]  index  The point's component. 
[in]  ascending  Indicates whether the control points of spline are sorted in ascending (!= 0) or in descending (== 0) order at component index . 
[in]  max_iter  The maximum number of iterations (30 is a sane default value). 
[out]  net  The output parameter. 
[out]  status  The status of this function. May be NULL. 
spline
<= index
. persnickety
is enabled (!= 0) and there is no point P satisfying the distance condition. tsError TINYSPLINE_API ts_bspline_chord_lengths  (  const tsBSpline *  spline, 
const tsReal *  knots,  
size_t  num,  
tsReal *  lengths,  
tsStatus *  status  
) 
Computes the cumulative chord lengths of the points of the given knots. Note that the first length (i.e., lengths[0]
) is always 0
, even if the minimum of the domain of spline
is less than the first knot (i.e., knots[0]
). Also, the returned lengths may be inaccurate if spline
is discontinuous (i.e., the multiplicity of one of the interior knots is equal to the order of spline
) with unequal evaluation points—in such case only the first result of the evaluation is included in the calculation.
knots
and lengths
have length num
. [in]  spline  The spline to query. 
[in]  knots  The knots to evaluate spline at. 
[in]  num  Number of knots in knots . 
[out]  lengths  The cumulative chord lengths. lengths[i] is the length of spline at knot i (knots[i] ). 
[out]  status  The status of this function. May be NULL. 
spline
is not defined at one of the knots in knots
. knots
is not monotonically increasing. tsError TINYSPLINE_API ts_bspline_compute_rmf  (  const tsBSpline *  spline, 
const tsReal *  knots,  
size_t  num,  
int  has_first_normal,  
tsFrame *  frames,  
tsStatus *  status  
) 
Computes a sequence of threedimensional frames (see tsFrame) for the spline spline
. The position of the frames corresponds to the knots in knots
. The implementation is based on:
@article{10.1145/1330511.1330513, author = {Wang, Wenping and J\"{u}ttler, Bert and Zheng, Dayue and Liu, Yang}, title = {Computation of Rotation Minimizing Frames}, year = {2008}, issue_date = {March 2008}, publisher = {Association for Computing Machinery}, address = {New York, NY, USA}, volume = {27}, number = {1}, issn = {07300301}, url = {https://doi.org/10.1145/1330511.1330513}, doi = {10.1145/1330511.1330513}, abstract = {Due to its minimal twist, the rotation minimizing frame (RMF) is widely used in computer graphics, including sweep or blending surface modeling, motion design and control in computer animation and robotics, streamline visualization, and tool path planning in CAD/CAM. We present a novel simple and efficient method for accurate and stable computation of RMF of a curve in 3D. This method, called the double reflection method, uses two reflections to compute each frame from its preceding one to yield a sequence of frames to approximate an exact RMF. The double reflection method has the fourth order global approximation error, thus it is much more accurate than the two currently prevailing methods with the second order approximation errorâ€”the projection method by Klok and the rotation method by Bloomenthal, while all these methods have nearly the same perframe computational cost. Furthermore, the double reflection method is much simpler and faster than using the standard fourth order RungeKutta method to integrate the defining ODE of the RMF, though they have the same accuracy. We also investigate further properties and extensions of the double reflection method, and discuss the variational principles in design moving frames with boundary conditions, based on RMF.}, journal = {ACM Trans. Graph.}, month = mar, articleno = {2}, numpages = {18}, keywords = {motion design, sweep surface, motion, differential geometry, Curve, rotation minimizing frame} }
knots
and frames
have num
entries. [in]  spline  The spline to query. 
[in]  knots  The knots to query spline at. 
[in]  num  Number of elements in knots and frames . Can be 0 . 
[in]  has_first_normal  Indicates whether the normal of the first element of frames should be taken as starting value for the algorithm. If 0 , the starting normal is determined based on the tangent of spline at knots [0]. Note that, if the argument value is not 0 , it is up to the caller of this function to ensure that the supplied normal is valid. The function only normalizes the supplied value. 
[in,out]  frames  Stores the computed frames. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_control_point_at_ptr  (  const tsBSpline *  spline, 
size_t  index,  
const tsReal **  ctrlp,  
tsStatus *  status  
) 
Returns the pointer to the control point of spline
at index
. Note that the type of the out parameter ctrlp
is const
for a reason. Clients should only read the returned array. When suppressing the constness of ctrlp
and writing to the array against better knowledge, the client is on its own with regard to the consistency of the internal state of spline
. If one of the control points of a spline needs to be changed, use ts_bspline_set_control_points to copy the new control point to the spline.
[in]  spline  The spline whose pointer to the control point at index is returned. 
[in]  index  Zerobased index of the control point to be returned. 
[out]  ctrlp  Pointer to the control point of spline at index . 
[out]  status  The status of this function. May be NULL. 
index
is out of range. tsError TINYSPLINE_API ts_bspline_control_points  (  const tsBSpline *  spline, 
tsReal **  ctrlp,  
tsStatus *  status  
) 
Returns a deep copy of the control points of spline
.
[in]  spline  The spline whose control points are read. 
[out]  ctrlp  The output array. Note: It is the responsibility of the client to release the allocated memory after use. 
[out]  status  The status of this function. May be NULL. 
Returns the pointer to the control point array of spline
. Note that the return type of this function is const
for a reason. Clients should only read the returned array. When suppressing the constness and writing to the array against better knowledge, the client is on its own with regard to the consistency of the internal state of spline
. If the control points of a spline need to be changed, use ts_bspline_control_points to obtain a copy of the control point array and ts_bspline_set_control_points to copy the changed values back to the spline.
[in]  spline  The spline whose pointer to the control point array is returned. 
spline
. tsError TINYSPLINE_API ts_bspline_copy  (  const tsBSpline *  src, 
tsBSpline *  dest,  
tsStatus *  status  
) 
Creates a deep copy of src
and stores the copied data in dest
. src
and dest
can be the same instance.
Note: Unlike memcpy and memmove, the first parameter is the source and the second parameter is the destination.
[in]  src  The spline to be deep copied. 
[out]  dest  The output spline. 
[out]  status  The status of this function. May be NULL. 
size_t TINYSPLINE_API ts_bspline_degree  (  const tsBSpline *  spline  ) 
Returns the degree of spline
.
[in]  spline  The spline whose degree is read. 
spline
. tsError TINYSPLINE_API ts_bspline_derive  (  const tsBSpline *  spline, 
size_t  n,  
tsReal  epsilon,  
tsBSpline *  deriv,  
tsStatus *  status  
) 
Returns the n'th
derivative of spline
as tsBSpline instance. The derivative of a spline s
of degree d
(d
> 0) with m
control points and n
knots is another spline s'
of degree d1
with m1
control points and n2
knots, defined over s
as:
If s
has a clamped knot vector, it can be shown that:
where the multiplicity of the first and the last knot value u
is p
rather than p+1
. The derivative of a point (degree 0) is another point with coordinate 0. For more details, see:
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bspline/bsplinederv.html
If spline
!= deriv
, the internal state of spline
is not modified, that is, deriv
is a new, independent tsBSpline instance.
[in]  spline  The spline to be derived. 
[in]  n  Number of derivations. 
[in]  epsilon  The maximum distance of discontinuous points. If negative, discontinuity is ignored and the derivative is computed based on the first result of the corresponding tsDeBoorNet. 
[out]  deriv  The derivative of spline . 
[out]  status  The status of this function. May be NULL. 
spline
is discontinuous at an internal knot and the distance between the corresponding points is greater than epsilon
. < Stores the intermediate result.
< Pointer to the control points of worker.
< Pointer to the knots of worker.
< Used in for loops.
< Pointer to first and second control point.
< Distance between fst and snd.
< Knots at i+deg+1 and i+1.
< Distance between kid1 and ki1.
< Used to swap worker and derivative.
size_t TINYSPLINE_API ts_bspline_dimension  (  const tsBSpline *  spline  ) 
Returns the dimensionality of spline
, that is, the number of components of its control points (ts_bspline_control_points). Onedimensional splines are possible, albeit their benefit might be questionable.
[in]  spline  The spline whose dimension is read. 
spline
(>= 1). Returns the domain of spline
.
[in]  spline  The spline to query. 
[out]  min  The lower bound of the domain of spline . 
[out]  max  The upper bound of the domain of spline . 
tsError TINYSPLINE_API ts_bspline_elevate_degree  (  const tsBSpline *  spline, 
size_t  amount,  
tsReal  epsilon,  
tsBSpline *  elevated,  
tsStatus *  status  
) 
Elevates the degree of spline
by amount
and stores the result in elevated
. If spline
!= elevated
, the internal state of spline
is not modified, that is, elevated
is a new, independent tsBSpline instance.
[in]  spline  The spline to be elevated. 
[in]  amount  How often to elevate the degree of spline . 
[in]  epsilon  In order to elevate the degree of a spline, it must be decomposed into a sequence of bezier curves (see ts_bspline_to_beziers). After degree elevation, the split points of the bezier curves are merged again. This parameter is used to distinguish between the split points of the decomposition process and discontinuity points that should be retained. A viable default value is TS_POINT_EPSILON. If negative, the resulting spline, elevated , forms a sequence of bezier curves. 
[out]  elevated  The elevated spline. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_equidistant_knot_seq  (  const tsBSpline *  spline, 
size_t  num,  
tsReal *  knots,  
size_t  num_samples,  
tsStatus *  status  
) 
Shortcut function for ts_chord_lengths_equidistant_knot_seq. The ordering of the parameters (in particular, num_samples
after knots
) is aligned to ts_bspline_uniform_knot_seq so that it is easier for users to replace one call with the other.
[in]  spline  The spline to query. 
[in]  num  Number of knots in knots . 
[out]  knots  Stores the generated knot sequence. 
[in]  num_samples  Number of knots to be sampled for the 'reparametrization by arc length'. 200 yields a quite precise mapping (subpixel accuracy). For very, very high precision requirements, 500 should be sufficient. If 0 , the default value 200 is used as fallback. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_eval  (  const tsBSpline *  spline, 
tsReal  knot,  
tsDeBoorNet *  net,  
tsStatus *  status  
) 
Evaluates spline
at knot
and stores the result (see tsDeBoorNet) in net
.
[in]  spline  The spline to evaluate. 
[in]  knot  The knot to evaluate spline at. 
[out]  net  Stores the evaluation result. 
[out]  status  The status of this function. May be NULL. 
spline
is not defined at knot
. tsError TINYSPLINE_API ts_bspline_eval_all  (  const tsBSpline *  spline, 
const tsReal *  knots,  
size_t  num,  
tsReal **  points,  
tsStatus *  status  
) 
Evaluates spline
at each knot in knots
and stores the evaluated points (see ts_deboornet_result) in points
. If knots
contains one or more knots where spline
is discontinuous at, only the first point of the corresponding evaluation result is taken. After calling this function points
contains exactly
values.
This function is in particular useful in cases where a multitude of knots need to be evaluated, because only a single instance of tsDeBoorNet is created and reused for all evaluation tasks (therefore the memory footprint is reduced to a minimum).
[in]  spline  The spline to evaluate. 
[in]  knots  The knot values to evaluate. 
[in]  num  The number of knots in us . 
[out]  points  The output parameter. 
[out]  status  The status of this function. May be NULL. 
spline
is not defined at one of the knot values in us
. void TINYSPLINE_API ts_bspline_free  (  tsBSpline *  spline  ) 
Releases the data of spline
. After calling this function, the data of spline
points to NULL.
[out]  spline  The spline to be released. 
tsBSpline TINYSPLINE_API ts_bspline_init  (  void  ) 
Creates a new spline whose data points to NULL.
tsError TINYSPLINE_API ts_bspline_insert_knot  (  const tsBSpline *  spline, 
tsReal  knot,  
size_t  num,  
tsBSpline *  result,  
size_t *  k,  
tsStatus *  status  
) 
Inserts knot
num
times into the knot vector of spline
. The operation fails if result
would have an invalid knot vector (i.e., multiplicity(knot) > order(result)). If spline
!= result
, the internal state of spline
is not modified, that is, result
is a new, independent tsBSpline instance.
[in]  spline  The spline into which knot is inserted num times. 
[in]  knot  The knot to be inserted. 
[in]  num  Number of insertions. 
[out]  result  The output spline. 
[out]  k  Stores the last index of knot in result . 
status  The status of this function. May be NULL. 
knot
is not within the domain of spline
. knot
in spline
plus num
is greater than the order of spline
. tsError TINYSPLINE_API ts_bspline_interpolate_catmull_rom  (  const tsReal *  points, 
size_t  num_points,  
size_t  dimension,  
tsReal  alpha,  
const tsReal *  first,  
const tsReal *  last,  
tsReal  epsilon,  
tsBSpline *  spline,  
tsStatus *  status  
) 
Interpolates a piecewise cubic spline by translating the given catmullrom control points into a sequence of bezier curves. In order to avoid division by zero, successive control points with distance less than or equal to epsilon
are filtered out. If the resultant sequence contains only a single point, a cubic point (i.e., a spline with four times the same control point) is created. Optionally, the first and last control point can be specified (see first
and last
).
[in]  points  The points to be interpolated. 
[in]  num_points  The number of points in points . If 1 , a cubic point (i.e., a spline with four times the same control point) is created. 
[in]  dimension  The dimensionality of the points. 
[in]  alpha  Knot parameterization: 0 => uniform, 0.5 => centripetal, 1 => chordal. The input value is clamped to the domain [0, 1]. 
[in]  first  The first control point of the catmullrom sequence. If NULL, an appropriate point is generated based on the first two points in points . If the distance between first and the first control point in points is less than or equals to epsilon , first is treated as NULL. This is necessary to avoid division by zero. 
[in]  last  The last control point of the catmullrom sequence. If NULL, an appropriate point is generated based on the last two points in points . If the distance between last and the last control point in points is less than or equals to epsilon , last is treated as NULL. This is necessary to avoid division by zero. 
[in]  epsilon  The maximum distance between points with "same" coordinates. That is, if the distance between neighboring points is less than or equal to epsilon , they are considered equal. For the sake of failsafeness, the sign is removed with fabs. It is advisable to pass a value greater than zero, however, it is not necessary. 
[out]  spline  The interpolated spline. 
[out]  status  The status of this function. May be NULL. 
dimension
is 0. num_points
is 0. < The points to interpolate based on points
.
< Used in for loops.
< Local error handling.
< CatmullRom knots.
< Used to calculate derivatives.
< Processed CatmullRom points.
tsError TINYSPLINE_API ts_bspline_interpolate_cubic_natural  (  const tsReal *  points, 
size_t  num_points,  
size_t  dimension,  
tsBSpline *  spline,  
tsStatus *  status  
) 
Interpolates a cubic spline with natural end conditions. For more details see:
https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm http://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf http://www.bakomatex.com/doc/generic/pstbspline/pstbsplinedoc.pdf
The interpolated spline is a sequence of bezier curves connecting each point in points
. Each bezier curve is of degree 3
with dimensionality dimension
. The total number of control points is:
min(1, \p num_points  1) * 4
Note: num_points
is the number of points in points
and not the length of points
. For instance, the following point vector has num_points
= 4 and dimension
= 2:
[x0, y0, x1, y1, x2, y2, x3, y3]
[in]  points  The points to be interpolated. 
[in]  num_points  The number of points in points . If 1 , a cubic point (i.e., a spline with four times the same control point) is created. 
[in]  dimension  The dimensionality of the points. 
[out]  spline  The interpolated spline. 
[out]  status  The status of this function. May be NULL. 
dimension
is 0. num_points
is 0. tsError TINYSPLINE_API ts_bspline_is_closed  (  const tsBSpline *  spline, 
tsReal  epsilon,  
int *  closed,  
tsStatus *  status  
) 
Checks whether the distance of the endpoints of spline
is less than or equal to epsilon
for the first 'ts_bspline_degree  1' derivatives (starting with the zeroth derivative).
[in]  spline  The spline to query. 
[in]  epsilon  The maximum distance. 
[out]  closed  The output parameter. 1 if true, 0 otherwise. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_knot_at  (  const tsBSpline *  spline, 
size_t  index,  
tsReal *  knot,  
tsStatus *  status  
) 
Returns the knot of spline
at index
.
[in]  spline  The spline whose knot is read at index . 
[in]  index  Zerobased index of the knot to be read. 
[out]  knot  The output value. 
[out]  status  The status of this function. May be NULL. 
index
is out of range. tsError TINYSPLINE_API ts_bspline_knots  (  const tsBSpline *  spline, 
tsReal **  knots,  
tsStatus *  status  
) 
Returns a deep copy of the knots of spline
.
[in]  spline  The spline whose knots are read. 
[out]  knots  The output array. Note: It is the responsibility of the client to release the allocated memory after use. 
[out]  status  The status of this function. May be NULL. 
Returns the pointer to the knot vector of spline
. Note that the return type of this function is const
for a reason. Clients should only read the returned array. When suppressing the constness and writing to the array against better knowledge, the client is on its own with regard to the consistency of the internal state of spline
. If the knot vector of a spline needs to be changed, use ts_bspline_knots to obtain a copy of the knot vector and ts_bspline_set_knots to copy the changed values back to the spline.
[in]  spline  The spline whose pointer to the knot vector is returned. 
spline
. size_t TINYSPLINE_API ts_bspline_len_control_points  (  const tsBSpline *  spline  ) 
Returns the length of the control point array of spline
.
[in]  spline  The spline whose length of the control point array is read. 
spline
. Loads spline
from a JSON ASCII file.
[in]  path  Path of the JSON file to be loaded. 
[out]  spline  The output spline. 
[ou]  status The status of this function. May be NULL. 
path
does not exist. path
. 0
. 0
. tsError TINYSPLINE_API ts_bspline_morph  (  const tsBSpline *  origin, 
const tsBSpline *  target,  
tsReal  t,  
tsReal  epsilon,  
tsBSpline *  out,  
tsStatus *  status  
) 
Interpolates between origin
and target
with respect to the time parameter t
(domain: [0, 1]; clamped if necessary). The resulting spline is stored in out
. Because it is to be expected that this function is called several times in a row (e.g., to have a smooth transition from one spline to another), memory for out
is allocated only if it points to NULL or if it has to be enlarged to store the result of the interpolation (which can only happen if origin
or target—or
both—have been changed since the last call). This way, this function can be used as follows:
tsReal t; tsBSpline origin = ... tsBSpline target = ... tsBSpline morph = ts_bspline_init(); for (t = (tsReal) 0.0; t <= (tsReal) 1.0; t += (tsReal) 0.001) ts_bspline_morph(&origin, &target, t, ..., &morph, ...); ts_bspline_free(&morph);
It should be noted that this function, if necessary, aligns origin
and target
using ts_bspline_align. In order to avoid the overhead of spline alignment, origin
and target
should be aligned in advance.
[in]  origin  Origin spline. 
[in]  target  Target spline. 
[in]  t  The time parameter. If 0, out becomes origin . If 1, out becomes target . Note that the value passed is clamped to the domain [0, 1]. 
[in]  epsilon  If origin and target must be aligned, this parameter is passed ts_bspline_elevate_degree to check whether two control points, p1 and p2 , are "equal", that is, the distance between p1 and p2 is less than or equal to epsilon . A viable default value is TS_POINT_EPSILON. 
[out]  out  The resulting spline. 
Moves the ownership of the data of src
to dest
. After calling this function, the data of src
points to NULL. Does not release the data of dest
. src
and dest
can be the same instance (in this case, the data of src
remains).
[in,out]  src  The spline whose data is moved to dest . 
[out]  dest  The spline that receives the data of src . 
tsError TINYSPLINE_API ts_bspline_new  (  size_t  num_control_points, 
size_t  dimension,  
size_t  degree,  
tsBSplineType  type,  
tsBSpline *  spline,  
tsStatus *  status  
) 
Creates a new spline and stores the result in spline
.
[in]  num_control_points  The number of control points of spline . 
[in]  dimension  The dimension of the control points of spline . 
[in]  degree  The degree of spline . 
[in]  type  How to setup the knot vector of spline . 
[out]  spline  The output spline. 
[out]  status  The status of this function. May be NULL. 
dimension
is 0
. degree
>= num_control_points
. type
is TS_BEZIERS and (num_control_points
% degree
+ 1) != 0. tsError TINYSPLINE_API ts_bspline_new_with_control_points  (  size_t  num_control_points, 
size_t  dimension,  
size_t  degree,  
tsBSplineType  type,  
tsBSpline *  spline,  
tsStatus *  status,  
double  first,  
...  
) 
Creates a new spline with given control points (varargs) and stores the result in spline
. As all splines have at least one control point (with minimum dimensionality one), the first component of the first control point has a named parameter. Note that, by design of varargs in C, the last named parameter must not be float. Thus, first
is of type double instead of tsReal.
[in]  num_control_points  The number of control points of spline . 
[in]  dimension  The dimension of the control points of spline . 
[in]  degree  The degree of spline . 
[in]  type  How to setup the knot vector of spline . 
[out]  spline  The output spline. 
[out]  status  The status of this function. May be NULL. 
[in]  first  The first component of the first control point. 
[in]  ...  The remaining components (control points). 
dimension
is 0
. degree
>= num_control_points
. type
is TS_BEZIERS and (num_control_points
% degree
+ 1) != 0. size_t TINYSPLINE_API ts_bspline_num_control_points  (  const tsBSpline *  spline  ) 
Returns the number of control points of spline
.
[in]  spline  The spline whose number of control points is read. 
spline
. size_t TINYSPLINE_API ts_bspline_num_knots  (  const tsBSpline *  spline  ) 
Returns the number of knots of spline
.
[in]  spline  The spline whose number of knots is read. 
spline
. size_t TINYSPLINE_API ts_bspline_order  (  const tsBSpline *  spline  ) 
Returns the order (degree + 1) of spline
.
[in]  spline  The spline whose order is read. 
spline
. tsError TINYSPLINE_API ts_bspline_parse_json  (  const char *  json, 
tsBSpline *  spline,  
tsStatus *  status  
) 
Parses json
and stores the result in spline
.
[in]  json  The JSON string to be parsed. 
[out]  spline  The output spline. 
[out]  status  The status of this function. May be NULL. 
json
. 0
. 0
. tsError TINYSPLINE_API ts_bspline_sample  (  const tsBSpline *  spline, 
size_t  num,  
tsReal **  points,  
size_t *  actual_num,  
tsStatus *  status  
) 
Generates a sequence of num
different knots, passes this sequence to ts_bspline_eval_all, and stores the resultant points in points
. The sequence of knots is generated using ts_bspline_uniform_knot_seq. If num
is 0, the default value 100
is used as fallback.
For the sake of stability regarding future changes, the actual number of generated knots (which only differs from num
if num
is 0) is stored in actual_num
. If num
is 1, the point located at the minimum of the domain of spline
is evaluated.
[in]  spline  The spline to be evaluate. 
[in]  num  The number of knots to be generate. 
[out]  points  The output parameter. 
[out]  actual_num  The actual number of generated knots. Differs from num only if num is 0. Must not be NULL. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_save  (  const tsBSpline *  spline, 
const char *  path,  
tsStatus *  status  
) 
Saves spline
as JSON ASCII file.
[in]  spline  The spline to be saved. 
[in]  path  Path of the JSON file. 
[out]  status  The status of this function. May be NULL. 
spline
. tsError TINYSPLINE_API ts_bspline_set_control_point_at  (  tsBSpline *  spline, 
size_t  index,  
const tsReal *  ctrlp,  
tsStatus *  status  
) 
Sets the control point of spline
at index
. Creates a deep copy of ctrlp
.
ctrlp
has length ts_bspline_dimension. [out]  spline  The spline whose control point is set at index . 
[in]  index  Zerobased index of the control point to be set. 
[in]  ctrlp  The value. 
[out]  status  The status of this function. May be NULL. 
index
is out of range. tsError TINYSPLINE_API ts_bspline_set_control_points  (  tsBSpline *  spline, 
const tsReal *  ctrlp,  
tsStatus *  status  
) 
Sets the control points of spline
. Creates a deep copy of ctrlp
.
ctrlp
has length ts_bspline_len_control_points. [out]  spline  The spline whose control points are set. 
[in]  ctrlp  The value. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_set_knot_at  (  tsBSpline *  spline, 
size_t  index,  
tsReal  knot,  
tsStatus *  status  
) 
Sets the knot of spline
at index
.
[in]  spline  The spline whose knot is set at index . 
[in]  index  Zerobased index of the knot to be set. 
[in]  knot  The value. 
[out]  status  The status of this function. May be NULL. 
index
is out of range. index
results in a decreasing knot vector. index
results in a knot vector containing knot
with multiplicity greater than the order of spline
. tsError TINYSPLINE_API ts_bspline_set_knots  (  tsBSpline *  spline, 
const tsReal *  knots,  
tsStatus *  status  
) 
Sets the knots of spline
. Creates a deep copy of knots
.
knots
has length ts_bspline_num_knots. [out]  spline  The spline whose knots are set. 
[in]  knots  The value. 
[out]  status  The status of this function. May be NULL. 
tsError TINYSPLINE_API ts_bspline_set_knots_varargs  (  tsBSpline *  spline, 
tsStatus *  status,  
tsReal  knot0,  
double  knot1,  
...  
) 
Sets the knots of spline
supplied as varargs. As all splines have at least two knots, the first two knots have a named parameter. Note that, by design of varargs in C, the last named parameter must not be float. Thus, knot1
is of type double instead of tsReal.
[out]  spline  The spline whose knots are set. 
[out]  status  The status of this function. May be NULL. 
[in]  knot0  The first knot. 
[in]  knot1  the second knot. 
[in]  ...  The remaining knots. 
size_t TINYSPLINE_API ts_bspline_sof_control_points  (  const tsBSpline *  spline  ) 
Returns the size of the control point array of spline
. This function may be useful when copying control points using memcpy or memmove.
[in]  spline  The spline whose size of the control point array is read. 
spline
. size_t TINYSPLINE_API ts_bspline_sof_knots  (  const tsBSpline *  spline  ) 
Returns the size of the knot array of spline
. This function may be useful when copying knots using memcpy or memmove.
[in]  spline  The spline whose size of the knot array is read. 
spline
. tsError TINYSPLINE_API ts_bspline_split  (  const tsBSpline *  spline, 
tsReal  knot,  
tsBSpline *  split,  
size_t *  k,  
tsStatus *  status  
) 
Splits spline
at knot
. That is, knot
is inserted into spline
n
times such that the multiplicity of knot
is equal the spline's order. If spline
!= split
, the internal state of spline
is not modified, that is, split
is a new, independent tsBSpline instance.
[in]  spline  The spline to be split. 
[in]  knot  The split point (knot). 
[out]  split  The split spline. 
[out]  k  Stores the last index of knot in split . 
[out]  status  The status of this function. May be NULL. 
spline
is not defined at knot
. tsError TINYSPLINE_API ts_bspline_sub_spline  (  const tsBSpline *  spline, 
tsReal  knot0,  
tsReal  knot1,  
tsBSpline *  sub,  
tsStatus *  status  
) 
Extracts a subspline from spline
with respect to the given domain [knot0, knot1]
. The knots knot0
and knot1
must lie within the domain of spline
and must not be equal according to ts_knots_equal. However, knot0
can be greater than knot1
. In this case, the control points of the subspline are reversed.
[in]  spline  The spline to query. 
[in]  knot0  Lower bound of the domain of the queried subspline if knot0 is less than knot1 . Upper bound otherwise. 
[in]  knot1  Upper bound of the domain of the queried subspline if knot1 is greater than knot0 . Lower bound otherwise. 
[out]  sub  The queried subspline. 
[out]  status  The status of this function. May be NULL. 
spline
is not defined at knot0
or knot1
. knot0
and knot1
are equal according to ts_knots_equal. tsError TINYSPLINE_API ts_bspline_tension  (  const tsBSpline *  spline, 
tsReal  beta,  
tsBSpline *  out,  
tsStatus *  status  
) 
Straightens the control points of spline
according to beta
(0 yields a line connecting the first and the last control point; 1 keeps the original shape). The value of beta
is clamped to [0, 1]. If spline
!= out
, the internal state of spline
is not modified, that is, out
is a new, independent tsBSpline instance.
This function is based on:
@ARTICLE{10.1109/TVCG.2006.147, author = {Holten, Danny}, journal = {IEEE Transactions on Visualization and Computer Graphics}, title = {Hierarchical Edge Bundles: Visualization of Adjacency Relations in Hierarchical Data}, year = {2006}, volume = {12}, number = {5}, pages = {741748}, abstract = {A compound graph is a frequently encountered type of data set. Relations are given between items, and a hierarchy is defined on the items as well. We present a new method for visualizing such compound graphs. Our approach is based on visually bundling the adjacency edges, i.e., nonhierarchical edges, together. We realize this as follows. We assume that the hierarchy is shown via a standard tree visualization method. Next, we bend each adjacency edge, modeled as a Bspline curve, toward the polyline defined by the path via the inclusion edges from one node to another. This hierarchical bundling reduces visual clutter and also visualizes implicit adjacency edges between parent nodes that are the result of explicit adjacency edges between their respective child nodes. Furthermore, hierarchical edge bundling is a generic method which can be used in conjunction with existing tree visualization techniques. We illustrate our technique by providing example visualizations and discuss the results based on an informal evaluation provided by potential users of such visualizations.}, keywords = {}, doi = {10.1109/TVCG.2006.147}, ISSN = {19410506}, month = {Sep.}, }
Holten calls it "straightening" (page 744, equation 1).
[in]  spline  The spline to be straightened. 
[in]  beta  The straightening factor. The value is clamped to the domain [0, 1]. 
[out]  out  The straightened spline. 
[out]  status  The status of this function. May be NULL. 
< The straightening factor.
< Pointer to the control points of ‘out’.
< Used in for loops.
< Straightening vector.
tsError TINYSPLINE_API ts_bspline_to_beziers  (  const tsBSpline *  spline, 
tsBSpline *  beziers,  
tsStatus *  status  
) 
Decomposes spline
into a sequence of Bezier curves by splitting it at each internal knot. If spline
!= beziers
, the internal state of spline
is not modified, that is, beziers
is a new, independent tsBSpline instance.
[in]  spline  The spline to be decomposed. 
[out]  beziers  The bezier decomposition of spline . 
[out]  status  The status of this function. May be NULL. 
< Number of control points to add/remove.
< Index of the split knot value.
< Minimum of the knot values.
< Maximum of the knot values.
< Temporarily stores the result.
< Pointer to the knots of tmp.
< Number of knots in tmp.
tsError TINYSPLINE_API ts_bspline_to_json  (  const tsBSpline *  spline, 
char **  json,  
tsStatus *  status  
) 
Serializes spline
to a nullterminated JSON string and stores the result in json
.
[in]  spline  The spline to be serialized. 
[out]  json  The serialized JSON string. 
[out]  status  The status of this function. May be NULL. 
void TINYSPLINE_API ts_bspline_uniform_knot_seq  (  const tsBSpline *  spline, 
size_t  num,  
tsReal *  knots  
) 
Generates a sequence of num
knots with uniform distribution. Uniform means that consecutive knots in knots
have the same distance.
[in]  spline  The spline to query. 
[in]  num  Number of knots in knots . 
[out]  knots  Stores the generated knot sequence. 
tsError TINYSPLINE_API ts_chord_lengths_equidistant_knot_seq  (  const tsReal *  knots, 
const tsReal *  lengths,  
size_t  num,  
size_t  num_knot_seq,  
tsReal *  knot_seq,  
tsStatus *  status  
) 
Generates a sequence of num_knot_seq
knots with equidistant distribution. Equidistant means that the points evaluated from consecutive knots in knot_seq
have the same distance along the spline. This is also known as 'reparametrization by arc length'.
lengths
is monotonically increasing and contains only nonnegative values (distances cannot be negative). [in]  knots  Knots that were passed to ts_bspline_chord_lengths. 
[in]  lengths  Cumulative chord lengths as computed by ts_bspline_chord_lengths. 
[in]  num  Number of values in knots and lengths . 
[in]  num_knot_seq  Number of knots in knot_seq . 
[out]  knot_seq  Stores the generated knot sequence. 
[out]  status  The status of this function. May be NULL. 
num
is 0
. tsError TINYSPLINE_API ts_chord_lengths_length_to_knot  (  const tsReal *  knots, 
const tsReal *  lengths,  
size_t  num,  
tsReal  len,  
tsReal *  knot,  
tsStatus *  status  
) 
Maps len
to a knot, k
, such that ts_bspline_eval(..., k ...)
yields a point whose length, with respect to knots[0]
, is close to len
. Note that len
is clamped to the domain of lengths
. The domain of the result, knot
, is [knots[0], knots[num1]]
.
The precision of the mapping depends on the resolution of knots
and lengths
. That is, the more chord lengths were computed, the more precise the lengthtoknotmapping becomes. Generally, 200
chord lengths yields a quite precise mapping (subpixel accuracy). For very, very high precision requirements, 500
chord lengths should be sufficient.
Returns TS_NO_RESULT if num
is 0
.
lengths
is monotonically increasing and contains only nonnegative values (distances cannot be negative). [in]  knots  Knots that were passed to ts_bspline_chord_lengths. 
[in]  lengths  Cumulative chord lengths as computed by ts_bspline_chord_lengths. 
[in]  num  Number of values in knots and lengths . 
[in]  len  Length to be mapped. Clamped to the domain of lengths . 
[out]  knot  A knot, such that ts_bspline_eval(..., knot ...) yields a point whose length, with respect to knots[0] , is close to len . 
[out]  status  The status of this function. May be NULL. 
num
is 0
. tsError TINYSPLINE_API ts_chord_lengths_t_to_knot  (  const tsReal *  knots, 
const tsReal *  lengths,  
size_t  num,  
tsReal  t,  
tsReal *  knot,  
tsStatus *  status  
) 
Same as ts_chord_lengths_length_to_knot, except that this function takes a chord length parameter, t
, with domain [0, 1] (clamped), which indicates the to be evaluated relative proportion of the total length (lengths[num1]
).
lengths
is monotonically increasing and contains only nonnegative values (distances cannot be negative). [in]  knots  Knots that were passed to ts_bspline_chord_lengths. 
[in]  lengths  Cumulative chord lengths as computed by ts_bspline_chord_lengths. 
[in]  num  Number of values in knots and lengths . 
[in]  t  Chord length parameter (relative proportion of the total length). Clamped to the domain [0, 1]. 
[out]  knot  A knot, such that ts_bspline_eval(..., knot ...) yields a point whose length, with respect to knots[0] , is close to t * lengths[num1] 
[out]  status 

TS_SUCCESS On success.
TS_NO_RESULT If num
is 0
.
tsError TINYSPLINE_API ts_deboornet_copy  (  const tsDeBoorNet *  src, 
tsDeBoorNet *  dest,  
tsStatus *  status  
) 
Creates a deep copy of src
and stores the copied data in dest
. src
and dest
can be the same instance.
Note: Unlike memcpy and memmove, the first parameter is the source and the second parameter is the destination.
[in]  src  The net to be deep copied. 
[out]  dest  The output net. 
[out]  status  The status of this function. May be NULL. 
size_t TINYSPLINE_API ts_deboornet_dimension  (  const tsDeBoorNet *  net  ) 
Returns the dimensionality of net
, that is, the number of components of its points (ts_deboornet_points) and result (ts_deboornet_result). Onedimensional nets are possible, albeit their benefit might be questionable.
[in]  net  The net whose dimension is read. 
net
(>= 1). void TINYSPLINE_API ts_deboornet_free  (  tsDeBoorNet *  net  ) 
Releases the data of net
. After calling this function, the data of net
points to NULL.
[out]  net  The net to be released. 
size_t TINYSPLINE_API ts_deboornet_index  (  const tsDeBoorNet *  net  ) 
Returns the index of the knot of net
.
[in]  net  The net whose index is read. 
u
being the knot of net
. tsDeBoorNet TINYSPLINE_API ts_deboornet_init  (  void  ) 
Creates a new net whose data points to NULL.
tsReal TINYSPLINE_API ts_deboornet_knot  (  const tsDeBoorNet *  net  ) 
Returns the knot (sometimes also referred to as u
or t
) of net
.
[in]  net  The net whose knot is read. 
net
. size_t TINYSPLINE_API ts_deboornet_len_points  (  const tsDeBoorNet *  net  ) 
Returns the length of the point array of net
.
[in]  net  The net whose length of the point array is read. 
net
. size_t TINYSPLINE_API ts_deboornet_len_result  (  const tsDeBoorNet *  net  ) 
Returns the length of the result array of net
.
[in]  net  The net whose length of the result array is read. 
net
. void TINYSPLINE_API ts_deboornet_move  (  tsDeBoorNet *  src, 
tsDeBoorNet *  dest  
) 
Moves the ownership of the data of src
to dest
. After calling this function, the data of src
points to NULL. Does not release the data of dest
. src
and dest
can be the same instance (in this case, the data of src
remains).
[out]  src  The net whose data is moved to dest . 
[out]  dest  The net that receives the data of src . 
size_t TINYSPLINE_API ts_deboornet_multiplicity  (  const tsDeBoorNet *  net  ) 
Returns the multiplicity of the knot of net
.
[in]  net  The net whose multiplicity is read. 
net
. size_t TINYSPLINE_API ts_deboornet_num_insertions  (  const tsDeBoorNet *  net  ) 
Returns the number of insertion that were necessary to evaluate the knot of net
.
[in]  net  The net whose number of insertions of its knot is read. 
net
. size_t TINYSPLINE_API ts_deboornet_num_points  (  const tsDeBoorNet *  net  ) 
Returns the number of points of net
.
[in]  net  The net whose number of points is read. 
net
. size_t TINYSPLINE_API ts_deboornet_num_result  (  const tsDeBoorNet *  net  ) 
Returns the number of points in the result array of net
(1 <= num_result <= 2).
[in]  net  The net whose number of points in the result array is read. 
net
. tsError TINYSPLINE_API ts_deboornet_points  (  const tsDeBoorNet *  net, 
tsReal **  points,  
tsStatus *  status  
) 
Returns a deep copy of the points of net
.
[in]  net  The net whose points are read. 
[out]  points  The output array. Note: It is the responsibility of the client to release the allocated memory after use. 
[out]  status  The status of this function. May be NULL. 
const tsReal TINYSPLINE_API* ts_deboornet_points_ptr  (  const tsDeBoorNet *  net  ) 
Returns the pointer to the point array of net
. Note that the return type of this function is const
for a reason. Clients should only read the returned array. When suppressing the constness and writing to the array against better knowledge, the client is on its own with regard to the consistency of the internal state of net
. To obtain a copy of the points of net
, use ts_deboornet_points.
[in]  net  The net whose pointer to the point array is returned. 
net
. tsError TINYSPLINE_API ts_deboornet_result  (  const tsDeBoorNet *  net, 
tsReal **  result,  
tsStatus *  status  
) 
Returns a deep copy of the result of net
.
[in]  net  The net whose result is read. 
[out]  result  The output array. Note: It is the responsibility of the client to release the allocated memory after use. 
[out]  status  The status of this function. May be NULL. 
const tsReal TINYSPLINE_API* ts_deboornet_result_ptr  (  const tsDeBoorNet *  net  ) 
Returns the pointer to the result array of net
. Note that the return type of this function is const
for a reason. Clients should only read the returned array. When suppressing the constness and writing to the array against better knowledge, the client is on its own with regard to the consistency of the internal state of net
. To obtain a copy of the result of net
, use ts_deboornet_result.
[in]  net  The net whose pointer to the result array is returned. 
net
. size_t TINYSPLINE_API ts_deboornet_sof_points  (  const tsDeBoorNet *  net  ) 
Returns the size of the point array of net
. This function may be useful when copying points using memcpy or memmove.
[in]  net  The net whose size of the point array is read. 
net
. size_t TINYSPLINE_API ts_deboornet_sof_result  (  const tsDeBoorNet *  net  ) 
Returns the size of the result array of net
. This function may be useful when copying results using memcpy or memmove.
[in]  net  The net whose size of the result array is read. 
net
. Returns the euclidean distance of the points x
and y
.
[in]  x  First point. 
[in]  y  Second point. 
[in]  dim  Dimensionality of x and y . 
x
and y
. Returns whether the knots x
and y
are equal with respect to the epsilon environment TS_KNOT_EPSILON (i.e., their distance is less than TS_KNOT_EPSILON).
[in]  x  First knot. 
[in]  y  Second knot. 
x
and y
are equal. x
and y
are not equal. Initializes vector out
with x
and y
.
out
has dimensionality 2
. [out]  out  Target vector. 
[in]  x  The x value. 
[in]  y  The y value. 
Copies the values of vector x
(a vector with dimensionality dim
) to vector out
(a vector with dimensionality 2
). If dim
is less than 2
, the remaining values of out
are set to 0
. Excess values in x
(i.e., dim
is greater than 2
) are ignored.
out
has dimensionality 2
. [out]  out  Target vector. 
[in]  x  Vector to read the values from. 
[in]  dim  Dimensionality of x . 
Computes the cross product (also known as vector product or directed area product) of the vectors x
and y
.
x
and y
have dimensionality 3
. [in]  x  First vector. 
[in]  y  Second vector. 
[out]  out  Result vector. Can be same as x or y , i.e., the result can be stored inplace. 
Initializes vector out
with x
, y
, and z
.
out
has dimensionality 3
. [out]  out  Target vector. 
[in]  x  The x value. 
[in]  y  The y value. 
[in]  z  The z value. 
Copies the values of vector x
(a vector with dimensionality dim
) to vector out
(a vector with dimensionality 3
). If dim
is less than 3
, the remaining values of out
are set to 0
. Excess values in x
(i.e., dim
is greater than 3
) are ignored.
out
has dimensionality 3
. [out]  out  Target vector. 
[in]  x  Vector to read the values from. 
[in]  dim  Dimensionality of x . 
Initializes vector out
with x
, y
, z
, and w
.
out
has dimensionality 4
. [out]  out  Target vector. 
[in]  x  The x value. 
[in]  y  The y value. 
[in]  z  The z value. 
[in]  w  The w value. 
Copies the values of vector x
(a vector with dimensionality dim
) to vector out
(a vector with dimensionality 4
). If dim
is less than 4
, the remaining values of out
are set to 0
. Excess values in x
(i.e., dim
is greater than 4
) are ignored.
out
has dimensionality 4
. [out]  out  Target vector. 
[in]  x  Vector to read the values from. 
[in]  dim  Dimensionality of x . 
Adds vector y
to vector x
and stores the result in vector out
.
[in]  x  First vector. 
[in]  y  Second vector. 
[in]  dim  Dimensionality of x , y , and out . 
[out]  out  Result vector. Can be same as x or y , i.e., the result can be stored inplace. 
Computes the angle in degrees between the vectors x
and y
. The angle returned is unsigned, that is, the smaller of the two possible angles is computed. The nullable parameter buf
servers as a buffer in case x
or y
(or both) are not normalized. If buf
is NULL
, it is expected that x
and y
are already normalized. If buf
is not NULL
, a storage twice the size of dim
is expected in which the normalized vectors of x
and y
are stored.
buf
is either NULL
or has length 2 * dim
. [in]  x  First vector. 
[in]  y  Second vector. 
[out]  buf  A buffer in which the normalized vectors of x and \y are stored. If NULL , it is expected that x and y are already normalized. 
[in]  dim  Dimensionality of x and y . 
x
and \y with 0.0 <= angle <= 180.0
. Computes the dot product (also known as scalar product) of the vectors x
and y
.
0
if dim
is 0
. [in]  x  First vector. 
[in]  y  Second vector. 
[in]  dim  Dimensionality of x and y . 
x
and \y. Determines the length of vector x
.
0
if dim
is 0
. [in]  x  A vector. 
[in]  dim  Dimensionality of x . 
Multiplies vector x
with scalar val
and stores the result in vector out
.
[in]  x  A vector. 
[in]  dim  Dimensionality of x . 
[in]  val  Scalar value. 
[out]  out  Result vector. Can be same as x , i.e., the result can be stored inplace. 
Normalizes vector x
.
0
if the length of x
(see ts_vec_mag) is less than TS_LENGTH_ZERO. [in]  x  A vector. 
[in]  dim  Dimensionality of x . 
[out]  out  Result vector. Can be same as x , i.e., the result can be stored inplace. 
Subtracts vector y
from vector x
and stores the result in vector out
.
[in]  x  First vector. 
[in]  y  Second vector. 
[in]  dim  Dimensionality of x , y , and out . 
[out]  out  Result vector. Can be same as x or y , i.e., the result can be stored inplace. 