fn update_segs(&mut self) {
        let n_seg = self.segments.len();
        let mut th_ix = 0;
        for i in 0..n_seg {
            if let Element::SplineTo(p1, p2, p3, _is_smooth) = self.elements[i + 1] {
                if p1.is_some() && p2.is_some() {
                    // All parameters already determined from given points.
                    continue;
                }
                let p0 = self.segments[i].p0;
                let v = p3 - p0;
                let a = Affine::new([v.x, v.y, -v.y, v.x, p0.x, p0.y]);
                let a_inv = a.inverse();
                let chord_th = v.atan2();
                let (th0, bias0) = if let Some(p1) = p1 {
                    let v0 = (a_inv * p1).to_vec2();
                    let (th0, bias0) = HyperBezier::params_for_v(v0);
                    (Some(th0), Some(bias0))
                } else {
                    match self.prev_el(i + 1) {
                        Some(Element::SplineTo(_, None, _, _)) => {
                            let th0 = util::mod_tau(self.ths[th_ix] - chord_th);
                            th_ix = (th_ix + 1) % self.ths.len();
                            (Some(th0), None)
                        }
                        Some(Element::SplineTo(_, Some(p2), _, _)) => {
                            let prev_ch_th = (p0 - *p2).atan2();
                            let th0 = util::mod_tau(prev_ch_th - chord_th);
                            (Some(th0), Some(self.segments[i].hb.bias0))
                        }
                        Some(Element::LineTo(..)) => {
                            let prev_seg = &self.segments[(i + n_seg - 1) % n_seg];
                            let prev_ch_th = prev_seg.chord().atan2();
                            let th0 = util::mod_tau(prev_ch_th - chord_th);
                            (Some(th0), Some(0.0))
                        }
                        _ => (None, None),
                    }
                };
                let (th1, bias1) = if let Some(p2) = p2 {
                    let v1 = Point::new(1.0, 0.0) - (a_inv * p2);
                    let (th1, bias1) = HyperBezier::params_for_v(v1);
                    (Some(-th1), Some(bias1))
                } else {
                    match self.next_el(i + 1) {
                        Some(Element::SplineTo(None, _, _, _)) => {
                            let th1 = util::mod_tau(chord_th - self.ths[th_ix]);
                            (Some(th1), None)
                        }
                        Some(Element::SplineTo(Some(p1), _, _, _)) => {
                            let next_ch_th = (*p1 - p3).atan2();
                            let th1 = util::mod_tau(chord_th - next_ch_th);
                            (Some(th1), Some(self.segments[i].hb.bias1))
                        }
                        Some(Element::LineTo(p1, _)) => {
                            let next_ch_th = (*p1 - p3).atan2();
                            let th1 = util::mod_tau(chord_th - next_ch_th);
                            (Some(th1), Some(0.0))
                        }
                        _ => (None, None),
                    }
                };
                let (th0, th1) = match (th0, th1) {
                    (Some(th0), Some(th1)) => (th0, th1),
                    (Some(th0), None) => (th0, simple_spline::endpoint_tangent(th0)),
                    (None, Some(th1)) => (simple_spline::endpoint_tangent(th1), th1),
                    (None, None) => continue,
                };
                let bias0 = bias0.unwrap_or_else(|| simple_spline::bias_for_theta(th0));
                let bias1 = bias1.unwrap_or_else(|| simple_spline::bias_for_theta(th1));
                let params = ThetaParams {
                    th0: -th0,
                    bias0,
                    th1: -th1,
                    bias1,
                };
                let hb = HyperBezier::solve_for_theta(&params);
                self.segments[i] = Segment::make(p0, p1, p2, p3, th0, th1, hb);
            }
        }
    }
/// Generate segments from the spline spec and thetas.
Generate segments from the spline spec and thetas.
Generate segments from the spline spec and thetas .
fn update_segs(&mut self) {
        let n_seg = self.segments.len();
        let mut th_ix = 0;
        for i in 0..n_seg {
            if let Element::SplineTo(p1, p2, p3, _is_smooth) = self.elements[i + 1] {
                if p1.is_some() && p2.is_some() {
                    // All parameters already determined from given points.
                    continue;
                }
                let p0 = self.segments[i].p0;
                let v = p3 - p0;
                let a = Affine::new([v.x, v.y, -v.y, v.x, p0.x, p0.y]);
                let a_inv = a.inverse();
                let chord_th = v.atan2();
                let (th0, bias0) = if let Some(p1) = p1 {
                    let v0 = (a_inv * p1).to_vec2();
                    let (th0, bias0) = HyperBezier::params_for_v(v0);
                    (Some(th0), Some(bias0))
                } else {
                    match self.prev_el(i + 1) {
                        Some(Element::SplineTo(_, None, _, _)) => {
                            let th0 = util::mod_tau(self.ths[th_ix] - chord_th);
                            th_ix = (th_ix + 1) % self.ths.len();
                            (Some(th0), None)
                        }
                        Some(Element::SplineTo(_, Some(p2), _, _)) => {
                            let prev_ch_th = (p0 - *p2).atan2();
                            let th0 = util::mod_tau(prev_ch_th - chord_th);
                            (Some(th0), Some(self.segments[i].hb.bias0))
                        }
                        Some(Element::LineTo(..)) => {
                            let prev_seg = &self.segments[(i + n_seg - 1) % n_seg];
                            let prev_ch_th = prev_seg.chord().atan2();
                            let th0 = util::mod_tau(prev_ch_th - chord_th);
                            (Some(th0), Some(0.0))
                        }
                        _ => (None, None),
                    }
                };
                let (th1, bias1) = if let Some(p2) = p2 {
                    let v1 = Point::new(1.0, 0.0) - (a_inv * p2);
                    let (th1, bias1) = HyperBezier::params_for_v(v1);
                    (Some(-th1), Some(bias1))
                } else {
                    match self.next_el(i + 1) {
                        Some(Element::SplineTo(None, _, _, _)) => {
                            let th1 = util::mod_tau(chord_th - self.ths[th_ix]);
                            (Some(th1), None)
                        }
                        Some(Element::SplineTo(Some(p1), _, _, _)) => {
                            let next_ch_th = (*p1 - p3).atan2();
                            let th1 = util::mod_tau(chord_th - next_ch_th);
                            (Some(th1), Some(self.segments[i].hb.bias1))
                        }
                        Some(Element::LineTo(p1, _)) => {
                            let next_ch_th = (*p1 - p3).atan2();
                            let th1 = util::mod_tau(chord_th - next_ch_th);
                            (Some(th1), Some(0.0))
                        }
                        _ => (None, None),
                    }
                };
                let (th0, th1) = match (th0, th1) {
                    (Some(th0), Some(th1)) => (th0, th1),
                    (Some(th0), None) => (th0, simple_spline::endpoint_tangent(th0)),
                    (None, Some(th1)) => (simple_spline::endpoint_tangent(th1), th1),
                    (None, None) => continue,
                };
                let bias0 = bias0.unwrap_or_else(|| simple_spline::bias_for_theta(th0));
                let bias1 = bias1.unwrap_or_else(|| simple_spline::bias_for_theta(th1));
                let params = ThetaParams {
                    th0: -th0,
                    bias0,
                    th1: -th1,
                    bias1,
                };
                let hb = HyperBezier::solve_for_theta(&params);
                self.segments[i] = Segment::make(p0, p1, p2, p3, th0, th1, hb);
            }
        }
    }
