partial test complete

This commit is contained in:
Henry Schimke
2023-04-24 17:42:40 -05:00
parent a811b56fbb
commit d08f67feed
8 changed files with 115 additions and 47 deletions

View File

@@ -305,7 +305,7 @@ pub fn CollectRingPoints(
edgeIndex: i32,
backup: bool,
) -> Vec<Point> {
let centerI = center.round();
let centerI = center.floor();
let radius = range;
let mut cur = EdgeTracer::new(image, centerI, point(0.0, 1.0));
if cur.stepToEdge(Some(edgeIndex), Some(radius), Some(backup)) == 0 {
@@ -362,17 +362,20 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
let dist2Center = |a, b| Point::distance(a, center) < Point::distance(b, center);
// rotate points such that the first one is the furthest away from the center (hence, a corner)
let max_by_pred = |a: &Point, b: &Point| {
if dist2Center(*a, *b) {
std::cmp::Ordering::Greater
} else {
std::cmp::Ordering::Less
}
let max_by_pred = |a: &&Point, b: &&Point| {
let da = Point::distance(**a, center);
let db = Point::distance(**b, center);
da.partial_cmp(&db).unwrap()
// if dist2Center(**a, **b) {
// std::cmp::Ordering::Greater
// } else {
// std::cmp::Ordering::Less
// }
};
let max = points.iter().copied().max_by(max_by_pred)?;
let max = points.iter().max_by(max_by_pred)?;
let pos = points.iter().position(|e| *e == max)?;
let pos = points.iter().position(|e| e == max)?;
points.rotate_left(pos);
// std::rotate(points.begin(), std::max_element(points.begin(), points.end(), dist2Center), points.end());
@@ -380,9 +383,8 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
let mut corners = [Point::default(); 4];
corners[0] = points[0];
// find the oposite corner by looking for the farthest point near the oposite point
points[(points.len() * 3 / 8)..=(points.len() * 5 / 8)]
corners[2] = *points[(points.len() * 3 / 8)..=(points.len() * 5 / 8)]
.iter()
.copied()
.max_by(max_by_pred)?;
// corners[2] = std::max_element(&points[Size(points) * 3 / 8], &points[Size(points) * 5 / 8], dist2Center);
// find the two in between corners by looking for the points farthest from the long diagonal
@@ -390,11 +392,14 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
let dist2Diagonal = /*[l = RegressionLine(*corners[0], *corners[2])]*/| a, b| { l.distance_single(a) < l.distance_single(b) };
let diagonal_max_by_pred = |p1: &Point, p2: &Point| {
if dist2Diagonal(*p1, *p2) {
std::cmp::Ordering::Greater
} else {
std::cmp::Ordering::Less
}
let d1 = l.distance_single(*p1);
let d2 = l.distance_single(*p2);
d1.partial_cmp(&d2).unwrap()
// if dist2Diagonal(*p1, *p2) {
// std::cmp::Ordering::Greater
// } else {
// std::cmp::Ordering::Less
// }
};
corners[1] = points[(points.len() / 8)..=(points.len() * 3 / 8)]
.iter()
@@ -407,11 +412,19 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
.max_by(diagonal_max_by_pred)?;
// corners[3] = std::max_element(&points[Size(points) * 5 / 8], &points[Size(points) * 7 / 8], dist2Diagonal);
let corner_positions = [0, points.iter().position(|p| *p == corners[1])?, points.iter().position(|p| *p == corners[2])?, points.iter().position(|p| *p == corners[3])?];
// let lines = [
// RegressionLine::with_two_points(corners[0] + 1.0, corners[1]),
// RegressionLine::with_two_points(corners[1] + 1.0, corners[2]),
// RegressionLine::with_two_points(corners[2] + 1.0, corners[3]),
// RegressionLine::with_two_points(corners[3] + 1.0, *points.last()? + 1.0),
// ];
let lines = [
RegressionLine::with_two_points(corners[0] + 1.0, corners[1]),
RegressionLine::with_two_points(corners[1] + 1.0, corners[2]),
RegressionLine::with_two_points(corners[2] + 1.0, corners[3]),
RegressionLine::with_two_points(corners[3] + 1.0, *points.last()? + 1.0),
RegressionLine::with_point_slice(&points[corner_positions[0] + 1.. corner_positions[1]]),
RegressionLine::with_point_slice(&points[corner_positions[1] + 1.. corner_positions[2]]),
RegressionLine::with_point_slice(&points[corner_positions[2] + 1.. corner_positions[3]]),
RegressionLine::with_point_slice(&points[corner_positions[3] + 1.. points.len()]),
];
// std::array lines{RegressionLine{corners[0] + 1, corners[1]}, RegressionLine{corners[1] + 1, corners[2]},
// RegressionLine{corners[2] + 1, corners[3]}, RegressionLine{corners[3] + 1, &points.back() + 1}};
@@ -428,6 +441,44 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
Some(res)
}
// fn fit_quadralateral_to_points(center: Point, points: Vec<Point>) -> Option<Quadrilateral> {
// let dist2center = |a, b| Point::distance(a, center) < Point::distance(b, center);
// // Rotate points such that the first one is the furthest away from the center (hence, a corner)
// let mut points = points;
// points.rotate_left(points.iter().position(|p| dist2center(p, center)).unwrap());
// let mut corners = [&points[0]; 4];
// corners[0] = &points[0];
// // Find the opposite corner by looking for the farthest point near the opposite point
// let opposite_corner = points.iter().take(points.len() / 2).max_by(|p| dist2center(p, corners[0]));
// corners[2] = opposite_corner;
// // Find the two in between corners by looking for the points farthest from the long diagonal
// let dist2diagonal = |l: &RegressionLine, a| l.distance(a);
// corners[1] = points.iter().take(points.len() / 2).max_by(|p| dist2diagonal(&RegressionLine(*corners[0], *corners[2]), *p));
// corners[3] = points.iter().skip(points.len() / 2).max_by(|p| dist2diagonal(&RegressionLine(*corners[0], *corners[2]), *p));
// let lines = [
// RegressionLine::new(corners[0], corners[1]),
// RegressionLine::new(corners[1], corners[2]),
// RegressionLine::new(corners[2], corners[3]),
// RegressionLine::new(corners[3], corners[0]),
// ];
// if lines.iter().any(|l| !l.is_valid()) {
// return None;
// }
// let mut res = QuadrilateralF::new();
// for i in 0..4 {
// res[i] = intersect(lines[i], lines[(i + 1) % 4]);
// }
// Some(res)
// }
pub fn QuadrilateralIsPlausibleSquare(q: &Quadrilateral, lineIndex: usize) -> bool {
let mut m;

View File

@@ -56,7 +56,7 @@ impl<'a> FastEdgeToEdgeCounter<'a> {
steps += 1;
if steps > maxSteps {
if maxSteps == self.stepsToBorder {
break false;
break;
} else {
return 0;
}
@@ -67,7 +67,7 @@ impl<'a> FastEdgeToEdgeCounter<'a> {
// if !(self.under_arry[idx_pt]
// == self.under_arry[self.p as usize])
if !(self.under_arry.get_index(idx_pt) == self.under_arry.get_index(self.p as usize)) {
break true;
break;
}
} // while (p[steps * stride] == p[0]);

View File

@@ -5,12 +5,12 @@ use crate::{Exceptions, Point};
pub struct Matrix<T: Default + Clone + Copy> {
width: usize,
height: usize,
data: Vec<T>,
data: Vec<Option<T>>,
}
impl<T: Default + Clone + Copy> Matrix<T> {
pub fn with_data(width: usize, height: usize, data: Vec<T>) -> Result<Matrix<T>> {
if (width != 0 && data.len() / width as usize != height as usize) {
pub fn with_data(width: usize, height: usize, data: Vec<Option<T>>) -> Result<Matrix<T>> {
if width != 0 && data.len() / width as usize != height as usize {
return Err(Exceptions::illegal_argument_with(
"invalid size: width * height is too big",
));
@@ -31,7 +31,7 @@ impl<T: Default + Clone + Copy> Matrix<T> {
Ok(Self {
width,
height,
data: vec![T::default(); width * height],
data: vec![None; width * height],
})
}
@@ -66,13 +66,15 @@ impl<T: Default + Clone + Copy> Matrix<T> {
pub fn get(&self, x: usize, y: usize) -> Option<T> {
if x >= self.width || y >= self.height {
None
} else {
Some(self.data[Self::get_offset(x, y, self.width)])
} else if let Some(Some(d)) = self.data.get(Self::get_offset(x, y, self.width)){
Some(*d)
}else {
None
}
}
pub fn set(&mut self, x: usize, y: usize, value: T) -> T {
self.data[Self::get_offset(x, y, self.width)] = value;
self.data[Self::get_offset(x, y, self.width)] = Some(value);
self.get(x, y).unwrap()
}
@@ -84,7 +86,7 @@ impl<T: Default + Clone + Copy> Matrix<T> {
self.set(p.x as usize, p.y as usize, value)
}
pub fn data(&self) -> &[T] {
pub fn data(&self) -> &[Option<T>] {
&self.data
}
@@ -97,10 +99,10 @@ impl<T: Default + Clone + Copy> Matrix<T> {
// }
pub fn clear_with(&mut self, value: T) {
self.data.fill(value)
self.data.fill(Some(value))
}
pub fn clear(&mut self) {
self.data.fill(T::default())
self.data.fill(None)
}
}

View File

@@ -228,4 +228,9 @@ impl RegressionLine {
new_rl.evaluate(&[point1, point2]);
new_rl
}
pub fn with_point_slice(points: &[Point]) -> Self {
let mut new_rl = RegressionLine::default();
new_rl.evaluate(points);
new_rl
}
}