utils for trap/clipping
This commit is contained in:
parent
fa3dc1d104
commit
ad9c8d6d37
1 changed files with 52 additions and 0 deletions
52
src/trap/utils.rs
Normal file
52
src/trap/utils.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
// GPT generated code is isolated to this file
|
||||
use geo::{Coordinate, Line, Point, Polygon, prelude::*};
|
||||
|
||||
///////////////////////
|
||||
// Clip filter related
|
||||
///////////////////////
|
||||
|
||||
// find distance of edge do point (used by GUI)
|
||||
pub fn point_to_segment_distance_squared(p: [f32; 2], a: [f32; 2], b: [f32; 2]) -> f32 {
|
||||
let ab = [b[0] - a[0], b[1] - a[1]];
|
||||
let ap = [p[0] - a[0], p[1] - a[1]];
|
||||
let ab_len_sq = ab[0] * ab[0] + ab[1] * ab[1];
|
||||
|
||||
if ab_len_sq == 0.0 {
|
||||
// Edge is a single point
|
||||
return ap[0] * ap[0] + ap[1] * ap[1];
|
||||
}
|
||||
|
||||
// Project point onto segment, clamped to [0,1]
|
||||
let t = ((ap[0] * ab[0] + ap[1] * ab[1]) / ab_len_sq).clamp(0.0, 1.0);
|
||||
let closest = [a[0] + t * ab[0], a[1] + t * ab[1]];
|
||||
|
||||
let dx = p[0] - closest[0];
|
||||
let dy = p[1] - closest[1];
|
||||
dx * dx + dy * dy
|
||||
}
|
||||
|
||||
|
||||
// find distance of edge do point (used by GUI)
|
||||
pub fn closest_edge(mask: &[[f32; 2]], target: [f32; 2]) -> Option<usize> {
|
||||
if mask.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut min_dist_sq = f32::MAX;
|
||||
let mut closest_edge_index = 0;
|
||||
|
||||
for i in 0..mask.len() {
|
||||
let a = mask[i];
|
||||
let b = mask[(i + 1) % mask.len()];
|
||||
let dist_sq = point_to_segment_distance_squared(target, a, b);
|
||||
|
||||
if dist_sq < min_dist_sq {
|
||||
min_dist_sq = dist_sq;
|
||||
closest_edge_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
Some(closest_edge_index)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue