rgbToHSV :: (Fractional t, Ord t) => RGB t -> HSV t
rgbToHSV (RGB r g b) = HSV h' s v
  where
  ub = max r (max g b)
  lb = min r (min g b)

  h  | ub == lb  = 0
     | ub == r   = 60 * (    (g-b)/(ub-lb))
     | ub == g   = 60 * (2 + (b-r)/(ub-lb))
     | otherwise = 60 * (4 + (r-g)/(ub-lb))

  h' | h < 0 = h + 360
     | otherwise = h

  s  | ub == 0   = 0
     | otherwise = (ub-lb)/ub

  v  = ub

-- | HSV to RGB conversion.
-- Pre: 0 <= h <= 360 and 0 <= s,v <= 1
-- (Source: http://de.wikipedia.org/wiki/HSV-Farbraum)
rgbToHSV :: (Fractional t, Ord t) => RGB t -> HSV t
rgbToHSV (RGB r g b) = HSV h' s v
  where
  ub = max r (max g b)
  lb = min r (min g b)

  h  | ub == lb  = 0
     | ub == r   = 60 * (    (g-b)/(ub-lb))
     | ub == g   = 60 * (2 + (b-r)/(ub-lb))
     | otherwise = 60 * (4 + (r-g)/(ub-lb))

  h' | h < 0 = h + 360
     | otherwise = h

  s  | ub == 0   = 0
     | otherwise = (ub-lb)/ub

  v  = ub

-- | HSV to RGB conversion.
-- Pre: 0 <= h <= 360 and 0 <= s,v <= 1
-- (Source: http://de.wikipedia.org/wiki/HSV-Farbraum)
rgbToHSV (RGB r g b) = HSV h' s v
  where
  ub = max r (max g b)
  lb = min r (min g b)

  h  | ub == lb  = 0
     | ub == r   = 60 * (    (g-b)/(ub-lb))
     | ub == g   = 60 * (2 + (b-r)/(ub-lb))
     | otherwise = 60 * (4 + (r-g)/(ub-lb))

  h' | h < 0 = h + 360
     | otherwise = h

  s  | ub == 0   = 0
     | otherwise = (ub-lb)/ub

  v  = ub

-- | HSV to RGB conversion.
-- Pre: 0 <= h <= 360 and 0 <= s,v <= 1
-- (Source: http://de.wikipedia.org/wiki/HSV-Farbraum)