1 use std::convert::{AsRef, AsMut, From};
2 use std::cell::{Cell, RefCell};
3 use std::marker::PhantomData;
4 use std::fmt::{Debug, Formatter};
5 use std::ops::Range;
6 
7 
8 use super::{BezCurve, Point2d, Float, Point, lerp};
9 
10 /// A struct that contains range information for slicing, used for slicing into the global factor
11 /// vector. The reason this is used instead of stdlib's `Range` struct is that `Range` does not
12 /// implement Copy, which means we have to use `RefCell`s instead of `Cell`s for interior mutability.
13 #[derive(Copy, Clone)]
14 struct RangeSlice {
15     start: usize,
16     end: usize
17 }
18 
19 impl RangeSlice {
20     #[inline]
new(start: usize, end: usize) -> RangeSlice21     fn new(start: usize, end: usize) -> RangeSlice {
22         RangeSlice {
23             start: start,
24             end: end
25         }
26     }
27 
as_range(&self) -> Range<usize>28     fn as_range(&self) -> Range<usize> {
29         self.start..self.end
30     }
31 
len(&self) -> usize32     fn len(&self) -> usize {
33         self.end - self.start
34     }
35 }
36 
combination(n: u64, k: u64) -> u6437 fn combination(n: u64, k: u64) -> u64 {
38     factorial(n) / (factorial(k) * factorial(n - k))
39 }
40 
factorial(mut n: u64) -> u6441 fn factorial(mut n: u64) -> u64 {
42     let mut accumulator: u64 = 1;
43     while n > 0 {
44         accumulator = accumulator.checked_mul(n).expect("Attempted to create Bézier curve with combination that overflow u64; decrease curve order");
45         n -= 1;
46     }
47     accumulator
48 }
49 
50 /// Given the `order` and references to the `factors`, `dfactors`, and `vec` cells, update the
51 /// cells to contain accurate information about the factors of the order.
update_factors(order: usize, factors: &Cell<RangeSlice>, dfactors: &Cell<RangeSlice>, vec: &RefCell<Vec<u64>>)52 fn update_factors(order: usize, factors: &Cell<RangeSlice>, dfactors: &Cell<RangeSlice>, vec: &RefCell<Vec<u64>>) {
53     if factors.get().len() != order + 1 {
54         let mut vec = vec.borrow_mut();
55         // Remove everything from the vector without freeing memory
56         unsafe{ vec.set_len(0) };
57 
58         // The vector stores both the factors of the order and the order's derivative, and this is the
59         // length necessary to contain those factors.
60         let new_len = (order + 1) * 2 - 1;
61         if vec.capacity() < new_len {
62             let reserve_amount = new_len - vec.capacity();
63             vec.reserve(reserve_amount);
64         }
65 
66         {
67             let order = order as u64;
68 
69             for k in 0..order + 1 {
70                 vec.push(combination(order, k));
71             }
72 
73             for k in 0..order {
74                 vec.push(combination(order - 1, k));
75             }
76         }
77 
78         factors.set(RangeSlice::new(0, order + 1));
79         dfactors.set(RangeSlice::new(order + 1, vec.len()));
80     }
81 }
82 
83 
84 /// An n-order bezier curve. The `from_slice`, `split`, and `split_unbounded` functions currently do not work.
85 #[derive(Clone)]
86 pub struct NBez<F, P = Point2d<F>, C = Vec<P>>
87         where F: Float,
88               P: Point<F>,
89               C: AsRef<[P]> + AsMut<[P]> {
90     points: C,
91     factor_vec: RefCell<Vec<u64>>,
92     factors: Cell<RangeSlice>,
93     dfactors: Cell<RangeSlice>,
94     phantom: PhantomData<(F, P)>
95 }
96 
97 impl<F, P, C> From<C> for NBez<F, P, C>
98         where F: Float,
99               P: Point<F>,
100               C: AsRef<[P]> + AsMut<[P]> {
from(container: C) -> NBez<F, P, C>101     fn from(container: C) -> NBez<F, P, C> {
102         NBez::from_container(container)
103     }
104 }
105 
106 impl<F, P, C> NBez<F, P, C>
107         where F: Float,
108               P: Point<F>,
109               C: AsRef<[P]> + AsMut<[P]> {
110     #[inline]
from_container(points: C) -> NBez<F, P, C>111     pub fn from_container(points: C) -> NBez<F, P, C> {
112         if points.as_ref().len() >= 22 {
113             panic!("Cannot create Bézier polynomials with an order >= 21")
114         }
115 
116         NBez {
117             points: points,
118             factor_vec: RefCell::new(Vec::new()),
119             factors: Cell::new(RangeSlice::new(0, 0)),
120             dfactors: Cell::new(RangeSlice::new(0, 0)),
121             phantom: PhantomData
122         }
123     }
124 
125     #[inline]
unwrap(self) -> C126     pub fn unwrap(self) -> C {
127         self.points
128     }
129 }
130 
131 impl<F, P, C> BezCurve<F> for NBez<F, P, C>
132         where F: Float,
133               P: Point<F>,
134               C: AsRef<[P]> + AsMut<[P]> {
135     type Point = P;
136     type Elevated = NBez<F, P, Vec<P>>;
137 
138     /// Currently non-functional; returns `None`
from_slice(_: &[P]) -> Option<NBez<F, P, C>>139     fn from_slice(_: &[P]) -> Option<NBez<F, P, C>> {
140         None
141     }
142 
interp_unbounded(&self, t: F) -> P143     fn interp_unbounded(&self, t: F) -> P {
144         let points = self.points.as_ref();
145         update_factors(self.order(), &self.factors, &self.dfactors, &self.factor_vec);
146         let factors = &self.factor_vec.borrow()[self.factors.get().as_range()];
147 
148 
149         let t1 = F::from_f32(1.0).unwrap() - t;
150         let order = factors.len() - 1;
151         let mut acc = P::zero();
152         let mut factor = 0;
153 
154         for point in points.iter() {
155             acc = acc + *point *
156                         t.powi(factor as i32) *
157                         t1.powi((order - factor) as i32) *
158                         F::from_u64(factors[factor]).unwrap();
159             factor += 1;
160         }
161         acc
162     }
163 
slope_unbounded(&self, t: F) -> P::Vector164     fn slope_unbounded(&self, t: F) -> P::Vector {
165         let points = self.points.as_ref();
166         update_factors(self.order(), &self.factors, &self.dfactors, &self.factor_vec);
167         let dfactors = &self.factor_vec.borrow()[self.dfactors.get().as_range()];
168 
169         let t1 = F::from_f32(1.0).unwrap() - t;
170         let order = dfactors.len() - 1;
171         let mut acc = P::zero();
172         let mut factor = 0;
173         let mut point_last = points[0].clone();
174 
175         for point in points[1..].iter().map(|p| *p) {
176             acc = acc + (point - point_last) *
177                         t.powi(factor as i32) *
178                         t1.powi((order-factor) as i32) *
179                         F::from_u64(dfactors[factor] * (order + 1) as u64).unwrap();
180             point_last = point;
181             factor += 1;
182         }
183         acc.into()
184     }
185 
elevate(&self) -> NBez<F, P, Vec<P>>186     fn elevate(&self) -> NBez<F, P, Vec<P>> {
187         let points = self.points.as_ref();
188         let order = self.order() + 1;
189         let order_f = F::from_usize(order).unwrap();
190 
191         // Elevated points
192         let mut el_points = Vec::with_capacity(order + 1);
193         el_points.push(points[0]);
194 
195         let mut prev_p = points[0];
196         for (i, p) in points.iter().map(|p| *p).enumerate().skip(1) {
197             el_points.push(lerp(p, prev_p, F::from_usize(i).unwrap()/order_f));
198 
199             prev_p = p;
200         }
201 
202         el_points.push(points[self.order()]);
203         NBez::from_container(el_points)
204     }
205 
206     /// Currently non-functional; returns `None`
split(&self, _: F) -> Option<(NBez<F, P, C>, NBez<F, P, C>)>207     fn split(&self, _: F) -> Option<(NBez<F, P, C>, NBez<F, P, C>)> {
208         None
209     }
210 
211     /// Currently non-functional; panics with unimplemented
split_unbounded(&self, _: F) -> (NBez<F, P, C>, NBez<F, P, C>)212     fn split_unbounded(&self, _: F) -> (NBez<F, P, C>, NBez<F, P, C>) {
213         unimplemented!()
214     }
215 
order(&self) -> usize216     fn order(&self) -> usize {
217         self.points.as_ref().len()-1
218     }
219 }
220 
221 impl<F, P, C> AsRef<C> for NBez<F, P, C>
222         where F: Float,
223               P: Point<F>,
224               C: AsRef<[P]> + AsMut<[P]> {
as_ref(&self) -> &C225     fn as_ref(&self) -> &C {
226         &self.points
227     }
228 }
229 
230 impl<F, P, C> AsMut<C> for NBez<F, P, C>
231         where F: Float,
232               P: Point<F>,
233               C: AsRef<[P]> + AsMut<[P]> {
as_mut(&mut self) -> &mut C234     fn as_mut(&mut self) -> &mut C {
235         &mut self.points
236     }
237 }
238 
239 impl<F, P, C> AsRef<[P]> for NBez<F, P, C>
240         where F: Float,
241               P: Point<F>,
242               C: AsRef<[P]> + AsMut<[P]> {
as_ref(&self) -> &[P]243     fn as_ref(&self) -> &[P] {
244         self.points.as_ref()
245     }
246 }
247 
248 impl<F, P, C> AsMut<[P]> for NBez<F, P, C>
249         where F: Float,
250               P: Point<F>,
251               C: AsRef<[P]> + AsMut<[P]> {
as_mut(&mut self) -> &mut [P]252     fn as_mut(&mut self) -> &mut [P] {
253         self.points.as_mut()
254     }
255 }
256 
257 impl<F, P, C> Debug for NBez<F, P, C>
258         where F: Float,
259               P: Point<F>,
260               C: AsRef<[P]> + AsMut<[P]> + Debug {
fmt(&self, f: &mut Formatter) -> Result<(), ::std::fmt::Error>261     fn fmt(&self, f: &mut Formatter) -> Result<(), ::std::fmt::Error> {
262         f.debug_tuple("NBez")
263             .field(&self.points)
264             .finish()
265     }
266 }
267