1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

use std::env;

type size_t = usize;

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

#[cfg(test)]
mod tests {
    use crate::*;
    use std::ptr;
    use std::slice;
    const EPSILON: tsReal = 0.0001;
    #[test]
    fn interpolation() {
        // adapted from https://github.com/msteinbeck/tinyspline/blob/master/test/c/interpolation.c
        unsafe {
            let points: [tsReal; 10] = [
                 1.0,
                -1.0,
                -1.0,
                 2.0,
                 1.0,
                 4.0,
                 4.0,
                 3.0,
                 7.0,
                 5.0,
            ];
            let mut ctrlp: *mut tsReal = ptr::null_mut();
            let mut knots: *mut tsReal = ptr::null_mut();
            let mut spline = ts_bspline_init();
            let mut status = tsStatus {
                code: tsError_TS_SUCCESS,
                message: [0; 100]
            };
            ts_bspline_interpolate_cubic_natural(
                &points as *const tsReal, 5, 2,
                &mut spline as *mut tsBSpline,
                &mut status as *mut tsStatus
            );
            if status.code != tsError_TS_SUCCESS {
                panic!("Error on ts_bspline_interpolate_cubic_natural");
            }
            ts_bspline_control_points(
                &mut spline as *mut tsBSpline,
                &mut ctrlp as *mut *mut tsReal,
                &mut status as *mut tsStatus
            );
            if status.code != tsError_TS_SUCCESS {
                panic!("Error on ts_bspline_control_points");
            }
            let numpts = ts_bspline_num_control_points(&mut spline as *mut tsBSpline);
            if numpts != 16 {
                panic!("Number of control points does not equal 16 (got {})", numpts);
            }
            let target_points = [
                 1.0,
                -1.0,
                 0.0,
                 0.0,
                -1.0,
                 1.0,
                -1.0,
                 2.0,
                -1.0,
                 2.0,
                -1.0,
                 3.0,
                 0.0,
                 4.0,
                 1.0,
                 4.0,
                 1.0,
                 4.0,
                 2.0,
                 4.0,
                 3.0,
                 3.0,
                 4.0,
                 3.0,
                 4.0,
                 3.0,
                 5.0,
                 3.0,
                 6.0,
                 4.0,
                 7.0,
                 5.0
            ];
            let ctrlp = std::slice::from_raw_parts(ctrlp, 32);
            for (i, value) in target_points.iter().enumerate() {
                if (value - ctrlp[i]).abs() > EPSILON {
                    panic!("Mismatch control point at index {}: {}, {}", i, value, ctrlp[i]);
                }
            }
            ts_bspline_knots(
                &mut spline as *mut tsBSpline,
                &mut knots as *mut *mut tsReal,
                &mut status as *mut tsStatus
            );
            if status.code != tsError_TS_SUCCESS {
                panic!("Error on ts_bspline_knots");
            }
            let target_knots = [
                0.0, 
                0.0, 
                0.0, 
                0.0, 
                0.25,
                0.25,
                0.25,
                0.25,
                0.5, 
                0.5, 
                0.5, 
                0.5, 
                0.75,
                0.75,
                0.75,
                0.75,
                1.0, 
                1.0, 
                1.0, 
                1.0, 
            ];
            let knots = slice::from_raw_parts(knots, 20);
            for (i, value) in target_knots.iter().enumerate() {
                if (value - knots[i]).abs() > EPSILON {
                    panic!("Mismatch knot at index {}: {}, {}", i, value, ctrlp[i]);
                }
            }
            ts_bspline_free(&mut spline as *mut tsBSpline);
        }
    }
}