updated the gitignore + cleanup
This commit is contained in:
parent
5d1deba9b9
commit
56d612f1e3
4 changed files with 29 additions and 357 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
*.hi
|
||||||
|
*.o
|
||||||
|
flame
|
||||||
|
flame.png
|
38
flame.elm
38
flame.elm
|
@ -8,6 +8,8 @@ import Random
|
||||||
l !! n = if n == 0 then head l else (tail l) !! (n-1)
|
l !! n = if n == 0 then head l else (tail l) !! (n-1)
|
||||||
-- negative of a number (I don't like writing 0-x).
|
-- negative of a number (I don't like writing 0-x).
|
||||||
neg x = 0-x
|
neg x = 0-x
|
||||||
|
-- too useful
|
||||||
|
concatmap f l = concat (map f l)
|
||||||
|
|
||||||
-- Colors (theme is solarized)
|
-- Colors (theme is solarized)
|
||||||
base03 = rgb 0 43 54
|
base03 = rgb 0 43 54
|
||||||
|
@ -32,9 +34,12 @@ mybase = rgba 108 113 196 (2/3)
|
||||||
|
|
||||||
-- draw a point at position (x,y)
|
-- draw a point at position (x,y)
|
||||||
point = filled mybase . rect 1 1
|
point = filled mybase . rect 1 1
|
||||||
|
colorpoint ((x,y),n) = filled (rgb n n n) . rect 1 1 $ (x,y)
|
||||||
|
|
||||||
|
|
||||||
-- fill the background with color base3
|
-- fill the background with color base3
|
||||||
background w h = filled base3 ( rect w h (div w 2,div h 2))
|
background w h = collage w h
|
||||||
|
[filled base03 $ rect w h (div w 2,div h 2)]
|
||||||
|
|
||||||
-- RANDOM PART
|
-- RANDOM PART
|
||||||
nextint n =
|
nextint n =
|
||||||
|
@ -112,27 +117,34 @@ rot phi = aff $ M (cos phi) (sin phi) 0.0 (neg (sin phi)) (cos phi) 0.0
|
||||||
zoom z = aff $ M z 0 0 0 z 0
|
zoom z = aff $ M z 0 0 0 z 0
|
||||||
|
|
||||||
-- The final transformation to transform the final result (zoom,rotate,translate)
|
-- The final transformation to transform the final result (zoom,rotate,translate)
|
||||||
final = trans (480,300) . zoom 500 . rot (neg 0.747)
|
final = trans (280,200) . zoom 300 . rot (neg 0.747)
|
||||||
|
|
||||||
sierpset startpoint rands =
|
sierpset startpoint rands tmpres =
|
||||||
if rands == []
|
if rands == []
|
||||||
then []
|
then tmpres
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
randval=(head rands) `rem` (length fs)
|
randval=(head rands) `rem` (length fs)
|
||||||
newpoint = (fs !! randval) startpoint
|
newpoint = (fs !! randval) startpoint
|
||||||
savepoint = final newpoint
|
roundPoint (x,y) = (round x,round y)
|
||||||
|
savepoint = roundPoint ( final newpoint )
|
||||||
|
oldvalue = Dict.lookup savepoint tmpres
|
||||||
|
newvalue = 1 + (Maybe.fromMaybe 0 oldvalue)
|
||||||
|
newtmpres = Dict.insert savepoint newvalue tmpres
|
||||||
in
|
in
|
||||||
savepoint:(sierpset newpoint (tail rands))
|
(sierpset newpoint (tail rands) newtmpres)
|
||||||
|
|
||||||
concatmap f l = concat (map f l)
|
sierpinsky = sierpset (0.0,0.0) (randlist 0 1000000) Dict.empty
|
||||||
sierpinsky = drop 30 $ concatmap (\s -> sierpset (0.0,0.0) (randlist s 4000)) [1..5]
|
|
||||||
|
|
||||||
scene (x,y) (w,h) =
|
scene (x,y) (w,h) =
|
||||||
let
|
let
|
||||||
inpoint (x,y) = x>=0 && x<=w && y>=0 && y<=h
|
inpoint ((x,y),_) = x>=0 && x<=w && y>=0 && y<=h
|
||||||
in collage w h $
|
in layers
|
||||||
background w h:
|
[ background w h
|
||||||
map point (filter inpoint sierpinsky)
|
, collage w h $
|
||||||
|
map colorpoint $
|
||||||
|
filter inpoint $
|
||||||
|
Dict.toList $ sierpinsky
|
||||||
|
]
|
||||||
|
|
||||||
main = scene <~ Mouse.position ~ Window.dimensions
|
main = scene (0,0) (500,500)
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
module Main where
|
|
||||||
|
|
||||||
import Data.HashMap as Dict -- cabal install HashMap
|
|
||||||
import Data.Maybe as Maybe
|
|
||||||
import Data.Word (Word8)
|
|
||||||
|
|
||||||
import Codec.Picture -- cabal install juicyPixels FTW
|
|
||||||
import Control.Monad
|
|
||||||
import System.Environment (getArgs)
|
|
||||||
data Global = Global { imgWidth :: Int
|
|
||||||
, imgHeight :: Int
|
|
||||||
, nbPoints :: Int }
|
|
||||||
|
|
||||||
type YMap = Map (Int,Int) Int
|
|
||||||
|
|
||||||
-- Basic functions
|
|
||||||
|
|
||||||
-- -- nth element of a list
|
|
||||||
-- l !! n = if n == 0 then head l else (tail l) !! (n-1)
|
|
||||||
-- negative of a number (I don't like writing 0-x).
|
|
||||||
neg x = 0-x
|
|
||||||
|
|
||||||
rgb :: Int -> Int -> Int -> (Int,Int,Int)
|
|
||||||
rgb = (,,)
|
|
||||||
rgba = (,,,)
|
|
||||||
-- Colors (theme is solarized)
|
|
||||||
base03 = rgb 0 43 54
|
|
||||||
base02 = rgb 7 54 66
|
|
||||||
base01 = rgb 88 110 117
|
|
||||||
base00 = rgb 101 123 131
|
|
||||||
base0 = rgb 131 148 150
|
|
||||||
base1 = rgb 147 161 161
|
|
||||||
base2 = rgb 238 232 213
|
|
||||||
base3 = rgb 253 246 227
|
|
||||||
yellow = rgb 181 137 0
|
|
||||||
orange = rgb 203 75 22
|
|
||||||
red = rgb 220 50 47
|
|
||||||
magenta = rgb 211 54 130
|
|
||||||
violet = rgb 108 113 196
|
|
||||||
blue = rgb 38 139 210
|
|
||||||
cyan = rgb 42 161 152
|
|
||||||
green = rgb 133 153 0
|
|
||||||
|
|
||||||
-- Default text color
|
|
||||||
mybase = rgba 108 113 196 (2/3)
|
|
||||||
|
|
||||||
-- RANDOM PART
|
|
||||||
nextint n =
|
|
||||||
let
|
|
||||||
a = 22695477
|
|
||||||
c = 1
|
|
||||||
m = 2^32
|
|
||||||
in
|
|
||||||
(a*n + c) `rem` m
|
|
||||||
|
|
||||||
-- generate a random sequence of length k starting with some seed
|
|
||||||
randlist seed k = if (k<0) then [] else (nextint seed):randlist (nextint seed) (k-1)
|
|
||||||
|
|
||||||
-- generate a random sequence of points of length k starting with some seed
|
|
||||||
randcouples seed k = if (k<0) then []
|
|
||||||
else
|
|
||||||
let ns = nextint seed
|
|
||||||
nns = nextint ns
|
|
||||||
in (ns,nns):randcouples nns (k-1)
|
|
||||||
-- END OF PSEUDO RANDOM NUMBER GENERATION
|
|
||||||
|
|
||||||
|
|
||||||
{-
|
|
||||||
- Flame Set
|
|
||||||
-
|
|
||||||
- S = U_{i} F_i(S)
|
|
||||||
-
|
|
||||||
- F_i being transformations
|
|
||||||
- General form:
|
|
||||||
- F = affine . linearcomp [variation] . affine
|
|
||||||
- affine is a linear function (x,y) -> (ax+by+c,dx+ey+f)
|
|
||||||
- variation is some kind of function with some contraction properties
|
|
||||||
ex: (x,y) -> (x,y), (sin x, sin y), etc...
|
|
||||||
- linearcomp [f] is a linear composition of functions: (x,y) -> Sum vi*f(x,y)
|
|
||||||
-}
|
|
||||||
|
|
||||||
data Matrice = M Float Float Float Float Float Float
|
|
||||||
aff (M a b c d e f) (x,y) = (a*x + b*y + c, d*x + e*y +f)
|
|
||||||
|
|
||||||
-- Some affine functions to generate the sierpinsky set
|
|
||||||
-- Equivalent to
|
|
||||||
-- sierp = [ \(x,y)->(x/2,y/2)
|
|
||||||
-- , \(x,y)->((x+1)/2,y/2)
|
|
||||||
-- , \(x,y)->(x/2,(y+1)/2) ]
|
|
||||||
sierp = [ aff $ M
|
|
||||||
0.5 0.0 0.0
|
|
||||||
0.0 0.5 0.0
|
|
||||||
, aff $ M
|
|
||||||
0.5 0.0 0.5
|
|
||||||
0.0 0.5 0.0
|
|
||||||
, aff $ M
|
|
||||||
0.5 0.0 0.0
|
|
||||||
0.0 0.5 0.5
|
|
||||||
]
|
|
||||||
|
|
||||||
-- Some variations
|
|
||||||
vs = [ \(x,y) -> (x,y)
|
|
||||||
, \(x,y) -> (sin x, sin y)
|
|
||||||
, \(x,y) -> let r2 = x*x+y*y in (x/r2,y/r2)
|
|
||||||
, \(x,y) -> let r2 = x*x+y*y in (x*(sin r2) - y*(cos r2),x*(cos r2) + y * (sin r2))
|
|
||||||
, \(x,y) -> let r = sqrt (x^2+y^2) in ((x - y)*(x + y)/r,2*x*y/r)
|
|
||||||
]
|
|
||||||
|
|
||||||
-- Some final functions
|
|
||||||
fs :: [(Float,Float) -> (Float,Float)]
|
|
||||||
fs = [ (vs !! 3) . (sierp !! 0)
|
|
||||||
, (vs !! 3) . (sierp !! 1)
|
|
||||||
, (vs !! 3) . (sierp !! 2)]
|
|
||||||
|
|
||||||
-- Transformation functions
|
|
||||||
-- translate
|
|
||||||
trans (tx,ty) = aff $ M 1 0 tx 0 1 ty
|
|
||||||
-- rotate
|
|
||||||
rot phi = aff $ M (cos phi) (sin phi) 0.0 (neg (sin phi)) (cos phi) 0.0
|
|
||||||
-- zoom
|
|
||||||
zoom z = aff $ M z 0 0 0 z 0
|
|
||||||
|
|
||||||
-- The final transformation to transform the final result (zoom,rotate,translate)
|
|
||||||
final = trans (280,200) . zoom 300 . rot (neg 0.747)
|
|
||||||
|
|
||||||
sierpset :: (Float,Float) -> [Int] -> YMap -> YMap
|
|
||||||
sierpset startpoint rands tmpres =
|
|
||||||
if rands == []
|
|
||||||
then tmpres
|
|
||||||
else
|
|
||||||
let
|
|
||||||
roundPoint (x,y) = (round x,round y)
|
|
||||||
randval=(head rands) `rem` (length fs)
|
|
||||||
newpoint = (fs !! randval) startpoint
|
|
||||||
savepoint = roundPoint ( final newpoint )
|
|
||||||
oldvalue = Dict.lookup savepoint tmpres
|
|
||||||
newvalue = 1 + (Maybe.fromMaybe 0 oldvalue)
|
|
||||||
newtmpres = savepoint `seq` newvalue `seq` Dict.insert savepoint newvalue tmpres
|
|
||||||
in
|
|
||||||
sierpset newpoint (tail rands) newtmpres
|
|
||||||
|
|
||||||
sierpinsky :: Int -> YMap
|
|
||||||
sierpinsky n = sierpset (0.0,0.0) (randlist 0 n) Dict.empty
|
|
||||||
|
|
||||||
scene env =
|
|
||||||
let
|
|
||||||
w = imgWidth env
|
|
||||||
h = imgHeight env
|
|
||||||
n = nbPoints env
|
|
||||||
inpoint ((x,y),_) = x>=0 && x<=w && y>=0 && y<=h
|
|
||||||
in (Prelude.filter inpoint) . Dict.toList $ (sierpinsky n)
|
|
||||||
|
|
||||||
|
|
||||||
initGlobalParams args =
|
|
||||||
Global { imgWidth = read (args !! 0)
|
|
||||||
, imgHeight = read (args !! 1)
|
|
||||||
, nbPoints = read (args !! 2) }
|
|
||||||
|
|
||||||
imageFromDict :: YMap -> Int -> Int -> Image PixelRGB8
|
|
||||||
imageFromDict dict width height = generateImage colorOfPoint width height
|
|
||||||
where
|
|
||||||
maxnb :: Int
|
|
||||||
maxnb = Dict.fold max 0 dict
|
|
||||||
colorOfPoint :: Int -> Int -> PixelRGB8
|
|
||||||
colorOfPoint x y = let nb = fromMaybe 0 (Dict.lookup (x,y) dict)
|
|
||||||
val :: Word8
|
|
||||||
val = fromIntegral $ div (255*nb) maxnb
|
|
||||||
in if nb == 0 then PixelRGB8 0 0 0
|
|
||||||
else PixelRGB8 val val val
|
|
||||||
|
|
||||||
writeImage :: Int -> Int -> Int -> YMap -> IO ()
|
|
||||||
writeImage w h n dict = writePng "flame.png" $ imageFromDict dict w h
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
args <- getArgs
|
|
||||||
if (length args<3)
|
|
||||||
then print $ "Usage flame w h n"
|
|
||||||
else do
|
|
||||||
env <- return (initGlobalParams args)
|
|
||||||
w <- return (imgWidth env)
|
|
||||||
h <- return (imgHeight env)
|
|
||||||
n <- return (nbPoints env)
|
|
||||||
-- mapM_ (print) (scene env)
|
|
||||||
writeImage w h n (sierpinsky n)
|
|
159
haskell/flame.hs
159
haskell/flame.hs
|
@ -1,159 +0,0 @@
|
||||||
module Main where
|
|
||||||
|
|
||||||
import Data.HashMap as Dict
|
|
||||||
import Data.Maybe as Maybe
|
|
||||||
|
|
||||||
import Control.Monad
|
|
||||||
import System.Environment (getArgs)
|
|
||||||
data Global = Global { imgWidth :: Int
|
|
||||||
, imgHeight :: Int
|
|
||||||
, nbPoints :: Int }
|
|
||||||
|
|
||||||
-- Basic functions
|
|
||||||
|
|
||||||
-- -- nth element of a list
|
|
||||||
-- l !! n = if n == 0 then head l else (tail l) !! (n-1)
|
|
||||||
-- negative of a number (I don't like writing 0-x).
|
|
||||||
neg x = 0-x
|
|
||||||
|
|
||||||
rgb :: Int -> Int -> Int -> (Int,Int,Int)
|
|
||||||
rgb = (,,)
|
|
||||||
rgba = (,,,)
|
|
||||||
-- Colors (theme is solarized)
|
|
||||||
base03 = rgb 0 43 54
|
|
||||||
base02 = rgb 7 54 66
|
|
||||||
base01 = rgb 88 110 117
|
|
||||||
base00 = rgb 101 123 131
|
|
||||||
base0 = rgb 131 148 150
|
|
||||||
base1 = rgb 147 161 161
|
|
||||||
base2 = rgb 238 232 213
|
|
||||||
base3 = rgb 253 246 227
|
|
||||||
yellow = rgb 181 137 0
|
|
||||||
orange = rgb 203 75 22
|
|
||||||
red = rgb 220 50 47
|
|
||||||
magenta = rgb 211 54 130
|
|
||||||
violet = rgb 108 113 196
|
|
||||||
blue = rgb 38 139 210
|
|
||||||
cyan = rgb 42 161 152
|
|
||||||
green = rgb 133 153 0
|
|
||||||
|
|
||||||
-- Default text color
|
|
||||||
mybase = rgba 108 113 196 (2/3)
|
|
||||||
|
|
||||||
-- RANDOM PART
|
|
||||||
nextint n =
|
|
||||||
let
|
|
||||||
a = 22695477
|
|
||||||
c = 1
|
|
||||||
m = 2^32
|
|
||||||
in
|
|
||||||
(a*n + c) `rem` m
|
|
||||||
|
|
||||||
-- generate a random sequence of length k starting with some seed
|
|
||||||
randlist seed k = if (k<0) then [] else (nextint seed):randlist (nextint seed) (k-1)
|
|
||||||
|
|
||||||
-- generate a random sequence of points of length k starting with some seed
|
|
||||||
randcouples seed k = if (k<0) then []
|
|
||||||
else
|
|
||||||
let ns = nextint seed
|
|
||||||
nns = nextint ns
|
|
||||||
in (ns,nns):randcouples nns (k-1)
|
|
||||||
-- END OF PSEUDO RANDOM NUMBER GENERATION
|
|
||||||
|
|
||||||
|
|
||||||
{-
|
|
||||||
- Flame Set
|
|
||||||
-
|
|
||||||
- S = U_{i} F_i(S)
|
|
||||||
-
|
|
||||||
- F_i being transformations
|
|
||||||
- General form:
|
|
||||||
- F = affine . linearcomp [variation] . affine
|
|
||||||
- affine is a linear function (x,y) -> (ax+by+c,dx+ey+f)
|
|
||||||
- variation is some kind of function with some contraction properties
|
|
||||||
ex: (x,y) -> (x,y), (sin x, sin y), etc...
|
|
||||||
- linearcomp [f] is a linear composition of functions: (x,y) -> Sum vi*f(x,y)
|
|
||||||
-}
|
|
||||||
|
|
||||||
data Matrice = M Float Float Float Float Float Float
|
|
||||||
aff (M a b c d e f) (x,y) = (a*x + b*y + c, d*x + e*y +f)
|
|
||||||
|
|
||||||
-- Some affine functions to generate the sierpinsky set
|
|
||||||
-- Equivalent to
|
|
||||||
-- sierp = [ \(x,y)->(x/2,y/2)
|
|
||||||
-- , \(x,y)->((x+1)/2,y/2)
|
|
||||||
-- , \(x,y)->(x/2,(y+1)/2) ]
|
|
||||||
sierp = [ aff $ M
|
|
||||||
0.5 0.0 0.0
|
|
||||||
0.0 0.5 0.0
|
|
||||||
, aff $ M
|
|
||||||
0.5 0.0 0.5
|
|
||||||
0.0 0.5 0.0
|
|
||||||
, aff $ M
|
|
||||||
0.5 0.0 0.0
|
|
||||||
0.0 0.5 0.5
|
|
||||||
]
|
|
||||||
|
|
||||||
-- Some variations
|
|
||||||
vs = [ \(x,y) -> (x,y)
|
|
||||||
, \(x,y) -> (sin x, sin y)
|
|
||||||
, \(x,y) -> let r2 = x*x+y*y in (x/r2,y/r2)
|
|
||||||
, \(x,y) -> let r2 = x*x+y*y in (x*(sin r2) - y*(cos r2),x*(cos r2) + y * (sin r2))
|
|
||||||
, \(x,y) -> let r = sqrt (x^2+y^2) in ((x - y)*(x + y)/r,2*x*y/r)
|
|
||||||
]
|
|
||||||
|
|
||||||
-- Some final functions
|
|
||||||
fs = [ (vs !! 3) . (sierp !! 0)
|
|
||||||
, (vs !! 3) . (sierp !! 1)
|
|
||||||
, (vs !! 3) . (sierp !! 2)]
|
|
||||||
|
|
||||||
-- Transformation functions
|
|
||||||
-- translate
|
|
||||||
trans (tx,ty) = aff $ M 1 0 tx 0 1 ty
|
|
||||||
-- rotate
|
|
||||||
rot phi = aff $ M (cos phi) (sin phi) 0.0 (neg (sin phi)) (cos phi) 0.0
|
|
||||||
-- zoom
|
|
||||||
zoom z = aff $ M z 0 0 0 z 0
|
|
||||||
|
|
||||||
-- The final transformation to transform the final result (zoom,rotate,translate)
|
|
||||||
final = trans (280,200) . zoom 300 . rot (neg 0.747)
|
|
||||||
|
|
||||||
sierpset startpoint rands tmpres =
|
|
||||||
if rands == []
|
|
||||||
then tmpres
|
|
||||||
else
|
|
||||||
let
|
|
||||||
roundPoint (x,y) = (round x,round y)
|
|
||||||
randval=(head rands) `rem` (length fs)
|
|
||||||
newpoint = (fs !! randval) startpoint
|
|
||||||
savepoint = roundPoint ( final newpoint )
|
|
||||||
oldvalue = Dict.lookup savepoint tmpres
|
|
||||||
newvalue = 1 + (Maybe.fromMaybe 0 oldvalue)
|
|
||||||
newtmpres = Dict.insert savepoint newvalue tmpres
|
|
||||||
in
|
|
||||||
sierpset newpoint (tail rands) newtmpres
|
|
||||||
|
|
||||||
sierpinsky n = sierpset (0.0,0.0) (randlist 0 n) Dict.empty
|
|
||||||
|
|
||||||
scene env =
|
|
||||||
let
|
|
||||||
w = imgWidth env
|
|
||||||
h = imgHeight env
|
|
||||||
n = nbPoints env
|
|
||||||
inpoint ((x,y),_) = x>=0 && x<=w && y>=0 && y<=h
|
|
||||||
in (Prelude.filter inpoint) . Dict.toList $ (sierpinsky n)
|
|
||||||
|
|
||||||
|
|
||||||
initGlobalParams args =
|
|
||||||
Global { imgWidth = read (args !! 0)
|
|
||||||
, imgHeight = read (args !! 1)
|
|
||||||
, nbPoints = read (args !! 2) }
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
args <- getArgs
|
|
||||||
if (length args<3)
|
|
||||||
then print $ "Usage flame w h n"
|
|
||||||
else do
|
|
||||||
env <- return (initGlobalParams args)
|
|
||||||
mapM_ (print) (scene env)
|
|
Loading…
Reference in a new issue