Skip to content

Commit

Permalink
add some tests for line_split_many
Browse files Browse the repository at this point in the history
  • Loading branch information
thehappycheese committed Aug 9, 2023
1 parent 096e6f4 commit 9e2c5d6
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 36 deletions.
61 changes: 32 additions & 29 deletions geo/src/algorithm/line_split/line_split_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,55 +29,58 @@ where
/// This default implementation is inefficient because it uses repeated application of
/// the line_split function. Implementing types should override this with a more efficient
/// algorithm if possible.
fn line_split_many(&self, mut fractions: &Vec<Scalar>) -> Option<Vec<Self>> where Self: Clone {
fn line_split_many(&self, fractions: &Vec<Scalar>) -> Option<Vec<Option<Self>>>
where
Self: Clone,
{
match fractions.len() {
0 => None,
1 => self.line_split(fractions[0]).map(|item| {
let (a, b) = item.into_tuple();
vec![a, b]
}),
_ => {
let mut fractions:Vec<Scalar> = fractions
let mut fractions: Vec<Scalar> = fractions
.iter()
.map(|item| item.min(Scalar::one()).max(Scalar::zero()))
.collect();
fractions.sort_unstable();

if fractions.last().unwrap() != Scalar::one() {
fractions.push(Scalar::one());
} else{
return None;
}
fractions
.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
fractions.insert(0, Scalar::zero());
fractions.push(Scalar::one());
let fractions = fractions; // remove mutability
let output = Vec::new();
let mut remaining_self = self.clone();
// TODO handel case where fractions is len 1 or 0
let mut output: Vec<Option<Self>> = Vec::new();
let mut remaining_self = Some(self.clone());
for fraction in fractions.windows(2) {
if let &[a, b] = fraction {
let fraction_interval = b - a;
let fraction_to_end = Scalar::one() - a;
let next_fraction = fraction_interval / fraction_to_end;
remaining_self = match remaining_self.line_split(next_fraction) {
Some(LineSplitResult::FirstSecond(line1, line2)) => {
output.push(Some(line1));
line2
},
Some(LineSplitResult::First(line1))=>{
output.push(Some(line1));
break
},
Some(LineSplitResult::Second(_))=>{
output.push(None);
break
},
None=>break
let next_fraction = fraction_interval / fraction_to_end;
remaining_self = if let Some(remaining_self) = remaining_self {
match remaining_self.line_split(next_fraction) {
Some(LineSplitResult::FirstSecond(line1, line2)) => {
output.push(Some(line1));
Some(line2)
}
Some(LineSplitResult::First(line1)) => {
output.push(Some(line1));
None
}
Some(LineSplitResult::Second(_)) => {
output.push(None);
None
}
None => return None,
}
} else {
output.push(None);
None
}
}
}
output
Some(output)
}
}

}

/// Note on choice of return type:
Expand Down
61 changes: 54 additions & 7 deletions geo/src/algorithm/line_split/line_split_trait_impl_for_line.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use geo_types::{CoordFloat, Line};
use crate::Vector2DOps;
use super::{LineSplit, LineSplitResult};
use crate::Vector2DOps;
use geo_types::{CoordFloat, Line};

impl<Scalar> LineSplit<Scalar> for Line<Scalar>
where
Expand Down Expand Up @@ -179,12 +179,59 @@ mod test {
// =============================================================================================

#[test]
fn test_line_split_many(){
fn test_line_split_many() {
let line = Line::new(
coord!{x: 0.0_f32, y:0.0_f32},
coord!{x:10.0_f32, y:0.0_f32},
coord! {x: 0.0_f32, y:0.0_f32},
coord! {x:10.0_f32, y:0.0_f32},
);
let result = line.line_split_many(&vec![0.1, 0.2, 0.5]);
assert_eq!(
result,
Some(vec![
Some(Line::new(
coord! { x: 0.0, y: 0.0 },
coord! { x: 1.0, y: 0.0 },
)),
Some(Line::new(
coord! { x: 1.0, y: 0.0 },
coord! { x: 2.0, y: 0.0 },
)),
Some(Line::new(
coord! { x: 2.0, y: 0.0 },
coord! { x: 5.0, y: 0.0 },
)),
Some(Line::new(
coord! { x: 5.0, y: 0.0 },
coord! { x: 10.0, y: 0.0 },
))
])
);
}

#[test]
fn test_line_split_many_edge() {
let line = Line::new(
coord! {x: 0.0_f32, y:0.0_f32},
coord! {x:10.0_f32, y:0.0_f32},
);
let result = line.line_split_many(&vec![0.1, 0.2, 2.0]);
assert_eq!(
result,
Some(vec![
Some(Line::new(
coord! { x: 0.0, y: 0.0 },
coord! { x: 1.0, y: 0.0 },
)),
Some(Line::new(
coord! { x: 1.0, y: 0.0 },
coord! { x: 2.0, y: 0.0 },
)),
Some(Line::new(
coord! { x: 2.0, y: 0.0 },
coord! { x:10.0, y: 0.0 },
)),
None
])
);
let result = line.line_split_many(vec![0.1, 0.2, 0.5]).unwrap();
println!(result);
}
}

0 comments on commit 9e2c5d6

Please sign in to comment.