Pretty Pictures from Genetic Algorithms
About this project
Details:
About this project: This project
is a reimplementation of my final
COMP 314 project, pretty pictures (via genetic algorithms). (originally by Dan Wallach)
Each picture is produced from a tree of functions (listed below), acting on x
and y coordinates in [-1,1], and mapping the results to RGB values 0-255. Breeding two pictures together involves taking a random subtree from one and splicing
it in a random place in the other. The backend script that draws the pictures
is written in C++, and the function tree is passed in a modified version of
JSON (using single quotes instead of double quotes, so they don't have to be URL encoded).
Try these pretty pictures!
- (abs (sub-wrap (neg (ccrgb (ru (ru (num 0.6614554081190059))) (log-clip (abs (div-clip (abs (cchsl (ccrgb (num 0.5266760532380341) (num 0.2037882282789114) y) x x)) (mul-wrap (sub-wrap (atan-wrap (num 0.2710625018544712)) (num 0.46994645301411775)) (abs x))))) (rd (cchsl (num 0.811607978527779) y x)))) (abs y)))
- (div-wrap (abs (div-clip (sub-clip (cchsl x (num 0.5522413404801835) (neg (sin (atan-wrap (num 0.8416469025349831))))) (cchsl (num 0.6429928276228649) (neg (abs y)) (div-clip (cchsl (mul-wrap x y) (cchsl (ccrgb x (div-wrap x y) x) x (exp-clip x)) (ccrgb (num 0.8167221711670928) (sub-clip y x) x)) y))) y)) (cchsl (ru (ccrgb (neg (ru y)) (abs (sub-clip (div-wrap x y) (add-clip x (cchsl (log-wrap (ccrgb (num 0.09141941365047113) y y)) y (num 0.30011079353156145))))) y)) (ccrgb (ru (add-clip x y)) (add-wrap (rd x) (num 0.7744101640567105)) y) (num 0.34666343576153713)))
- (sub-clip (cchsl (abs (div-clip (sub-clip (cchsl x (num 0.5522413404801835) (neg (sin (atan-wrap (num 0.8416469025349831))))) (cchsl (num 0.6429928276228649) (neg (abs y)) (div-clip (cchsl (mul-wrap x y) (cchsl (ccrgb x (div-wrap x y) x) x (exp-clip x)) (ccrgb (num 0.8167221711670928) (sub-clip y x) x)) y))) y)) (abs (div-clip (sub-clip (cchsl x (num 0.5522413404801835) (neg (sin (atan-wrap (num 0.8416469025349831))))) (cchsl (num 0.6429928276228649) (neg (abs y)) (div-clip (cchsl (mul-wrap x y) (cchsl (ccrgb x (div-wrap x y) x) x (exp-clip x)) (ccrgb (num 0.8167221711670928) (sub-clip y x) x)) y))) y)) (abs (div-clip (sub-clip (cchsl x (num 0.5522413404801835) (neg (sin (atan-wrap (num 0.8416469025349831))))) (cchsl (num 0.6429928276228649) (neg (abs y)) (div-clip (cchsl (mul-wrap x y) (cchsl (ccrgb x (div-wrap x y) x) x (exp-clip x)) (ccrgb (num 0.8167221711670928) (sub-clip y x) x)) y))) y))) (cchsl (num 0.6429928276228649) (neg (abs y)) (div-clip (cchsl (mul-wrap x y) (cchsl (ccrgb x (div-wrap x y) x) x (exp-clip x)) (ccrgb (num 0.8167221711670928) (sub-clip y x) x)) y)))
- (ccrgb (exp-wrap (neg (sub-wrap x (sub-wrap (sub-clip (sub-wrap x y) (neg (atan-wrap (add-wrap x y)))) y)))) (neg (sub-wrap x (sub-wrap (sub-clip (sub-wrap x y) (neg (atan-wrap (add-wrap x y)))) y))) (num 0.37767491866913594 ))
- (neg (sub-wrap (sub-wrap (num 0.12345183270643267) y) (neg (atan-wrap (cchsl (add-wrap y (exp-wrap y)) (cos (log-wrap y)) (add-clip (cchsl (neg x) (num 0.3833093051145148) x) (num 0.5117598243776572)))))))
- (cchsl x (exp-wrap x) (cchsl (num 0.11385156752423187) (sub-clip (rd (abs (cos (abs (add-clip y x))))) (atan-wrap (num 0.6693146834356939))) (cchsl (ccrgb y (log-wrap (neg (sub-clip x y))) (cchsl (log-clip (div-wrap x y)) (log-wrap y) (atan-wrap (num 0.6652075928655149 )))) (rd (ru y)) (mul-clip (sin (atan-clip x)) y))))
- (cchsl (rd (mul-clip y (num 0.8930935061312807))) (mul-wrap (sub-clip (div-wrap (sin (log-clip (exp-wrap (sin (div-clip y (sin (sub-clip (abs y) x))))))) (exp-wrap (mul-wrap (ccrgb (cchsl x y (rd (ru (add-clip x (num 0.2885036108320864))))) (ccrgb x x x) y) x))) (atan-clip x)) (ru x)) (cchsl (cchsl (ccrgb x y (rd (div-wrap y x))) (mul-wrap (num 0.6513866723933591) (ru (cos y))) (mul-clip (abs (cchsl (ccrgb (cchsl (cos (exp-clip x)) (log-clip (num 0.9449103938454887)) x) (abs y) (sub-clip (rd (sub-clip y (ccrgb (num 0.2000245931658713) y (num 0.2939034489073272)))) (abs (num 0.8075909711606815)))) (rd (num 0.6600860480909476)) y)) (cchsl (num 0.581083193368841) (num 0.8221578845301776) x))) x (div-clip (ccrgb (num 0.21036100477822162) (num 0.38626346057286887) (add-wrap (num 0.12241015819010093) x)) (mul-wrap y (sub-wrap (neg (num 0.7872759417842692)) x)))))
- (colorperlin 1919395543 451637955 760248740 (sub-clip (add-clip (div-clip (colorperlin 536113926 333887465 274645468 (sub-wrap (sub-clip (num 0.12196193171715553) y) (div-clip (ccrgb x (cchsl y x x) (sin y)) (num 0.7066544961050378))) (num 0.7049402963855226)) (atan-clip y)) (cos (div-clip (log-clip x) y))) (add-clip (cchsl (rd (num 0.5119759903891848)) (add-clip x (neg (sub-clip y (exp-wrap x)))) (sin y)) y)) (cchsl (colorperlin 1210668918 1783404624 1243030991 (mul-wrap y (colorperlin 600223328 1395788105 861194798 (log-clip (sub-wrap y (neg (neg x)))) (num 0.6093212396309351))) (ru (sub-wrap y (rd (atan-clip x))))) (num 0.29363189060327777) x))
- (div-clip (colorperlin 1362710210 278847481 1402125762 (add-wrap (abs (num 0.031681362818044456)) (sub-clip (cos (ccrgb (sin (atan-clip (rd (add-clip (add-wrap x (num 0.578092059228798)) x)))) y (num 0.23646468718646263))) (colorperlin 1502179640 1316738189 454935563 (neg (div-wrap x y)) (num 0.5078184951973896)))) x) (bwperlin 880129745 (abs (add-clip (sin x) (ccrgb y (sub-wrap (cos x) (neg (log-clip (num 0.05318551299931629)))) (num 0.751250719855975)))) y))
Source files:
- json.js - modified JSON parser (taken from here) that accepts single quotes instead of double quotes.
- ppga.js - generates random functions and breeds them together.
- writepng.cpp - writes the PNG files. Uses TinyJSON as a parser (modified to parse JSON with single quotes) and libpng to write the PNG file. The older python version is below; this version in C++ is much faster.
Old source files:
I was also working on a version in Haskell; here are the source files:
- Png.hs - code to write (and hopefully read someday) PNG files - taken from here and modified.
- MakePng.hs - draws the PNG file given a function.
- cgiHandler.hs - the CGI handler.
Here's the list of functions. Ones with a * can take their values outside
[-1,1], and so must be followed by "-clip" or "-wrap" (describing how they
return their values to [-1,1]).
num
(takes a value argument)
x
y
atan*
abs
cos
exp*
log*
neg
rd
(round down to an integer)
ru
(round up to an integer)
sin
add*
div*
mul*
sub*
bwperlin
(takes one seed argument)
colorperlin
(takes three seed arguments)
ccrgb
(color conditional - arguments are red, green, blue channels)
cchsl
(color conditional - arguments are HSL channels)