Use Float type bound for rgb/hsv conversions

This commit is contained in:
Brendan Zabarauskas 2012-12-03 13:14:25 +10:00
parent e1ed642f76
commit 566fffdac6

View file

@ -58,27 +58,25 @@ pub trait Color4<T>: Color<T> {
/** /**
* A generic rgb to hsv conversion * RGB to HSV conversion
*
* Assumes that T is a floating point type
*
* TODO: Use some sort of 'Float' trait bound to make this safer
*/ */
#[inline(always)] #[inline(always)]
pub pure fn to_hsv<T:Copy Num NumCast Eq Ord>(color: &RGB<T>) -> HSV<T> { pub pure fn to_hsv<T:Copy Float>(color: &RGB<T>) -> HSV<T> {
// Algorithm taken from the Wikipedia article on HSL and HSV: // Algorithm taken from the Wikipedia article on HSL and HSV:
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
let _0 = cast(0); let _0 = Float::from_float(0f);
let mx = [color.r, color.g, color.b].max(); let mx = [color.r, color.g, color.b].max();
let mn = [color.r, color.g, color.b].min(); let mn = [color.r, color.g, color.b].min();
let chr = mx - mn; let chr = mx - mn;
if chr != cast(0) { if chr != Float::from_float(0f) {
let h = Degrees(if color.r == mx { ((color.g - color.b) / chr) % cast(6) } let h = Degrees(
else if color.g == mx { ((color.b - color.r) / chr) + cast(2) } if color.r == mx { ((color.g - color.b) / chr) % Float::from_float(6f) }
else /* color.b == mx */{ ((color.r - color.g) / chr) + cast(4) } * cast(60)); else if color.g == mx { ((color.b - color.r) / chr) + Float::from_float(2f) }
else /* color.b == mx */{ ((color.r - color.g) / chr) + Float::from_float(4f) }
* Float::from_float(60f));
let s = chr / mx; let s = chr / mx;
@ -90,35 +88,31 @@ pub pure fn to_hsv<T:Copy Num NumCast Eq Ord>(color: &RGB<T>) -> HSV<T> {
} }
/** /**
* A generic hsv to rgb conversion * HSV to RGB conversion
*
* Assumes that T is a floating point type
*
* TODO: Use some sort of 'Float' trait bound to make this safer
*/ */
#[inline(always)] #[inline(always)]
pub pure fn to_rgb<T:Copy Num NumCast Sign Eq Ord>(color: &HSV<T>) -> RGB<T> { pub pure fn to_rgb<T:Copy Float Sign>(color: &HSV<T>) -> RGB<T> {
// Algorithm taken from the Wikipedia article on HSL and HSV: // Algorithm taken from the Wikipedia article on HSL and HSV:
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
let _0: T = cast(0); let _0: T = Float::from_float(0f);
let _1: T = cast(1); let _1: T = Float::from_float(1f);
let _2: T = cast(2); let _2: T = Float::from_float(2f);
let chr = color.v * color.s; let chr = color.v * color.s;
let h_ = *(color.h) / cast(60); // TODO: it'd be nice if Degrees / Degrees returned a scalar let h_ = (* color.h) / Float::from_float(60f); // TODO: it'd be nice if Degrees / Degrees returned a scalar
// the 2nd largest component // the 2nd largest component
let x = chr * (_1 - ((h_ % _2) - _1).abs()); let x = chr * (_1 - ((h_ % _2) - _1).abs());
let mut color_rgb = let mut color_rgb =
if h_ < cast(1) { RGB::new(chr, x, _0) } if h_ < Float::from_float(1f) { RGB::new(chr, x, _0) }
else if h_ < cast(2) { RGB::new( x, chr, _0) } else if h_ < Float::from_float(2f) { RGB::new( x, chr, _0) }
else if h_ < cast(3) { RGB::new( _0, chr, x) } else if h_ < Float::from_float(3f) { RGB::new( _0, chr, x) }
else if h_ < cast(4) { RGB::new( _0, x, chr) } else if h_ < Float::from_float(4f) { RGB::new( _0, x, chr) }
else if h_ < cast(5) { RGB::new( x, _0, chr) } else if h_ < Float::from_float(5f) { RGB::new( x, _0, chr) }
else if h_ < cast(6) { RGB::new(chr, _0, x) } else if h_ < Float::from_float(6f) { RGB::new(chr, _0, x) }
else { RGB::new( _0, _0, _0) }; else { RGB::new( _0, _0, _0) };
// match the value by adding the same amount to each component // match the value by adding the same amount to each component