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

72 lines
1.6 KiB

module Maths
( dotP,
lengthSquared,
unitVector,
randV3,
rand,
reflect,
refract,
reflectance,
clamp,
)
where
import Control.Monad.Random
import Control.Monad.State (State, evalState, get, put)
import Debug.Trace
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 :: (Floating a) => a -> a
degToRadians d = (d * pi) / 180.0
dotP :: (Num a) => V3 a -> V3 a -> a
dotP (V3 a b c) (V3 d e f) = a * d + b * e + c * f
lengthSquared :: (Num a) => V3 a -> a
lengthSquared (V3 x y z) = x ^ 2 + y ^ 2 + z ^ 2
vectorLength :: (Floating f) => V3 f -> f
vectorLength v = sqrt (lengthSquared v)
unitVector :: (Floating f) => V3 f -> V3 f
unitVector v = v ^/ vectorLength v
reflect :: (Floating f) => V3 f -> V3 f -> V3 f
reflect v n = v - (2 * (v `dotP` n)) *^ n
refract :: (RealFloat f) => V3 f -> V3 f -> f -> V3 f
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