From 592a4d694c43160842c3f66c603d72d5e2be78bf Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Thu, 4 May 2023 13:16:44 -0500 Subject: [PATCH] move more to generic points --- src/common/cpp_essentials/pattern.rs | 2 +- src/rxing_result_point.rs | 197 ++++++++++++++++++--------- 2 files changed, 137 insertions(+), 62 deletions(-) diff --git a/src/common/cpp_essentials/pattern.rs b/src/common/cpp_essentials/pattern.rs index bd8ebd4..db16934 100644 --- a/src/common/cpp_essentials/pattern.rs +++ b/src/common/cpp_essentials/pattern.rs @@ -228,7 +228,7 @@ impl<'a> PatternView<'a> { let mut size = size.unwrap_or(0); if size == 0 { size = self.count - offset; - } + } // else if size < 0 { // size += self.count - offset; // } diff --git a/src/rxing_result_point.rs b/src/rxing_result_point.rs index 08b5abb..1ef94e7 100644 --- a/src/rxing_result_point.rs +++ b/src/rxing_result_point.rs @@ -1,3 +1,4 @@ +use std::process::Output; use std::{fmt, iter::Sum}; use std::hash::Hash; @@ -32,7 +33,7 @@ pub type Point = PointF; impl Into for Point { fn into(self) -> PointI { - PointI{ + PointI { x: self.x.floor() as u32, y: self.y.floor() as u32, } @@ -75,58 +76,82 @@ impl PartialEq for Point { } impl Eq for Point {} -impl Point { - pub const fn new(x: f32, y: f32) -> Self { - Self { x, y } +impl PointT +where + T: Copy, +{ + pub const fn new(x: T, y: T) -> PointT { + PointT { x: x, y: y } } - - pub const fn with_single(x: f32) -> Self { + pub const fn with_single(x: T) -> Self { Self { x, y: x } } } -impl std::ops::AddAssign for Point { +impl std::ops::AddAssign for PointT +where + T: std::ops::Add + Copy, +{ fn add_assign(&mut self, rhs: Self) { self.x = self.x + rhs.x; self.y = self.y + rhs.y; } } -impl std::ops::SubAssign for Point { +impl std::ops::SubAssign for PointT +where + T: std::ops::Sub + Copy, +{ fn sub_assign(&mut self, rhs: Self) { self.x = self.x - rhs.x; self.y = self.y - rhs.y; } } -impl<'a> Sum<&'a Point> for Point { +impl<'a, T> Sum<&'a PointT> for PointT +where + T: std::ops::Add + 'a + Default, + PointT: std::ops::Add> + Copy, +{ fn sum>(iter: I) -> Self { iter.fold(Self::default(), |acc, &p| acc + p) } } /** This impl is temporary and is there to ease refactoring. */ -impl ResultPoint for Point { +impl ResultPoint for PointT +where + T: Into + Copy, +{ fn getX(&self) -> f32 { - self.x + self.x.into() } fn getY(&self) -> f32 { - self.y + self.y.into() } - fn to_rxing_result_point(&self) -> Self { - *self + fn to_rxing_result_point(&self) -> PointT { + PointT { + x: self.x.into(), + y: self.y.into(), + } } } -impl fmt::Display for Point { +impl fmt::Display for PointT +where + T: std::fmt::Display, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "({},{})", self.x, self.y) } } -impl std::ops::Sub for Point { +impl std::ops::Sub for PointT +where + T: std::ops::Sub + Copy, +{ type Output = Self; fn sub(self, rhs: Self) -> Self::Output { @@ -134,7 +159,10 @@ impl std::ops::Sub for Point { } } -impl std::ops::Neg for Point { +impl std::ops::Neg for PointT +where + T: std::ops::Neg + Copy, +{ type Output = Self; fn neg(self) -> Self::Output { @@ -142,7 +170,10 @@ impl std::ops::Neg for Point { } } -impl std::ops::Add for Point { +impl std::ops::Add for PointT +where + T: std::ops::Add + Copy, +{ type Output = Self; fn add(self, rhs: Self) -> Self::Output { @@ -150,7 +181,10 @@ impl std::ops::Add for Point { } } -impl std::ops::Add for Point { +impl std::ops::Add for PointT +where + T: Into + std::ops::Add + Copy, +{ type Output = Self; fn add(self, rhs: f32) -> Self::Output { @@ -158,15 +192,21 @@ impl std::ops::Add for Point { } } -impl std::ops::Add for f32 { +impl std::ops::Add> for f32 +where + T: std::ops::Add, +{ type Output = Point; - fn add(self, rhs: Point) -> Self::Output { + fn add(self, rhs: PointT) -> Self::Output { Point::new(rhs.x + self, rhs.y + self) } } -impl std::ops::Mul for Point { +impl std::ops::Mul for PointT +where + T: std::ops::Mul + Copy, +{ type Output = Self; fn mul(self, rhs: Self) -> Self::Output { @@ -230,36 +270,41 @@ impl std::ops::Mul for u32 { } } -impl Point { - pub fn dot(self, p: Self) -> f32 { +impl PointT +where + T: std::ops::Mul + std::ops::Sub + num::traits::real::Real, + PointT: std::ops::Div>, +{ + pub fn dot(self, p: Self) -> T { self.x * p.x + self.y * p.y } - pub fn cross(self, p: Self) -> f32 { + pub fn cross(self, p: Self) -> T { self.x * p.y - p.x * self.y } /// L1 norm - pub fn sumAbsComponent(self) -> f32 { + pub fn sumAbsComponent(self) -> T { self.x.abs() + self.y.abs() } /// L2 norm - pub fn length(self) -> f32 { + pub fn length(self) -> T { self.x.hypot(self.y) } /// L-inf norm - pub fn maxAbsComponent(self) -> f32 { - f32::max(self.x.abs(), self.y.abs()) + pub fn maxAbsComponent(self) -> T { + self.x.abs().max(self.y.abs()) + // f32::max(self.x.abs(), self.y.abs()) } - pub fn squaredDistance(self, p: Self) -> f32 { + pub fn squaredDistance(self, p: Self) -> T { let diff = self - p; diff.x * diff.x + diff.y * diff.y } - pub fn distance(self, p: Self) -> f32 { + pub fn distance(self, p: Self) -> T { (self - p).length() } @@ -267,20 +312,15 @@ impl Point { Self::new(self.x.abs(), self.y.abs()) } - pub fn fold U>(self, f: F) -> U { + pub fn fold U>(self, f: F) -> U { f(self.x, self.y) } - /// Calculate a floating point pixel coordinate representing the 'center' of the pixel. - /// This is sort of the inverse operation of the PointI(PointF) conversion constructor. - /// See also the documentation of the GridSampler API. - #[inline(always)] - pub fn centered(self) -> Self { - Self::new(self.x.floor() + 0.5, self.y.floor() + 0.5) - } - - pub fn middle(self, p: Self) -> Self { - (self + p) / 2.0 + pub fn middle(self, p: Self) -> Self + where + T: From, + { + (self + p) / 2.into() } pub fn normalized(self) -> Self { @@ -291,11 +331,14 @@ impl Point { self / Self::maxAbsComponent(self) } - pub fn mainDirection(self) -> Self { + pub fn mainDirection(self) -> Self + where + T: From, + { if self.x.abs() > self.y.abs() { - Self::new(self.x, 0.0) + Self::new(self.x, 0.into()) } else { - Self::new(0.0, self.y) + Self::new(0.into(), self.y) } } @@ -306,6 +349,17 @@ impl Point { } } + /// Calculate a floating point pixel coordinate representing the 'center' of the pixel. + /// This is sort of the inverse operation of the PointI(PointF) conversion constructor. + /// See also the documentation of the GridSampler API. + #[inline(always)] + pub fn centered(self) -> PointT + where + T: Into, + { + PointT::new(self.x.floor().into() + 0.5, self.y.floor().into() + 0.5) + } + pub fn floor(self) -> Self { Self { x: self.x.floor(), @@ -314,27 +368,48 @@ impl Point { } } -impl From<&(f32, f32)> for Point { - fn from(&(x, y): &(f32, f32)) -> Self { - Self::new(x, y) - } -} - -impl From<(f32, f32)> for Point { - fn from((x, y): (f32, f32)) -> Self { - Self::new(x, y) - } -} - impl From<(i32, i32)> for Point { - fn from(value: (i32, i32)) -> Self { - Self::new(value.0 as f32, value.1 as f32) + fn from((x, y): (i32, i32)) -> Self { + Self::new(x as f32, y as f32) } } impl From<(u32, u32)> for Point { - fn from(value: (u32, u32)) -> Self { - Self::new(value.0 as f32, value.1 as f32) + fn from((x, y): (u32, u32)) -> Self { + Self::new(x as f32, y as f32) + } +} + +impl From<(f32, f32)> for PointI { + fn from((x, y): (f32, f32)) -> Self { + PointI { + x: x.floor() as u32, + y: y.floor() as u32, + } + } +} + +impl From<(T, T)> for PointT { + fn from((x, y): (T, T)) -> PointT { + PointT { x, y } + } +} + +impl From<&(T, T)> for PointT +where + T: Copy, +{ + fn from(&(x, y): &(T, T)) -> PointT { + PointT { x, y } + } +} + +impl From for PointT +where + T: Copy, +{ + fn from(value: T) -> Self { + Self::with_single(value) } }