From 65aea95e7dfadf7d0d2060d812881443b1b0ff1c Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 21 Jul 2013 15:08:54 +1000 Subject: [PATCH] Add scalar and component-wise clamp methods --- src/color/color.rs | 3 ++- src/color/hsv.rs | 21 +++++++++++++++++++-- src/color/rgb.rs | 21 +++++++++++++++++++-- src/math/vec.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/color/color.rs b/src/color/color.rs index 45687ef..2302720 100644 --- a/src/color/color.rs +++ b/src/color/color.rs @@ -28,7 +28,8 @@ pub mod srgb; pub mod ycbcr; pub trait Color { - pub fn clamp(&self, lo: T, hi: T) -> Self; + pub fn clamp_s(&self, lo: T, hi: T) -> Self; + pub fn clamp_c(&self, lo: &Self, hi: &Self) -> Self; pub fn inverse(&self) -> Self; // pub fn mix(&self, other: &Self, value: T) -> Self; // pub fn saturation(&self, value: T) -> Self; diff --git a/src/color/hsv.rs b/src/color/hsv.rs index 035c31d..735b5f6 100644 --- a/src/color/hsv.rs +++ b/src/color/hsv.rs @@ -40,12 +40,20 @@ impl HSV { impl Color for HSV { /// Clamps the components of the color to the range `(lo,hi)`. #[inline] - pub fn clamp(&self, lo: T, hi: T) -> HSV { + pub fn clamp_s(&self, lo: T, hi: T) -> HSV { HSV::new(self.h.clamp(&lo, &hi), // Should the hue component be clamped? self.s.clamp(&lo, &hi), self.v.clamp(&lo, &hi)) } + /// Clamps the components of the color component-wise between `lo` and `hi`. + #[inline] + pub fn clamp_c(&self, lo: &HSV, hi: &HSV) -> HSV { + HSV::new(self.h.clamp(&lo.h, &hi.h), + self.s.clamp(&lo.s, &hi.s), + self.v.clamp(&lo.v, &hi.v)) + } + /// Inverts the color. #[inline] pub fn inverse(&self) -> HSV { @@ -159,13 +167,22 @@ impl HSVA { impl Color for HSVA { /// Clamps the components of the color to the range `(lo,hi)`. #[inline] - pub fn clamp(&self, lo: T, hi: T) -> HSVA { + pub fn clamp_s(&self, lo: T, hi: T) -> HSVA { HSVA::new(self.h.clamp(&lo, &hi), // Should the hue component be clamped? self.s.clamp(&lo, &hi), self.v.clamp(&lo, &hi), self.a.clamp(&lo, &hi)) } + /// Clamps the components of the color component-wise between `lo` and `hi`. + #[inline] + pub fn clamp_c(&self, lo: &HSVA, hi: &HSVA) -> HSVA { + HSVA::new(self.h.clamp(&lo.h, &hi.h), + self.s.clamp(&lo.s, &hi.s), + self.v.clamp(&lo.v, &hi.v), + self.a.clamp(&lo.a, &hi.a)) + } + /// Inverts the color. #[inline] pub fn inverse(&self) -> HSVA { diff --git a/src/color/rgb.rs b/src/color/rgb.rs index 689173f..596f368 100644 --- a/src/color/rgb.rs +++ b/src/color/rgb.rs @@ -41,12 +41,20 @@ impl RGB { impl Color for RGB { /// Clamps the components of the color to the range `(lo,hi)`. #[inline] - pub fn clamp(&self, lo: T, hi: T) -> RGB { + pub fn clamp_s(&self, lo: T, hi: T) -> RGB { RGB::new(self.r.clamp(&lo, &hi), self.g.clamp(&lo, &hi), self.b.clamp(&lo, &hi)) } + /// Clamps the components of the color component-wise between `lo` and `hi`. + #[inline] + pub fn clamp_c(&self, lo: &RGB, hi: &RGB) -> RGB { + RGB::new(self.r.clamp(&lo.r, &hi.r), + self.g.clamp(&lo.g, &hi.g), + self.b.clamp(&lo.b, &hi.b)) + } + /// Inverts the color. #[inline] pub fn inverse(&self) -> RGB { @@ -156,13 +164,22 @@ impl RGBA { impl Color for RGBA { /// Clamps the components of the color to the range `(lo,hi)`. #[inline] - pub fn clamp(&self, lo: T, hi: T) -> RGBA { + pub fn clamp_s(&self, lo: T, hi: T) -> RGBA { RGBA::new(self.r.clamp(&lo, &hi), self.g.clamp(&lo, &hi), self.b.clamp(&lo, &hi), self.a.clamp(&lo, &hi)) } + /// Clamps the components of the color component-wise between `lo` and `hi`. + #[inline] + pub fn clamp_c(&self, lo: &RGBA, hi: &RGBA) -> RGBA { + RGBA::new(self.r.clamp(&lo.r, &hi.r), + self.g.clamp(&lo.g, &hi.g), + self.b.clamp(&lo.b, &hi.b), + self.a.clamp(&lo.a, &hi.a)) + } + /// Inverts the color. #[inline] pub fn inverse(&self) -> RGBA { diff --git a/src/math/vec.rs b/src/math/vec.rs index f3a104c..a242c73 100644 --- a/src/math/vec.rs +++ b/src/math/vec.rs @@ -81,9 +81,11 @@ pub trait OrdVec: Vec { pub fn min_s(&self, other: T) -> Self; pub fn max_s(&self, other: T) -> Self; + pub fn clamp_s(&self, mn: T, mx: T) -> Self; pub fn min_v(&self, other: &Self) -> Self; pub fn max_v(&self, other: &Self) -> Self; + pub fn clamp_v(&self, mn: &Self, mx: &Self) -> Self; pub fn comp_min(&self) -> T; pub fn comp_max(&self) -> T; @@ -501,6 +503,12 @@ impl OrdVec> for Vec2 { self.index(1).max(&value)) } + #[inline] + pub fn clamp_s(&self, mn: T, mx: T) -> Vec2 { + Vec2::new(self.index(0).clamp(&mn, &mx), + self.index(1).clamp(&mn, &mx)) + } + #[inline] pub fn min_v(&self, other: &Vec2) -> Vec2 { Vec2::new(self.index(0).min(other.index(0)), @@ -513,6 +521,12 @@ impl OrdVec> for Vec2 { self.index(1).max(other.index(1))) } + #[inline] + pub fn clamp_v(&self, mn: &Vec2, mx: &Vec2) -> Vec2 { + Vec2::new(self.index(0).clamp(mn.index(0), mx.index(0)), + self.index(1).clamp(mn.index(1), mx.index(1))) + } + /// Returns the smallest component of the vector. #[inline] pub fn comp_min(&self) -> T { @@ -1170,6 +1184,13 @@ impl OrdVec> for Vec3 { self.index(2).max(&value)) } + #[inline] + pub fn clamp_s(&self, mn: T, mx: T) -> Vec3 { + Vec3::new(self.index(0).clamp(&mn, &mx), + self.index(1).clamp(&mn, &mx), + self.index(2).clamp(&mn, &mx)) + } + #[inline] pub fn min_v(&self, other: &Vec3) -> Vec3 { Vec3::new(self.index(0).min(other.index(0)), @@ -1184,6 +1205,13 @@ impl OrdVec> for Vec3 { self.index(2).max(other.index(2))) } + #[inline] + pub fn clamp_v(&self, mn: &Vec3, mx: &Vec3) -> Vec3 { + Vec3::new(self.index(0).clamp(mn.index(0), mx.index(0)), + self.index(1).clamp(mn.index(1), mx.index(1)), + self.index(2).clamp(mn.index(2), mx.index(2))) + } + /// Returns the smallest component of the vector. #[inline] pub fn comp_min(&self) -> T { @@ -1873,6 +1901,14 @@ impl OrdVec> for Vec4 { self.index(3).max(&value)) } + #[inline] + pub fn clamp_s(&self, mn: T, mx: T) -> Vec4 { + Vec4::new(self.index(0).clamp(&mn, &mx), + self.index(1).clamp(&mn, &mx), + self.index(2).clamp(&mn, &mx), + self.index(3).clamp(&mn, &mx)) + } + #[inline] pub fn min_v(&self, other: &Vec4) -> Vec4 { Vec4::new(self.index(0).min(other.index(0)), @@ -1889,6 +1925,14 @@ impl OrdVec> for Vec4 { self.index(3).max(other.index(3))) } + #[inline] + pub fn clamp_v(&self, mn: &Vec4, mx: &Vec4) -> Vec4 { + Vec4::new(self.index(0).clamp(mn.index(0), mx.index(0)), + self.index(1).clamp(mn.index(1), mx.index(1)), + self.index(2).clamp(mn.index(2), mx.index(2)), + self.index(3).clamp(mn.index(3), mx.index(3))) + } + /// Returns the smallest component of the vector. #[inline] pub fn comp_min(&self) -> T {