{-# LANGUAGE Strict #-}

-- |
-- Maintainer: Jeremy Nuttall <jeremy@jeremy-nuttall.com>
-- Stability: experimental
--
-- This module implements a variation of OpenSimplex2 noise derived from FastNoiseLite.
module Numeric.Noise.OpenSimplex (
  -- * 2D Noise
  noise2,
  noise2Base,
) 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 :: (RealFrac a) => Seed -> a -> a -> a
noise2Base :: forall a. RealFrac a => Seed -> a -> a -> a
noise2Base Seed
seed a
xo a
yo =
  let f2 :: a
f2 = a
0.5 a -> a -> a
forall a. Num a => a -> a -> a
* (a
forall a. Fractional a => a
sqrt3 a -> a -> a
forall a. Num a => a -> a -> a
- a
1)
      to :: a
to = (a
xo a -> a -> a
forall a. Num a => a -> a -> a
+ a
yo) a -> a -> a
forall a. Num a => a -> a -> a
* a
f2
      x :: a
x = a
xo a -> a -> a
forall a. Num a => a -> a -> a
+ a
to
      y :: a
y = a
yo a -> a -> a
forall a. Num a => a -> a -> a
+ a
to

      fx :: Hash
fx = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
x
      fy :: Hash
fy = a -> Hash
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a
y
      xi :: a
xi = 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
fx
      yi :: a
yi = 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
fy

      t :: a
t = (a
xi a -> a -> a
forall a. Num a => a -> a -> a
+ a
yi) a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Fractional a => a
g2
      x0 :: a
x0 = a
xi a -> a -> a
forall a. Num a => a -> a -> a
- a
t
      y0 :: a
y0 = a
yi a -> a -> a
forall a. Num a => a -> a -> a
- a
t
      i :: Hash
i = Hash
fx Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeX
      j :: Hash
j = Hash
fy Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
* Hash
primeY

      a :: a
a = a
0.5 a -> a -> a
forall a. Num a => a -> a -> a
- a
x0 a -> a -> a
forall a. Num a => a -> a -> a
* a
x0 a -> a -> a
forall a. Num a => a -> a -> a
- a
y0 a -> a -> a
forall a. Num a => a -> a -> a
* a
y0
      n0 :: a
n0
        | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 = a
0
        | Bool
otherwise =
            (a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
a)
              a -> a -> a
forall a. Num a => a -> a -> a
* (a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
a)
              a -> a -> a
forall a. Num a => a -> a -> a
* Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
i Hash
j a
x0 a
y0

      n1 :: a
n1
        | a
y0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
x0 =
            let ~a
x1 = a
x0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
forall a. Fractional a => a
g2
                ~Hash
i1 = Hash
i
                ~a
y1 = a
y0 a -> a -> a
forall a. Num a => a -> a -> a
+ (a
forall a. Fractional a => a
g2 a -> a -> a
forall a. Num a => a -> a -> a
- a
1)
                ~Hash
j1 = Hash
j Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeY
                ~a
b = a
0.5 a -> a -> a
forall a. Num a => a -> a -> a
- a
x1 a -> a -> a
forall a. Num a => a -> a -> a
* a
x1 a -> a -> a
forall a. Num a => a -> a -> a
- a
y1 a -> a -> a
forall a. Num a => a -> a -> a
* a
y1
             in if a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0
                  then a
0
                  else
                    (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
b)
                      a -> a -> a
forall a. Num a => a -> a -> a
* (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
b)
                      a -> a -> a
forall a. Num a => a -> a -> a
* Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
i1 Hash
j1 a
x1 a
y1
        | Bool
otherwise =
            let ~a
x1 = a
x0 a -> a -> a
forall a. Num a => a -> a -> a
+ (a
forall a. Fractional a => a
g2 a -> a -> a
forall a. Num a => a -> a -> a
- a
1)
                ~Hash
i1 = Hash
i Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeX
                ~a
y1 = a
y0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
forall a. Fractional a => a
g2
                ~Hash
j1 = Hash
j
                ~a
b = a
0.5 a -> a -> a
forall a. Num a => a -> a -> a
- a
x1 a -> a -> a
forall a. Num a => a -> a -> a
* a
x1 a -> a -> a
forall a. Num a => a -> a -> a
- a
y1 a -> a -> a
forall a. Num a => a -> a -> a
* a
y1
             in if a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0
                  then a
0
                  else
                    (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
b)
                      a -> a -> a
forall a. Num a => a -> a -> a
* (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
b)
                      a -> a -> a
forall a. Num a => a -> a -> a
* Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed Hash
i1 Hash
j1 a
x1 a
y1

      c :: a
c =
        let g2t :: a
g2t = a
1 a -> a -> a
forall a. Num a => a -> a -> a
- a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Fractional a => a
g2
         in a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
g2t a -> a -> a
forall a. Num a => a -> a -> a
* (a
1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
forall a. Fractional a => a
g2 a -> a -> a
forall a. Num a => a -> a -> a
- a
2) a -> a -> a
forall a. Num a => a -> a -> a
* a
t
              a -> a -> a
forall a. Num a => a -> a -> a
+ (-a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
g2t a -> a -> a
forall a. Num a => a -> a -> a
* a
g2t a -> a -> a
forall a. Num a => a -> a -> a
+ a
a)
      n2 :: a
n2
        | a
c a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 = a
0
        | Bool
otherwise =
            let ~a
x2 = a
x0 a -> a -> a
forall a. Num a => a -> a -> a
+ (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Fractional a => a
g2 a -> a -> a
forall a. Num a => a -> a -> a
- a
1)
                ~a
y2 = a
y0 a -> a -> a
forall a. Num a => a -> a -> a
+ (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Fractional a => a
g2 a -> a -> a
forall a. Num a => a -> a -> a
- a
1)
             in (a
c a -> a -> a
forall a. Num a => a -> a -> a
* a
c)
                  a -> a -> a
forall a. Num a => a -> a -> a
* (a
c a -> a -> a
forall a. Num a => a -> a -> a
* a
c)
                  a -> a -> a
forall a. Num a => a -> a -> a
* Seed -> Hash -> Hash -> a -> a -> a
forall a. RealFrac a => Seed -> Hash -> Hash -> a -> a -> a
gradCoord2 Seed
seed (Hash
i Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeX) (Hash
j Hash -> Hash -> Hash
forall a. Num a => a -> a -> a
+ Hash
primeY) a
x2 a
y2
   in (a
n0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
n1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
n2) a -> a -> a
forall a. Num a => a -> a -> a
* a
99.83685446303647
{-# INLINE noise2Base #-}