You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
haskell-raytracer/src/Maths.hs

70 lines
1.5 KiB

module Maths
( dotP,
lengthSquared,
unitVector,
randV3,
rand,
reflect,
refract,
reflectance,
clamp,
)
where
import Control.Monad.Random
import Linear.V3
import Linear.Vector
import System.Random
rand :: (RandomGen g) => Rand g Double
rand = getRandomR (-1.0, 1.0 :: Double)
randV3 :: (RandomGen g) => Rand g (V3 Double)
randV3 = do
x <- rand
y <- rand
z <- rand
if vectorLength (V3 x y z) >= 1.0
then randV3
else return $ unitVector (V3 x y z)
-- _ -> randV3
--inf = read "Infinity"
degToRadians :: Double -> Double
degToRadians d = (d * pi) / 180.0
dotP :: V3 Double -> V3 Double -> Double
dotP (V3 a b c) (V3 d e f) = a * d + b * e + c * f
lengthSquared :: V3 Double -> Double
lengthSquared (V3 x y z) = x ^ 2 + y ^ 2 + z ^ 2
vectorLength :: V3 Double -> Double
vectorLength v = sqrt (lengthSquared v)
unitVector :: V3 Double -> V3 Double
unitVector v = v ^/ vectorLength v
reflect :: V3 Double -> V3 Double -> V3 Double
reflect v n = v - (2 * (v `dotP` n)) *^ n
refract :: V3 Double -> V3 Double -> Double -> V3 Double
refract uv n etai_over_etat = perp ^+^ parallel
where
ct = min (uv `dotP` n) 1.0
perp = etai_over_etat *^ ((-1.0 *^ uv) ^+^ (ct *^ n))
parallel = -1.0 * sqrt (abs (1.0 - lengthSquared perp)) *^ n
reflectance :: Double -> Double -> Double
reflectance c r = r00 + (1 - r00) * (1 - c) ^ 5
where
r0 = (1 - r) / (1 + r)
r00 = r0 * r0
clamp :: Double -> Double -> Double -> Double
clamp x mi ma
| x < mi = mi
| x > ma = ma
| otherwise = x