#![allow(dead_code)]
use std::fmt::Display;
use crate::prelude::*;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PVertex {
pub p: Point,
pub b: f64,
}
impl Display for PVertex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[{}, {}]", self.p, self.b)
}
}
impl PVertex {
#[inline]
pub fn new(p: Point, b: f64) -> Self {
PVertex { p, b }
}
}
#[inline]
pub fn pvertex(p: Point, b: f64) -> PVertex {
PVertex::new(p, b)
}
pub type Polyline = Vec<PVertex>;
#[must_use]
pub fn polyline_reverse(poly: &Polyline) -> Polyline {
if poly.is_empty() {
return Vec::new();
}
if poly.len() == 1 {
return vec![pvertex(poly[0].p, -poly[0].b)];
}
let last = match poly.last() {
Some(l) => l,
None => unreachable!("polyline_reverse: poly is empty, should be handled above"),
};
let mut reverse = poly.clone();
reverse.reverse();
let mut res: Polyline = Vec::with_capacity(poly.len());
for i in 0..reverse.len() - 1 {
let e = pvertex(reverse[i].p, -reverse[i + 1].b);
res.push(e);
}
let e = pvertex(match reverse.last() {
Some(v) => v.p,
None => unreachable!("polyline_reverse: reverse is empty, should be impossible here"),
}, -last.b);
res.push(e);
res
}
#[must_use]
pub fn polylines_reverse(poly: &Vec<Polyline>) -> Vec<Polyline> {
let mut res: Vec<Polyline> = Vec::with_capacity(poly.len());
for p in poly {
res.push(polyline_reverse(p));
}
res
}
#[must_use]
pub fn polyline_scale(poly: &Polyline, scale: f64) -> Polyline {
let mut res: Polyline = Vec::with_capacity(poly.len());
for e in poly {
let e = pvertex(e.p * scale, e.b);
res.push(e);
}
res
}
#[must_use]
pub fn polyline_translate(poly: &Polyline, translate: Point) -> Polyline {
let mut res: Polyline = Vec::with_capacity(poly.len());
for e in poly {
let e = pvertex(e.p + translate, e.b);
res.push(e);
}
res
}
#[cfg(test)]
mod test_pvertex {
use super::*;
use crate::point::point;
#[test]
fn test_new() {
let p0 = PVertex::new(point(1.0, 2.0), 5.5);
let p1 = pvertex(point(1.0, 2.0), 5.5);
assert_eq!(p0, p1);
}
#[test]
fn test_display() {
let p = pvertex(point(1.0, 2.0), 5.5);
assert_eq!(
"[[1.00000000000000000000, 2.00000000000000000000], 5.5]",
format!("{}", p)
);
}
#[test]
fn test_polylines_reverse() {
let poly1 = vec![
pvertex(point(0.0, 0.0), 0.5),
pvertex(point(1.0, 0.0), -0.3),
];
let poly2 = vec![pvertex(point(2.0, 2.0), 0.0), pvertex(point(3.0, 3.0), 0.2)];
let polylines = vec![poly1, poly2];
let reversed = polylines_reverse(&polylines);
assert_eq!(reversed.len(), 2);
assert_eq!(reversed[0].len(), 2);
assert_eq!(reversed[1].len(), 2);
}
#[test]
fn test_polyline_scale_edge_cases() {
let original = vec![pvertex(point(2.0, 3.0), 0.5)];
let scaled = polyline_scale(&original, 0.0);
assert_eq!(scaled[0].p, point(0.0, 0.0));
assert_eq!(scaled[0].b, 0.5);
let scaled_neg = polyline_scale(&original, -2.0);
assert_eq!(scaled_neg[0].p, point(-4.0, -6.0));
assert_eq!(scaled_neg[0].b, 0.5);
}
#[test]
fn test_polyline_translate_empty() {
let empty: Polyline = vec![];
let translated = polyline_translate(&empty, point(10.0, 5.0));
assert_eq!(translated.len(), 0);
}
#[test]
fn test_polyline_reverse_basic() {
let poly = vec![
pvertex(point(0.0, 0.0), 0.5),
pvertex(point(1.0, 0.0), -0.3),
pvertex(point(1.0, 1.0), 0.0),
];
let reversed = polyline_reverse(&poly);
assert_eq!(reversed.len(), poly.len());
assert_eq!(reversed[0].p, poly[2].p);
assert_eq!(reversed[1].p, poly[1].p);
assert_eq!(reversed[2].p, poly[0].p);
}
#[test]
fn test_polyline_reverse_bulge_negation() {
let poly = vec![
pvertex(point(0.0, 0.0), 0.5),
pvertex(point(1.0, 0.0), -0.3),
pvertex(point(1.0, 1.0), 0.7),
];
let reversed = polyline_reverse(&poly);
assert_eq!(reversed[0].b, -poly[1].b); assert_eq!(reversed[1].b, -poly[0].b); assert_eq!(reversed[2].b, -poly[2].b); }
#[test]
fn test_polyline_reverse_single_vertex() {
let poly = vec![pvertex(point(5.0, 5.0), 1.2)];
let reversed = polyline_reverse(&poly);
assert_eq!(reversed.len(), 1);
assert_eq!(reversed[0].p, poly[0].p);
assert_eq!(reversed[0].b, -poly[0].b);
}
#[test]
fn test_polyline_reverse_empty() {
let poly: Polyline = vec![];
let reversed = polyline_reverse(&poly);
assert_eq!(reversed.len(), 0);
assert_eq!(reversed, vec![]);
}
#[test]
fn test_polyline_reverse_all_zero_bulges() {
let poly = vec![
pvertex(point(0.0, 0.0), 0.0),
pvertex(point(1.0, 0.0), 0.0),
pvertex(point(1.0, 1.0), 0.0),
];
let reversed = polyline_reverse(&poly);
assert_eq!(reversed.len(), poly.len());
for v in reversed {
assert_eq!(v.b, 0.0);
}
}
}