{-# LANGUAGE Strict #-}

-- |
-- Maintainer: Jeremy Nuttall <jeremy@jeremy-nuttall.com>
-- Stability : experimental
module Numeric.Noise.Perlin (
  -- * 2D
  noise2,
  noise2Base,

  -- * 3D
  noise3,
  noise3Base,
)
where

import Numeric.Noise.Internal
import Numeric.Noise.Internal.Math

noise2 :: (RealFrac a) => Noise2 a
noise2 :: forall a. RealFrac a => Noise2 a
noise2 = (Seed -> a -> a -> a) -> Noise2 a
forall a. (Seed -> a -> a -> a) -> Noise2 a
Noise2 Seed -> a -> a -> a
forall a. RealFrac a => Seed -> a -> a -> a
noise2Base
{-# INLINE noise2 #-}

noise2Base :: forall a. (RealFrac a) => Seed -> a -> a -> a
noise2Base :: forall a. RealFrac a => Seed -> a -> a -> a
noise2Base Seed
seed a
x a
y =
  let x0 :: Hash
x0 = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
x
      y0 :: Hash
y0 = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
y

      xd0 :: a
xd0 = a
x a -> a -> a
forall a. Num a => a -> a -> a
- Hash -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Hash
x0
      yd0 :: a
yd0 = a
y a -> a -> a
forall a. Num a => a -> a -> a
- Hash -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Hash
y0
      xd1 :: a
xd1 = a
xd0 a -> a -> a
forall a. Num a => a -> a -> a
- a
1
      yd1 :: a
yd1 = a
yd0 a -> a -> a
forall a. Num a => a -> a -> a
- a
1

      u :: a
u = a -> a
forall a. Num a => a -> a
quinticInterp a
xd0
      v :: a
v = a -> a
forall a. Num a => a -> a
quinticInterp a
yd0

      x0p :: Hash
x0p = Hash
x0 Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeX
      y0p :: Hash
y0p = Hash
y0 Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeY

      x1p :: Hash
x1p = Hash
x0p Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeX
      y1p :: Hash
y1p = Hash
y0p Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeY
   in a
1.4247691104677813
        a -> a -> a
forall a. Num a => a -> a -> a
* a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
          ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
              (Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
x0p Hash
y0p a
xd0 a
yd0)
              (Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
x1p Hash
y0p a
xd1 a
yd0)
              a
u
          )
          ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
              (Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
x0p Hash
y1p a
xd0 a
yd1)
              (Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
x1p Hash
y1p a
xd1 a
yd1)
              a
u
          )
          a
v
{-# INLINE noise2Base #-}

noise3 :: (RealFrac a) => Noise3 a
noise3 :: forall a. RealFrac a => Noise3 a
noise3 = (Seed -> a -> a -> a -> a) -> Noise3 a
forall a. (Seed -> a -> a -> a -> a) -> Noise3 a
Noise3 Seed -> a -> a -> a -> a
forall a. RealFrac a => Seed -> a -> a -> a -> a
noise3Base
{-# INLINE noise3 #-}

noise3Base :: (RealFrac a) => Seed -> a -> a -> a -> a
noise3Base :: forall a. RealFrac a => Seed -> a -> a -> a -> a
noise3Base Seed
seed a
x a
y a
z =
  let x0 :: Hash
x0 = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
x
      y0 :: Hash
y0 = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
y
      z0 :: Hash
z0 = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
z

      xd0 :: a
xd0 = a
x a -> a -> a
forall a. Num a => a -> a -> a
- Hash -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Hash
x0
      yd0 :: a
yd0 = a
y a -> a -> a
forall a. Num a => a -> a -> a
- Hash -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Hash
y0
      zd0 :: a
zd0 = a
z a -> a -> a
forall a. Num a => a -> a -> a
- Hash -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Hash
z0

      xd1 :: a
xd1 = a
xd0 a -> a -> a
forall a. Num a => a -> a -> a
- a
1
      yd1 :: a
yd1 = a
yd0 a -> a -> a
forall a. Num a => a -> a -> a
- a
1
      zd1 :: a
zd1 = a
zd0 a -> a -> a
forall a. Num a => a -> a -> a
- a
1

      u :: a
u = a -> a
forall a. Num a => a -> a
quinticInterp a
xd0
      v :: a
v = a -> a
forall a. Num a => a -> a
quinticInterp a
yd0
      w :: a
w = a -> a
forall a. Num a => a -> a
quinticInterp a
zd0

      x0p :: Hash
x0p = Hash
x0 Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeX
      y0p :: Hash
y0p = Hash
y0 Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeY
      z0p :: Hash
z0p = Hash
z0 Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeZ
      x1p :: Hash
x1p = Hash
x0p Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeX
      y1p :: Hash
y1p = Hash
y0p Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeY
      z1p :: Hash
z1p = Hash
z0p Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeZ
   in a
0.96492141485214233398437
        a -> a -> a
forall a. Num a => a -> a -> a
* a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
          ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
              ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x0p Hash
y0p Hash
z0p a
xd0 a
yd0 a
zd0)
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x1p Hash
y0p Hash
z0p a
xd1 a
yd0 a
zd0)
                  a
u
              )
              ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x0p Hash
y1p Hash
z0p a
xd0 a
yd1 a
zd0)
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x1p Hash
y1p Hash
z0p a
xd1 a
yd1 a
zd0)
                  a
u
              )
              a
v
          )
          ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
              ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x0p Hash
y0p Hash
z1p a
xd0 a
yd0 a
zd1)
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x1p Hash
y0p Hash
z1p a
xd1 a
yd0 a
zd1)
                  a
u
              )
              ( a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x0p Hash
y1p Hash
z1p a
xd0 a
yd1 a
zd1)
                  (Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
forall a.
RealFrac a =>
Seed -> Hash -> Hash -> Hash -> a -> a -> a -> a
gradCoord3 Seed
seed Hash
x1p Hash
y1p Hash
z1p a
xd1 a
yd1 a
zd1)
                  a
u
              )
              a
v
          )
          a
w
{-# INLINE noise3Base #-}