{-# LANGUAGE RecordWildCards #-} module Blucontrol.RGB.Temperature ( Temperature ) where import Control.DeepSeq import Data.Default import GHC.Generics import Blucontrol.RGB -- | Arbitrary precision temperature in Kelvin newtype Temperature = Temperature Rational deriving (Enum, Eq, Fractional, Generic, Num, Ord, Read, Real, RealFrac, Show) instance NFData Temperature instance Bounded Temperature where minBound = 0 maxBound = 20000 instance Default Temperature where def = 6600 instance RGB Temperature where -- TODO: test and implement more accurate, currently based on blugon toRGB (Temperature temp) = Trichromaticity {..} where red = round . inBounds $ if t <= 66 then 255 else 329.698727446 * ((t - 60) ** (-0.1332047592)) green = round . inBounds $ if t <= 66 then 99.4708025861 * log t - 161.1195681661 else 288.1221695283 * ((t - 60) ** (-0.0755148492)) blue = round . inBounds $ if t <= 0 then 0 else if t >= 66 then 255 else 138.5177312231 * log (t - 10) - 305.0447927307 t = fromRational $ temp / 100 :: Double inBounds x | x < 0 = 0 | x > 255 = 255 | otherwise = x