Add scalar and component-wise clamp methods

This commit is contained in:
Brendan Zabarauskas 2013-07-21 15:08:54 +10:00
parent 31be8b79df
commit 65aea95e7d
4 changed files with 84 additions and 5 deletions

View file

@ -28,7 +28,8 @@ pub mod srgb;
pub mod ycbcr;
pub trait Color<T> {
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;

View file

@ -40,12 +40,20 @@ impl<T:FloatChannel> HSV<T> {
impl<T:FloatChannel> Color<T> for HSV<T> {
/// Clamps the components of the color to the range `(lo,hi)`.
#[inline]
pub fn clamp(&self, lo: T, hi: T) -> HSV<T> {
pub fn clamp_s(&self, lo: T, hi: T) -> HSV<T> {
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<T>, hi: &HSV<T>) -> HSV<T> {
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<T> {
@ -159,13 +167,22 @@ impl<T:FloatChannel> HSVA<T> {
impl<T:FloatChannel> Color<T> for HSVA<T> {
/// Clamps the components of the color to the range `(lo,hi)`.
#[inline]
pub fn clamp(&self, lo: T, hi: T) -> HSVA<T> {
pub fn clamp_s(&self, lo: T, hi: T) -> HSVA<T> {
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<T>, hi: &HSVA<T>) -> HSVA<T> {
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<T> {

View file

@ -41,12 +41,20 @@ impl<T:Channel> RGB<T> {
impl<T:Channel> Color<T> for RGB<T> {
/// Clamps the components of the color to the range `(lo,hi)`.
#[inline]
pub fn clamp(&self, lo: T, hi: T) -> RGB<T> {
pub fn clamp_s(&self, lo: T, hi: T) -> RGB<T> {
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<T>, hi: &RGB<T>) -> RGB<T> {
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<T> {
@ -156,13 +164,22 @@ impl<T:Channel> RGBA<T> {
impl<T:Channel> Color<T> for RGBA<T> {
/// Clamps the components of the color to the range `(lo,hi)`.
#[inline]
pub fn clamp(&self, lo: T, hi: T) -> RGBA<T> {
pub fn clamp_s(&self, lo: T, hi: T) -> RGBA<T> {
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<T>, hi: &RGBA<T>) -> RGBA<T> {
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<T> {

View file

@ -81,9 +81,11 @@ pub trait OrdVec<T,Slice,BV>: Vec<T,Slice> {
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<T:Orderable> OrdVec<T,[T,..2],Vec2<bool>> for Vec2<T> {
self.index(1).max(&value))
}
#[inline]
pub fn clamp_s(&self, mn: T, mx: T) -> Vec2<T> {
Vec2::new(self.index(0).clamp(&mn, &mx),
self.index(1).clamp(&mn, &mx))
}
#[inline]
pub fn min_v(&self, other: &Vec2<T>) -> Vec2<T> {
Vec2::new(self.index(0).min(other.index(0)),
@ -513,6 +521,12 @@ impl<T:Orderable> OrdVec<T,[T,..2],Vec2<bool>> for Vec2<T> {
self.index(1).max(other.index(1)))
}
#[inline]
pub fn clamp_v(&self, mn: &Vec2<T>, mx: &Vec2<T>) -> Vec2<T> {
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<T:Orderable> OrdVec<T,[T,..3],Vec3<bool>> for Vec3<T> {
self.index(2).max(&value))
}
#[inline]
pub fn clamp_s(&self, mn: T, mx: T) -> Vec3<T> {
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<T>) -> Vec3<T> {
Vec3::new(self.index(0).min(other.index(0)),
@ -1184,6 +1205,13 @@ impl<T:Orderable> OrdVec<T,[T,..3],Vec3<bool>> for Vec3<T> {
self.index(2).max(other.index(2)))
}
#[inline]
pub fn clamp_v(&self, mn: &Vec3<T>, mx: &Vec3<T>) -> Vec3<T> {
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<T:Orderable> OrdVec<T,[T,..4],Vec4<bool>> for Vec4<T> {
self.index(3).max(&value))
}
#[inline]
pub fn clamp_s(&self, mn: T, mx: T) -> Vec4<T> {
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<T>) -> Vec4<T> {
Vec4::new(self.index(0).min(other.index(0)),
@ -1889,6 +1925,14 @@ impl<T:Orderable> OrdVec<T,[T,..4],Vec4<bool>> for Vec4<T> {
self.index(3).max(other.index(3)))
}
#[inline]
pub fn clamp_v(&self, mn: &Vec4<T>, mx: &Vec4<T>) -> Vec4<T> {
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 {