fn update_segs ( & mut self ) { let n_seg = self . segments . len ( ) ; let mut th_ix = 0 ; for i in 0 .. n_seg { if let Element :: SplineTo ( p1 , p2 , p3 , _is_smooth ) = self . elements [ i + 1 ] { if p1 . is_some ( ) && p2 . is_some ( ) { // All parameters already determined from given points. continue ; } let p0 = self . segments [ i ] . p0 ; let v = p3 - p0 ; let a = Affine :: new ( [ v . x , v . y , - v . y , v . x , p0 . x , p0 . y ] ) ; let a_inv = a . inverse ( ) ; let chord_th = v . atan2 ( ) ; let ( th0 , bias0 ) = if let Some ( p1 ) = p1 { let v0 = ( a_inv * p1 ) . to_vec2 ( ) ; let ( th0 , bias0 ) = HyperBezier :: params_for_v ( v0 ) ; ( Some ( th0 ) , Some ( bias0 ) ) } else { match self . prev_el ( i + 1 ) { Some ( Element :: SplineTo ( _ , None , _ , _ ) ) => { let th0 = util :: mod_tau ( self . ths [ th_ix ] - chord_th ) ; th_ix = ( th_ix + 1 ) % self . ths . len ( ) ; ( Some ( th0 ) , None ) } Some ( Element :: SplineTo ( _ , Some ( p2 ) , _ , _ ) ) => { let prev_ch_th = ( p0 - * p2 ) . atan2 ( ) ; let th0 = util :: mod_tau ( prev_ch_th - chord_th ) ; ( Some ( th0 ) , Some ( self . segments [ i ] . hb . bias0 ) ) } Some ( Element :: LineTo ( .. ) ) => { let prev_seg = & self . segments [ ( i + n_seg - 1 ) % n_seg ] ; let prev_ch_th = prev_seg . chord ( ) . atan2 ( ) ; let th0 = util :: mod_tau ( prev_ch_th - chord_th ) ; ( Some ( th0 ) , Some ( 0.0 ) ) } _ => ( None , None ) , } } ; let ( th1 , bias1 ) = if let Some ( p2 ) = p2 { let v1 = Point :: new ( 1.0 , 0.0 ) - ( a_inv * p2 ) ; let ( th1 , bias1 ) = HyperBezier :: params_for_v ( v1 ) ; ( Some ( - th1 ) , Some ( bias1 ) ) } else { match self . next_el ( i + 1 ) { Some ( Element :: SplineTo ( None , _ , _ , _ ) ) => { let th1 = util :: mod_tau ( chord_th - self . ths [ th_ix ] ) ; ( Some ( th1 ) , None ) } Some ( Element :: SplineTo ( Some ( p1 ) , _ , _ , _ ) ) => { let next_ch_th = ( * p1 - p3 ) . atan2 ( ) ; let th1 = util :: mod_tau ( chord_th - next_ch_th ) ; ( Some ( th1 ) , Some ( self . segments [ i ] . hb . bias1 ) ) } Some ( Element :: LineTo ( p1 , _ ) ) => { let next_ch_th = ( * p1 - p3 ) . atan2 ( ) ; let th1 = util :: mod_tau ( chord_th - next_ch_th ) ; ( Some ( th1 ) , Some ( 0.0 ) ) } _ => ( None , None ) , } } ; let ( th0 , th1 ) = match ( th0 , th1 ) { ( Some ( th0 ) , Some ( th1 ) ) => ( th0 , th1 ) , ( Some ( th0 ) , None ) => ( th0 , simple_spline :: endpoint_tangent ( th0 ) ) , ( None , Some ( th1 ) ) => ( simple_spline :: endpoint_tangent ( th1 ) , th1 ) , ( None , None ) => continue , } ; let bias0 = bias0 . unwrap_or_else ( | | simple_spline :: bias_for_theta ( th0 ) ) ; let bias1 = bias1 . unwrap_or_else ( | | simple_spline :: bias_for_theta ( th1 ) ) ; let params = ThetaParams { th0 : - th0 , bias0 , th1 : - th1 , bias1 , } ; let hb = HyperBezier :: solve_for_theta ( & params ) ; self . segments [ i ] = Segment :: make ( p0 , p1 , p2 , p3 , th0 , th1 , hb ) ; } } }
Generate segments from the spline spec and thetas.
Generate segments from the spline spec and thetas .
&mut self
&mut self