From 39c0348c9f98b4dd29bd112a0a2a42faa67c92d4 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 24 Jun 2020 15:20:02 -0400 Subject: Use the acap nearest neighbors implementation --- src/color.rs | 107 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 42 deletions(-) (limited to 'src/color.rs') diff --git a/src/color.rs b/src/color.rs index 5d50aa1..ff113a7 100644 --- a/src/color.rs +++ b/src/color.rs @@ -3,8 +3,9 @@ pub mod order; pub mod source; -use crate::metric::kd::{Cartesian, CartesianMetric}; -use crate::metric::{Metric, SquaredDistance}; +use acap::coords::{Coordinates, CoordinateMetric, CoordinateProximity}; +use acap::distance::{Metric, Proximity}; +use acap::euclid::{EuclideanDistance, euclidean_distance}; use image::Rgb; @@ -14,7 +15,11 @@ use std::ops::Index; pub type Rgb8 = Rgb; /// A [color space](https://en.wikipedia.org/wiki/Color_space). -pub trait ColorSpace: Copy + From + CartesianMetric { +pub trait ColorSpace: Copy + From + + Coordinates + + Metric + + CoordinateMetric<::Value, Distance = ::Distance> +{ /// Compute the average of the given colors. fn average>(colors: I) -> Self; } @@ -41,32 +46,38 @@ impl From for RgbSpace { } } -impl Metric<[f64]> for RgbSpace { - type Distance = SquaredDistance; +impl Coordinates for RgbSpace { + type Value = f64; - fn distance(&self, other: &[f64]) -> Self::Distance { - self.0.distance(other) + fn dims(&self) -> usize { + self.0.dims() + } + + fn coord(&self, i: usize) -> f64 { + self.0.coord(i) } } -impl Metric for RgbSpace { - type Distance = SquaredDistance; +impl Proximity for RgbSpace { + type Distance = EuclideanDistance; fn distance(&self, other: &Self) -> Self::Distance { - self.0.distance(&other.0) + euclidean_distance(&self.0, &other.0) } } -impl Cartesian for RgbSpace { - fn dimensions(&self) -> usize { - self.0.dimensions() - } +impl Metric for RgbSpace {} + +impl CoordinateProximity for RgbSpace { + type Distance = EuclideanDistance; - fn coordinate(&self, i: usize) -> f64 { - self.0.coordinate(i) + fn distance_to_coords(&self, other: &[f64]) -> Self::Distance { + euclidean_distance(&self.0, other) } } +impl CoordinateMetric for RgbSpace {} + impl ColorSpace for RgbSpace { fn average>(colors: I) -> Self { let mut sum = [0.0, 0.0, 0.0]; @@ -161,32 +172,38 @@ impl From for LabSpace { } } -impl Metric<[f64]> for LabSpace { - type Distance = SquaredDistance; +impl Coordinates for LabSpace { + type Value = f64; + + fn dims(&self) -> usize { + self.0.dims() + } - fn distance(&self, other: &[f64]) -> Self::Distance { - self.0.distance(other) + fn coord(&self, i: usize) -> f64 { + self.0.coord(i) } } -impl Metric for LabSpace { - type Distance = SquaredDistance; +impl Proximity for LabSpace { + type Distance = EuclideanDistance; fn distance(&self, other: &Self) -> Self::Distance { - self.0.distance(&other.0) + euclidean_distance(self.0, other.0) } } -impl Cartesian for LabSpace { - fn dimensions(&self) -> usize { - self.0.dimensions() - } +impl Metric for LabSpace {} - fn coordinate(&self, i: usize) -> f64 { - self.0.coordinate(i) +impl CoordinateProximity for LabSpace { + type Distance = EuclideanDistance; + + fn distance_to_coords(&self, other: &[f64]) -> Self::Distance { + euclidean_distance(&self.0, other) } } +impl CoordinateMetric for LabSpace {} + impl ColorSpace for LabSpace { fn average>(colors: I) -> Self { let mut sum = [0.0, 0.0, 0.0]; @@ -241,32 +258,38 @@ impl From for LuvSpace { } } -impl Metric<[f64]> for LuvSpace { - type Distance = SquaredDistance; +impl Coordinates for LuvSpace { + type Value = f64; + + fn dims(&self) -> usize { + self.0.dims() + } - fn distance(&self, other: &[f64]) -> Self::Distance { - self.0.distance(other) + fn coord(&self, i: usize) -> f64 { + self.0.coord(i) } } -impl Metric for LuvSpace { - type Distance = SquaredDistance; +impl Proximity for LuvSpace { + type Distance = EuclideanDistance; fn distance(&self, other: &Self) -> Self::Distance { - self.0.distance(&other.0) + euclidean_distance(&self.0, &other.0) } } -impl Cartesian for LuvSpace { - fn dimensions(&self) -> usize { - self.0.dimensions() - } +impl Metric for LuvSpace {} + +impl CoordinateProximity for LuvSpace { + type Distance = EuclideanDistance; - fn coordinate(&self, i: usize) -> f64 { - self.0.coordinate(i) + fn distance_to_coords(&self, other: &[f64]) -> Self::Distance { + euclidean_distance(&self.0, other) } } +impl CoordinateMetric for LuvSpace {} + impl ColorSpace for LuvSpace { fn average>(colors: I) -> Self { let mut sum = [0.0, 0.0, 0.0]; -- cgit v1.2.3