diff --git a/src/aztec/detector.rs b/src/aztec/detector.rs index bd508de..fdba244 100644 --- a/src/aztec/detector.rs +++ b/src/aztec/detector.rs @@ -289,8 +289,8 @@ impl<'a> Detector<'_> { //c b if self.nb_center_layers > 2 { - let q: f32 = Self::distance_points(&poutd, &pouta) * self.nb_center_layers as f32 - / (Self::distance_points(&pind, &pina) * (self.nb_center_layers + 2) as f32); + let q: f32 = Self::distance_points(poutd, pouta) * self.nb_center_layers as f32 + / (Self::distance_points(pind, pina) * (self.nb_center_layers + 2) as f32); // let q: f32 = Self::distance( // &poutd.to_rxing_result_point(), @@ -583,25 +583,25 @@ impl<'a> Detector<'_> { // let p4 = Point::new(Math.min(image.getWidth() - 1, p4.getX() + corr), // Math.min(image.getHeight() - 1, p4.getY() + corr)); - let c_init = self.get_color(&p4, &p1); + let c_init = self.get_color(p4, p1); if c_init == 0 { return false; } - let c = self.get_color(&p1, &p2); + let c = self.get_color(p1, p2); if c != c_init { return false; } - let c = self.get_color(&p2, &p3); + let c = self.get_color(p2, p3); if c != c_init { return false; } - let c = self.get_color(&p3, &p4); + let c = self.get_color(p3, p4); c == c_init } @@ -611,7 +611,7 @@ impl<'a> Detector<'_> { * * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else */ - fn get_color(&self, p1: &AztecPoint, p2: &AztecPoint) -> i32 { + fn get_color(&self, p1: AztecPoint, p2: AztecPoint) -> i32 { let d = Self::distance_points(p1, p2); if d == 0.0f32 { return 0; @@ -715,12 +715,12 @@ impl<'a> Detector<'_> { self.is_valid_points(x, y) } - fn distance_points(a: &AztecPoint, b: &AztecPoint) -> f32 { - MathUtils::distance(a.get_x(), a.get_y(), b.get_x(), b.get_y()) + fn distance_points(a: AztecPoint, b: AztecPoint) -> f32 { + Point::from(a).distance(b.into()) } fn distance(a: Point, b: Point) -> f32 { - MathUtils::distance(a.getX(), a.getY(), b.getX(), b.getY()) + a.distance(b) } fn get_dimension(&self) -> u32 { diff --git a/src/common/detector/MathUtils.rs b/src/common/detector/MathUtils.rs index 9123211..3f1d1dc 100644 --- a/src/common/detector/MathUtils.rs +++ b/src/common/detector/MathUtils.rs @@ -14,10 +14,7 @@ * limitations under the License. */ -use std::{ - f32, i32, - ops::{Add, Sub}, -}; +use std::{f32, i32, ops::Add}; /** * General math-related and numeric utility functions. @@ -66,16 +63,6 @@ pub fn round(d: f32) -> i32 { // (xDiff * xDiff + yDiff * yDiff).sqrt() as f32 // } -#[inline(always)] -pub fn distance(aX: T, aY: T, bX: T, bY: T) -> f32 -where - T: Sub + Into, -{ - let xDiff: f64 = (aX - bX).into(); - let yDiff: f64 = (aY - bY).into(); - (xDiff * xDiff + yDiff * yDiff).sqrt() as f32 -} - /** * @param array values to sum * @return sum of values in array @@ -119,25 +106,13 @@ mod tests { assert_eq!(0, MathUtils::round(f32::NAN)); } - #[test] - fn testDistance() { - assert_eq!( - (8.0f32).sqrt(), - MathUtils::distance(1.0f32, 2.0f32, 3.0f32, 4.0f32) - ); - assert_eq!(0.0f32, MathUtils::distance(1.0f32, 2.0f32, 1.0f32, 2.0f32)); - - assert_eq!((8.0f32).sqrt(), MathUtils::distance(1, 2, 3, 4)); - assert_eq!(0.0f32, MathUtils::distance(1, 2, 1, 2)); - } - - #[test] - fn testSum() { - assert_eq!(0, MathUtils::sum(&[])); - assert_eq!(1, MathUtils::sum(&[1])); - assert_eq!(4, MathUtils::sum(&[1, 3])); - assert_eq!(0, MathUtils::sum(&[-1, 1])); - assert_eq!(0.0, MathUtils::sum(&[-1.0, 1.0])); - assert_eq!(4.0, MathUtils::sum(&[1.0, 3.0])); - } + // #[test] + // fn testSum() { + // assert_eq!(0, MathUtils::sum(&[])); + // assert_eq!(1, MathUtils::sum(&[1])); + // assert_eq!(4, MathUtils::sum(&[1, 3])); + // assert_eq!(0, MathUtils::sum(&[-1, 1])); + // assert_eq!(0.0, MathUtils::sum(&[-1.0, 1.0])); + // assert_eq!(4.0, MathUtils::sum(&[1.0, 3.0])); + // } } diff --git a/src/common/detector/white_rectangle_detector.rs b/src/common/detector/white_rectangle_detector.rs index c85e9fa..7cdb660 100644 --- a/src/common/detector/white_rectangle_detector.rs +++ b/src/common/detector/white_rectangle_detector.rs @@ -290,7 +290,10 @@ impl<'a> WhiteRectangleDetector<'_> { } fn get_black_point_on_segment(&self, a_x: f32, a_y: f32, b_x: f32, b_y: f32) -> Option { - let dist = MathUtils::round(MathUtils::distance(a_x, a_y, b_x, b_y)); + let a = Point::new(a_x, a_y); + let b = Point::new(b_x, b_y); + + let dist = MathUtils::round(a.distance(b)); let x_step: f32 = (b_x - a_x) / dist as f32; let y_step: f32 = (b_y - a_y) / dist as f32; diff --git a/src/maxicode/detector.rs b/src/maxicode/detector.rs index e19dd44..d2a846c 100644 --- a/src/maxicode/detector.rs +++ b/src/maxicode/detector.rs @@ -2,10 +2,7 @@ use num::integer::Roots; use crate::{ - common::{ - detector::MathUtils, BitMatrix, DefaultGridSampler, DetectorRXingResult, GridSampler, - Result, - }, + common::{BitMatrix, DefaultGridSampler, DetectorRXingResult, GridSampler, Result}, Exceptions, Point, }; @@ -349,8 +346,8 @@ pub fn detect(image: &BitMatrix, try_harder: bool) -> Result Point { + fn to_rxing_result_point(&self) -> Point { Point { x: self.point.0, y: self.point.1, diff --git a/src/qrcode/detector/finder_pattern.rs b/src/qrcode/detector/finder_pattern.rs index 447ee48..9d0c239 100644 --- a/src/qrcode/detector/finder_pattern.rs +++ b/src/qrcode/detector/finder_pattern.rs @@ -39,7 +39,7 @@ impl ResultPoint for FinderPattern { self.point.1 } - fn into_rxing_result_point(self) -> Point { + fn to_rxing_result_point(&self) -> Point { Point { x: self.point.0, y: self.point.1, diff --git a/src/qrcode/detector/qrcode_detector.rs b/src/qrcode/detector/qrcode_detector.rs index ccfc746..7016528 100644 --- a/src/qrcode/detector/qrcode_detector.rs +++ b/src/qrcode/detector/qrcode_detector.rs @@ -22,7 +22,7 @@ use crate::{ Result, }, qrcode::decoder::Version, - result_point_utils, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, + result_point_utils, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, Point, PointCallback, ResultPoint, }; @@ -153,16 +153,16 @@ impl<'a> Detector<'_> { let bits = Detector::sampleGrid(self.image, &transform, dimension)?; let mut points = vec![ - bottomLeft.into_rxing_result_point(), - topLeft.into_rxing_result_point(), - topRight.into_rxing_result_point(), + bottomLeft.to_rxing_result_point(), + topLeft.to_rxing_result_point(), + topRight.to_rxing_result_point(), ]; if alignmentPattern.is_some() { points.push( alignmentPattern .ok_or(Exceptions::NotFoundException(None))? - .into_rxing_result_point(), + .to_rxing_result_point(), ) } @@ -379,7 +379,10 @@ impl<'a> Detector<'_> { // color, advance to next state or end if we are in state 2 already if (state == 1) == self.image.get(realX as u32, realY as u32) { if state == 2 { - return MathUtils::distance(x, y, fromX as i32, fromY as i32); + return Point::distance( + Point::new(x as f32, y as f32), + Point::new(fromX as f32, fromY as f32), + ); } state += 1; } @@ -399,7 +402,10 @@ impl<'a> Detector<'_> { // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. if state == 2 { - return MathUtils::distance(toX as i32 + xstep, toY as i32, fromX as i32, fromY as i32); + return Point::distance( + Point::new((toX as i32 + xstep) as f32, toY as f32), + Point::new(fromX as f32, fromY as f32), + ); } // else we didn't find even black-white-black; no estimate is really possible f32::NAN diff --git a/src/result_point.rs b/src/result_point.rs index 2a3700a..8b1565d 100644 --- a/src/result_point.rs +++ b/src/result_point.rs @@ -21,5 +21,5 @@ use crate::Point; pub trait ResultPoint { fn getX(&self) -> f32; fn getY(&self) -> f32; - fn into_rxing_result_point(self) -> Point; + fn to_rxing_result_point(&self) -> Point; } diff --git a/src/result_point_utils.rs b/src/result_point_utils.rs index 909b566..de673f5 100644 --- a/src/result_point_utils.rs +++ b/src/result_point_utils.rs @@ -1,4 +1,4 @@ -use crate::{common::detector::MathUtils, ResultPoint}; +use crate::{Point, ResultPoint}; /** * Orders an array of three Points in an order [A,B,C] such that AB is less than AC @@ -8,23 +8,17 @@ use crate::{common::detector::MathUtils, ResultPoint}; */ pub fn orderBestPatterns(patterns: &mut [T; 3]) { // Find distances between pattern centers - let zeroOneDistance = MathUtils::distance( - patterns[0].getX(), - patterns[0].getY(), - patterns[1].getX(), - patterns[1].getY(), + let zeroOneDistance = Point::distance( + patterns[0].to_rxing_result_point(), + patterns[1].to_rxing_result_point(), ); - let oneTwoDistance = MathUtils::distance( - patterns[1].getX(), - patterns[1].getY(), - patterns[2].getX(), - patterns[2].getY(), + let oneTwoDistance = Point::distance( + patterns[1].to_rxing_result_point(), + patterns[2].to_rxing_result_point(), ); - let zeroTwoDistance = MathUtils::distance( - patterns[0].getX(), - patterns[0].getY(), - patterns[2].getX(), - patterns[2].getY(), + let zeroTwoDistance = Point::distance( + patterns[0].to_rxing_result_point(), + patterns[2].to_rxing_result_point(), ); let mut pointA; @@ -69,11 +63,9 @@ pub fn orderBestPatterns(patterns: &mut [T; 3]) { * @return distance between two points */ pub fn distance(pattern1: &T, pattern2: &T) -> f32 { - MathUtils::distance( - pattern1.getX(), - pattern1.getY(), - pattern2.getX(), - pattern2.getY(), + Point::distance( + pattern1.to_rxing_result_point(), + pattern2.to_rxing_result_point(), ) } diff --git a/src/rxing_result_point.rs b/src/rxing_result_point.rs index eb617e3..e0ed881 100644 --- a/src/rxing_result_point.rs +++ b/src/rxing_result_point.rs @@ -68,8 +68,8 @@ impl ResultPoint for Point { self.y } - fn into_rxing_result_point(self) -> Self { - self + fn to_rxing_result_point(&self) -> Self { + *self } } @@ -167,7 +167,7 @@ impl Point { /// L2 norm pub fn length(self) -> f32 { - Self::dot(self, self).sqrt() + self.x.hypot(self.y) } /// L-inf norm @@ -176,7 +176,7 @@ impl Point { } pub fn distance(self, p: Self) -> f32 { - Self::length(self - p) + (self - p).length() } /// Calculate a floating point pixel coordinate representing the 'center' of the pixel. @@ -207,3 +207,35 @@ 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) + } +} + +#[cfg(test)] +mod tests { + use super::Point; + + #[test] + fn testDistance() { + assert_eq!( + (8.0f32).sqrt(), + Point::new(1.0, 2.0).distance(Point::new(3.0, 4.0)) + ); + assert_eq!(0.0, Point::new(1.0, 2.0).distance(Point::new(1.0, 2.0))); + + assert_eq!( + (8.0f32).sqrt(), + Point::new(1.0, 2.0).distance(Point::new(3.0, 4.0)) + ); + assert_eq!(0.0, Point::new(1.0, 2.0).distance(Point::new(1.0, 2.0))); + } +}