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
/*a Copyright

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@file    point.rs
@brief   Part of bezier library
 */

//a Imports
use geo_nd::{Float, Vector};
use crate::line::BezierLineIter;

//a BezierPointIter
//tp BezierPointIter
/// An iterator of points that form a single Bezier curve where the
/// steps between points would be lines that are 'straight enough'
///
/// This iterator returns the points that BezierLineIter uses, in the
/// same order (pa, pb, ...)
pub struct BezierPointIter<F:Float, V:Vector<F, D>, const D:usize> {
    /// A line iterator that returns the next line segment required;
    /// usually the first point of this segment that this iterator
    /// provides is returned as the next point.
    ///
    /// When this returns none, the end-point of the previous
    /// iteration needs to be returned as the last point.
    lines : BezierLineIter<F, V, D>,
    /// The last point to be returned - if this is valid then the line
    /// iterator has finished, and just the last point on the Bezier
    /// needs to be returned.
    last_point : Option<V>,
}

//ip BezierPointIter
impl <F, V, const D:usize> BezierPointIter<F, V, D>
where F:Float, V:Vector<F,D> {
    //fp new
    /// Create a new point iterator from a line iterator
    pub fn new(lines:BezierLineIter<F, V, D>) -> Self {
        Self { lines, last_point:None }
    }

    //zz All done
}

//ii BezierPointIter
impl <F, V, const D:usize> Iterator for BezierPointIter<F, V, D>
where F:Float, V:Vector<F,D> {
    /// Iterator returns Point's
    type Item = V;

    /// Return the first point of any line segment provided by the
    /// line iterator, but record the endpoint of that segment first;
    /// if the line iterator has finished then return any recorded
    /// endpoint, deleting it first.
    fn next(&mut self) -> Option<Self::Item> {
        if let Some( (p0, p1) ) = self.lines.next() {
            self.last_point = Some(p1);
            Some(p0)
        } else {
            let p = self.last_point;
            self.last_point = None;
            p
        }
    }

    //zz All done
}