packages feed

hsnoise 0.0.1 → 0.0.2

raw patch · 7 files changed

+206/−55 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Numeric.Noise.Perlin: Perlin :: Seed -> Int -> Double -> Double -> Perlin
+ Numeric.Noise: clamp :: Ord a => a -> a -> a -> a
+ Numeric.Noise: pmap :: (Double -> Double) -> Point -> Point
+ Numeric.Noise.Perlin: perlin :: Seed -> Int -> Double -> Double -> Perlin
+ Numeric.Noise.Ridged: data Ridged
+ Numeric.Noise.Ridged: instance Noise Ridged
+ Numeric.Noise.Ridged: noiseValue :: Noise a => a -> Point -> Double
+ Numeric.Noise.Ridged: ridged :: Seed -> Int -> Double -> Double -> Double -> Ridged

Files

examples/Perlin.hs view
@@ -1,9 +1,9 @@-module Perlin where+module Main where -import Noise.Perlin+import Numeric.Noise.Perlin  import Codec.PPM.Binary-import Data.Word+import Data.Word (Word8)  main = do     -- The size of the resulting image.@@ -16,11 +16,11 @@     let persistance = 0.5      -- Create the perlin function.-    let perlin = Perlin seed octaves scale persistance    +    let perlinNoise = perlin seed octaves scale persistance          -- Compute the noise value for each pixel in the image.     let coords = [1.0..fromInteger size]-    let xs = [noiseValue perlin (x, y, 0) | y <- coords, x <- coords]+    let xs = [noiseValue perlinNoise (x, y, 0) | y <- coords, x <- coords]          -- Convert the noise values to grayscale colors.     let ps = map noiseToColor xs
+ examples/Ridged.hs view
@@ -0,0 +1,39 @@+module Main where++import Numeric.Noise.Ridged++import Codec.PPM.Binary+import Data.Word (Word8)++main = do+    -- The size of the resulting image.+    let size = 200++    -- Parameters for the noise function.+    let seed = 1+    let octaves = 5+    let scale = 0.05+    let frequency = 1+    let lacunarity = 2++    -- Create the ridged multi-fractal function.+    let ridgedNoise = ridged seed octaves scale frequency lacunarity ++    -- Compute the noise value for each pixel in the image.+    let coords = [1.0..fromInteger size]+    let xs = [noiseValue ridgedNoise (x, y, 0) | y <- coords, x <- coords]++    putStrLn (show (maximum xs))+    putStrLn (show (minimum xs))+    +    -- Convert the noise values to grayscale colors.+    let ps = map noiseToColor xs+    +    -- Write the image.+    writePPM "Noise.ppm" (size, size) ps+    return ()++-- Converts a value from -1 to 1 to a gray 24-bit color value from 0 to 255.+noiseToColor :: Double -> (Word8, Word8, Word8)+noiseToColor n = (n', n', n')+    where n' = fromInteger (floor ((n * 0.5 + 0.5) * 255)) :: Word8
hsnoise.cabal view
@@ -1,5 +1,5 @@ name:               hsnoise-version:            0.0.1+version:            0.0.2  cabal-version:      >= 1.2.3 build-type:         Simple@@ -17,8 +17,8 @@ synopsis:           A coherent 3d noise library.  description:        A coherent 3d noise library loosely based on libnoise.  Currently has an-                    implementation of perlin noise.  Will eventually support other noise-                    types as well as noise function combinations.+                    implementation of Perlin noise and ridged multi-fractal noise.  Will +                    eventually support other noise types as well as noise function combinations.                     .                     Code examples included in package.                     .@@ -27,12 +27,11 @@  category:           Noise -extra-source-files: examples/Perlin.hs+extra-source-files: examples/Perlin.hs, examples/Ridged.hs  library-    exposed-modules:-        Numeric.Noise-        Numeric.Noise.Perlin-        Numeric.Noise.Random +    exposed-modules:    Numeric.Noise, Numeric.Noise.Perlin, Numeric.Noise.Random,+                        Numeric.Noise.Ridged      build-depends:      base >= 4 && < 5, vector -any     hs-source-dirs:     src+    ghc-options:        -Wall
src/Numeric/Noise.hs view
@@ -1,12 +1,16 @@ -- Copyright (c) 2011, Colin Hill--- Loosely based on implementation of Libnoise (libnoise.sourceforge.net)+--+-- Loosely based on implementation of libnoise by Jason Bevins Copyright (C) 2003, 2004+-- http://libnoise.sourceforge.net  -- | Contains 'Noise' class as well as a general coherent noise generating function which -- the specific noise implementations are based on. module Numeric.Noise (     Point,     Seed,-    Noise(..),+    Noise(noiseValue),+    pmap,+    clamp,     coherentNoise ) where @@ -24,9 +28,17 @@     -- | Maps 3-space points to a noise value between -1 and 1 for the given noise function.     noiseValue :: a -> Point -> Double +-- | Map a function on a 'Point'.+pmap :: (Double -> Double) -> Point -> Point+pmap f (x, y, z) = (f x, f y, f z)++-- | Returns a clamped value between a min and max value.+clamp :: Ord a => a -> a -> a -> a+clamp v m m' = max m (min m' v)+ -- | Returns a coherent noise value between -1 and 1 given a seed and a point in 3-space. coherentNoise :: Seed -> Point -> Double-coherentNoise seed (x, y, z) = max (-1.0) (min 1.0 (lerp sz iy0 iy1))+coherentNoise seed (x, y, z) = clamp noise (-1) 1     where (ox, oy, oz) = (clampToIntRange x, clampToIntRange y, clampToIntRange z)           x0           = if ox > 0.0 then floor ox else floor ox - 1           x1           = x0 + 1@@ -39,30 +51,31 @@           sz           = scurve (oz - fromIntegral z0)           n0           = gradientNoise seed ox oy oz x0 y0 z0           n1           = gradientNoise seed ox oy oz x1 y0 z0+          n2           = gradientNoise seed ox oy oz x0 y1 z0+          n3           = gradientNoise seed ox oy oz x1 y1 z0+          n4           = gradientNoise seed ox oy oz x0 y0 z1+          n5           = gradientNoise seed ox oy oz x1 y0 z1+          n6           = gradientNoise seed ox oy oz x0 y1 z1+          n7           = gradientNoise seed ox oy oz x1 y1 z1           ix0          = lerp sx n0 n1-          n0'          = gradientNoise seed ox oy oz x0 y1 z0-          n1'          = gradientNoise seed ox oy oz x1 y1 z0-          ix1          = lerp sx n0' n1'+          ix1          = lerp sx n2 n3+          ix2          = lerp sx n4 n5+          ix3          = lerp sx n6 n7           iy0          = lerp sy ix0 ix1-          n0''         = gradientNoise seed ox oy oz x0 y0 z1-          n1''         = gradientNoise seed ox oy oz x1 y0 z1-          ix0'         = lerp sx n0'' n1''-          n0'''        = gradientNoise seed ox oy oz x0 y1 z1-          n1'''        = gradientNoise seed ox oy oz x1 y1 z1-          ix1'         = lerp sx n0''' n1'''-          iy1          = lerp sy ix0' ix1'+          iy1          = lerp sy ix2 ix3+          noise        = lerp sz iy0 iy1  -- | Returns a gradient noise value given a seed, a point in 3-space, and a nearby integer -- point in 3-space. gradientNoise :: Seed -> Double -> Double -> Double -> Int -> Int -> Int -> Double gradientNoise seed fx fy fz ix iy iz = 2.12 * (gx * ox + gy * oy + gz * oz)-    where (gx, gy, gz) = (vectorTable ! (shiftL i 2),-                          vectorTable ! ((shiftL i 2) + 1),-                          vectorTable ! ((shiftL i 2) + 2))+    where (gx, gy, gz) = (vectorTable ! shiftL i 2,+                          vectorTable ! (shiftL i 2 + 1),+                          vectorTable ! (shiftL i 2 + 2))           (ox, oy, oz) = (fx - fromIntegral ix,                           fy - fromIntegral iy,                           fz - fromIntegral iz)-          i            = (i' `xor` (shiftR i' 8)) .&. 0xff+          i            = (i' `xor` shiftR i' 8) .&. 0xff           i'           = (1619 * ix + 31337 * iy + 6971 * iz + 1013 * seed) .&. 0xffffffff  -- | Returns the linearly interpolated value between two values given a delta.@@ -76,15 +89,16 @@           a4 = a3 * a           a5 = a4 * a --- | Clamps a 'Double' to the range of a 32 bit 'Int'.+-- | Clamps a 'Double' to the range of an 'Int'. clampToIntRange :: Double -> Double-clampToIntRange n | n >=   1073741824.0  = 2.0 * (fmod n 1073741824.0) - 1073741824.0-                  | n <= (-1073741824.0) = 2.0 * (fmod n 1073741824.0) + 1073741824.0+clampToIntRange n | n >= maxInt    = 2.0 * fmod n maxInt - maxInt+                  | n <= (-maxInt) = 2.0 * fmod n maxInt + maxInt                   | otherwise            = n+    where maxInt = 1073741824.0 -- Max 32 bit signed Int.  Should not be hardcoded.  -- | Floating point modulus function. fmod :: Double -> Double -> Double-fmod x y = x - fromIntegral (floor (x / y)) * y+fmod x y = x - fromIntegral (floor (x / y) :: Int) * y  -- | Table of random normalized vectors. vectorTable :: Vector Double
src/Numeric/Noise/Perlin.hs view
@@ -1,32 +1,47 @@ -- Copyright (c) 2011, Colin Hill  -- | Implementation of Perlin noise.+--+-- Example of use:+--+-- @+--main = putStrLn (\"Noise value at (1, 2, 3): \" ++ show x)+--    where seed        = 1+--          octaves     = 5+--          scale       = 0.05+--          persistance = 0.5+--          perlinNoise = perlin seed octaves scale persistance+--          x           = noiseValue perlinNoise (1, 2, 3)+-- @ module Numeric.Noise.Perlin (-    Perlin(..),+    Perlin,+    perlin,     noiseValue ) where  import Numeric.Noise --- | Perlin noise function.-data Perlin =-    -- | Constructs a perlin noise function given a 'Seed', number of octaves, scale, and -    -- persistance.-    Perlin Seed Int Double Double+-- | A Perlin noise function.+data Perlin = Perlin Seed Int Double Double --- | Implementation of 'Noise' for 'Perlin'. instance Noise Perlin where-    -- | Returns a perlin noise value given a 'Perlin' function and a point.-    noiseValue nf xyz = max (-1.0) (min 1.0 noise)-        where Perlin _ octs _ _ = nf-              noise             = perlinNoise nf octs 0 1.0 1.0 xyz+    noiseValue perlinNoise xyz = clamp noise (-1) 1+        where Perlin _ octs _ _ = perlinNoise+              noise             = perlinNoiseValue perlinNoise octs 1 1 xyz --- | Evaluates a given number of octaves of perlin noise holding the total, amplitude--- and frequency in the arguments.-perlinNoise :: Perlin -> Int -> Double -> Double -> Double -> Point -> Double-perlinNoise nf 0 t freq amp xyz = t-perlinNoise nf o t freq amp xyz = t + perlinNoise nf (o - 1) t' (freq * 2.0) (amp * persist) xyz-    where Perlin seed _ scale persist = nf-          (x, y, z)                   = xyz-          (x', y', z')                = (x * scale * freq, y * scale * freq, z * scale * freq)-          t'                          = coherentNoise seed (x', y', z') * amp+-- | Constructs a Perlin noise function given a seed, number of octaves, scale, and persistance.+perlin :: Seed -> Int -> Double -> Double -> Perlin+perlin = Perlin++-- | Evaluates a given number of octaves of perlin noise holding the frequency and amplitude in +-- the arguments.+perlinNoiseValue :: Perlin -> Int -> Double -> Double -> Point -> Double+perlinNoiseValue _           0   _    _   _   = 0+perlinNoiseValue perlinNoise oct freq amp xyz = noise + noise'+    where Perlin seed _ scale pers = perlinNoise+          oct'   = oct - 1+          freq'  = freq * 2+          amp'   = amp * pers+          xyz'   = pmap (* (scale * freq)) xyz+          noise  = coherentNoise seed xyz' * amp+          noise' = perlinNoiseValue perlinNoise oct' freq' amp' xyz
src/Numeric/Noise/Random.hs view
@@ -1,6 +1,19 @@ -- Copyright (c) 2011, Colin Hill  -- | A simple implementation of a pure linear congruential psuedo-random number generator.+--+-- Example of use:+--+-- @+--main = do+--    let seed = 1+--    let (r, seed') = randomInt seed+--    putStrLn (\"Random number 1: \" ++ show r)+--    let (r', seed'') = randomInt seed'+--    putStrLn (\"Random number 2: \" ++ show r')+--    putStrLn (\"Random int list: \" ++ show (randomInts 10 seed))+--    putStrLn (\"Shuffled list: \" ++ show (shuffle [1..10] seed))+-- @ module Numeric.Noise.Random (     randomInt,     randomInts,@@ -37,4 +50,4 @@ shuffle' [] acc seed = (acc, seed) shuffle' xs acc seed = shuffle' (h ++ ys) (y:acc) seed'     where (seed', r) = randomInt seed-          (h, y:ys)  = splitAt (r `mod` (length xs)) xs+          (h, y:ys)  = splitAt (r `mod` length xs) xs
+ src/Numeric/Noise/Ridged.hs view
@@ -0,0 +1,71 @@+-- Copyright (c) 2011, Colin Hill++-- | Implementation of ridged multi-fractal noise.+--+-- Example of use:+--+-- @+--main = putStrLn (\"Noise value at (1, 2, 3): \" ++ show x)+--    where seed        = 1+--          octaves     = 5+--          scale       = 0.005+--          frequency   = 1+--          lacunarity  = 2+--          ridgedNoise = ridged seed octaves scale frequency lacunarity+--          x           = noiseValue ridgedNoise (1, 2, 3)+-- @+module Numeric.Noise.Ridged (+    Ridged,+    ridged,+    noiseValue+) where++import Numeric.Noise++import Data.Bits ((.&.))+import Data.Vector.Unboxed (Vector, fromList, (!))++-- | A ridged multi-fractal noise function.+data Ridged = Ridged Seed Int Double Double Double (Vector Double)++-- | Constructs a ridged multi-fractal noise function given a seed, number of octaves, scale, +-- frequency, and lacunarity.+ridged :: Seed -> Int -> Double -> Double -> Double -> Ridged+ridged seed octs scale freq lac = ridgedNoise+    where specWeights = computeSpecWeights octs lac+          ridgedNoise = Ridged seed octs scale freq lac specWeights++instance Noise Ridged where+    noiseValue ridgedNoise xyz = clamp noise (-1) 1+        where Ridged _ octs scale freq _ _ = ridgedNoise+              xyz'  = pmap (* (scale * freq)) xyz+              noise = ridgedNoiseValue ridgedNoise octs 1 xyz' * 1.25 - 1++-- | Computes the noise value for a ridged multi-fractal noise function given the octave number, +-- the weight, and the point.+ridgedNoiseValue :: Ridged -> Int -> Double -> Point -> Double+ridgedNoiseValue _           0   _      _   = 0+ridgedNoiseValue ridgedNoise oct weight xyz = noise + noise'+    where Ridged seed octs _ _ lac specWeights = ridgedNoise+          oct'    = oct - 1+          xyz'    = pmap (* lac) xyz+          seed'   = (seed + (octs - oct)) .&. 0x7fffffff+          signal  = (offset - abs (coherentNoise seed' xyz)) * weight * weight+          weight' = clamp (signal * gain) 0 1+          noise   = signal * (specWeights ! (octs - oct))+          noise'  = ridgedNoiseValue ridgedNoise oct' weight' xyz'+          gain    = 2+          offset  = 1++-- | Computes the spectral weight for each oct given the number of octs and the lac.+computeSpecWeights :: Int -> Double -> Vector Double+computeSpecWeights octs lac = fromList (computeSpecWeights' octs lac 1)++-- | Helper for 'computeSpecWeights'.+computeSpecWeights' :: Int -> Double -> Double -> [Double]+computeSpecWeights' 0   _   _    = []+computeSpecWeights' oct lac freq = weight : weights+    where freq'   = freq * lac+          oct'    = oct - 1+          weight  = freq ** (-1)+          weights = computeSpecWeights' oct' lac freq'