Advertisement
ptrelford

Random Art in Go

Sep 3rd, 2015
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.73 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.   "fmt"
  5.   "image"
  6.   "image/color"
  7.   "image/draw"
  8.   "image/png"
  9.   "math"
  10.   "math/rand"
  11.   "os"
  12.   "time"
  13. )
  14.  
  15. type Expr interface {
  16.   Eval(x float64, y float64) (r, g, b float64)
  17. }
  18.  
  19. func average(x,y,w float64) float64 {
  20.   return w * x + (1.0 - w) * y
  21. }
  22.  
  23. type SumExpr struct {
  24.   e1     Expr
  25.   e2     Expr
  26. }
  27.  
  28. func (e SumExpr) Eval(x, y float64) (r, g, b float64) {
  29.   r1,g1,b1 := e.e1.Eval(x,y)
  30.   r2,g2,b2 := e.e2.Eval(x,y)
  31.   r = average(r1,r2,0.5)
  32.   g = average(g1,g2,0.5)
  33.   b = average(b1,b2,0.5)
  34.   return
  35. }
  36.  
  37. func tent(x float64) float64 {
  38.   return 1.0 - 2.0 * math.Abs(x)
  39. }
  40.  
  41. type TentExpr struct {
  42.   e1    Expr
  43. }
  44.  
  45. func (e TentExpr) Eval(x, y float64) (r, g, b float64) {
  46.   r1,g1,b1 := e.e1.Eval(x,y)
  47.   r = tent(r1)
  48.   g = tent(g1)
  49.   b = tent(b1)
  50.   return
  51. }
  52.  
  53. func pown(x float64, y int) float64 {
  54.   acc := 1.0
  55.   for i:=0; i<y;i++ {acc *= x }
  56.   return acc
  57. }
  58.  
  59. func well(x float64) float64 {
  60.   return 1.0 - 2.0 / pown(1.0 + x * x,8)
  61. }
  62.  
  63. type WellExpr struct {
  64.   e1    Expr
  65. }
  66.  
  67. func (e WellExpr) Eval(x, y float64) (r, g, b float64) {
  68.   r1,g1,b1 := e.e1.Eval(x,y)
  69.   r = well(r1)
  70.   g = well(g1)
  71.   b = well(b1)
  72.   return
  73. }
  74.  
  75. type SinExpr struct {
  76.   e1    Expr
  77.   phase float64
  78.   freq  float64
  79. }
  80.  
  81. func makeSinExpr(e Expr) Expr {
  82.   return SinExpr{e, rand.Float64() * math.Pi, (rand.Float64() * 5.0) + 1.0}
  83. }
  84.  
  85. func (e SinExpr) Eval(x, y float64) (r, g, b float64) {
  86.   r1, g1, b1 := e.e1.Eval(x, y)
  87.   r = math.Sin(e.phase + r1*e.freq)
  88.   g = math.Sin(e.phase + g1*e.freq)
  89.   b = math.Sin(e.phase + b1*e.freq)
  90.   return
  91. }
  92.  
  93. type MaxExpr struct {
  94.   e1 Expr
  95.   e2 Expr
  96. }
  97.  
  98. func (e MaxExpr) Eval(x, y float64) (r, g, b float64) {
  99.   r1, g1, b1 := e.e1.Eval(x, y)
  100.   r2, g2, b2 := e.e2.Eval(x, y)
  101.   r = math.Max(r1, r2)
  102.   g = math.Max(g1, g2)
  103.   b = math.Max(b1, b2)
  104.   return
  105. }
  106.  
  107. type ModExpr struct {
  108.   e1 Expr
  109.   e2 Expr
  110. }
  111.  
  112. func (e ModExpr) Eval(x, y float64) (r, g, b float64) {
  113.   r1, g1, b1 := e.e1.Eval(x, y)
  114.   r2, g2, b2 := e.e2.Eval(x, y)
  115.   r = math.Mod(r1, r2)
  116.   g = math.Mod(g1, g2)
  117.   b = math.Mod(b1, b2)
  118.   return
  119. }
  120.  
  121. type SquareExpr struct {
  122.   e1 Expr
  123. }
  124.  
  125. func (e SquareExpr) Eval(x, y float64) (r, g, b float64) {
  126.   r1, g1, b1 := e.e1.Eval(x, y)
  127.   r = r1 * r1
  128.   g = g1 * g1
  129.   b = b1 * b1
  130.   return
  131. }
  132.  
  133. type ProductExpr struct {
  134.   e1 Expr
  135.   e2 Expr
  136. }
  137.  
  138. func (e ProductExpr) Eval(x, y float64) (r, g, b float64) {
  139.   r1, g1, b1 := e.e1.Eval(x, y)
  140.   r2, g2, b2 := e.e2.Eval(x, y)
  141.   r = r1 * r2
  142.   g = g1 * g2
  143.   b = b1 * b2
  144.   return
  145. }
  146.  
  147. type MixExpr struct {
  148.   e1 Expr
  149.   e2 Expr
  150.   e3 Expr
  151. }
  152.  
  153. func (e MixExpr) Eval(x, y float64) (r, g, b float64) {
  154.   n, _, _ := e.e1.Eval(x, y)
  155.   w := 0.5 * (n + 1.0)
  156.   r1,g1,b1 := e.e2.Eval(x, y)
  157.   r2,g2,b2 := e.e3.Eval(x, y)
  158.   r = average(r1,r2,w)
  159.   g = average(g1,g2,w)
  160.   b = average(b1,b2,w)
  161.   return
  162. }
  163.  
  164. type LevelExpr struct {
  165.   e1 Expr
  166.   e2 Expr
  167.   e3 Expr
  168.   threshold float64
  169. }
  170.  
  171. func (e LevelExpr) Eval(x, y float64) (r, g, b float64) {
  172.   r1,g1,b1 := e.e1.Eval(x, y)
  173.   r2,g2,b2 := e.e2.Eval(x, y)
  174.   r3,g3,b3 := e.e3.Eval(x, y)
  175.   r = r2
  176.   if r1 < e.threshold { r = r3 }
  177.   g = g2
  178.   if g1 < e.threshold { g = g3 }
  179.   b = b2
  180.   if b1 < e.threshold { b = b3 }
  181.   return
  182. }
  183.  
  184. func makeLevelExpr(e1,e2,e3 Expr) Expr {
  185.   threshold := (rand.Float64()*2.0) - 1.0
  186.   return LevelExpr{e1,e2,e3,threshold}
  187. }
  188.  
  189. type XExpr struct{}
  190.  
  191. func (XExpr) Eval(x, _ float64) (r, g, b float64) {
  192.   r = x
  193.   g = x
  194.   b = x
  195.   return
  196. }
  197.  
  198. type YExpr struct{}
  199.  
  200. func (YExpr) Eval(_, y float64) (r, g, b float64) {
  201.   r = y
  202.   g = y
  203.   b = y
  204.   return
  205. }
  206.  
  207. type ConstantExpr struct {
  208.   r float64
  209.   g float64
  210.   b float64
  211. }
  212.  
  213. func (c ConstantExpr) Eval(x, y float64) (r, g, b float64) {
  214.   r = c.r
  215.   g = c.g
  216.   b = c.b
  217.   return
  218. }
  219.  
  220. func makeConstantExpr() Expr {
  221.   return ConstantExpr{rand.Float64(), rand.Float64(), rand.Float64()}
  222. }
  223.  
  224. func generateExpr(count int) Expr {
  225.   if count == 0 {
  226.     switch rand.Intn(3) {
  227.     case 0: return XExpr{}
  228.     case 1: return YExpr{}
  229.     default: return makeConstantExpr()
  230.     }
  231.   }
  232.   switch rand.Intn(10) {
  233.   case 0:
  234.     return MixExpr{generateExpr(count - 1), generateExpr(count - 1), generateExpr(count -1)}
  235.   case 1:
  236.     return ProductExpr{generateExpr(count - 1), generateExpr(count - 1)}
  237.   case 2:
  238.     return ModExpr{generateExpr(count - 1), generateExpr(count - 1)}
  239.   case 3:
  240.     return MaxExpr{generateExpr(count - 1), generateExpr(count - 1)}
  241.   case 4:
  242.     return SquareExpr{generateExpr(count - 1)}
  243.   case 5:
  244.     return WellExpr{generateExpr(count - 1)}
  245.   case 6:
  246.     return TentExpr{generateExpr(count - 1)}
  247.   case 7:
  248.     return SumExpr{generateExpr(count - 1), generateExpr(count - 1)}
  249.   case 8:
  250.     return makeSinExpr(generateExpr(count - 1))
  251.   default:
  252.     return makeLevelExpr(generateExpr(count - 1), generateExpr(count - 1), generateExpr(count -1))
  253.   }
  254. }
  255.  
  256. func toByte(x float64) uint8 {
  257.   return uint8(math.Max(0.0, math.Min(255.0, 128.0*(x+1.0))))
  258. }
  259.  
  260. func createImage(width int, height int, e *Expr) image.Image {
  261.   imgRect := image.Rect(0, 0, width, height)
  262.   img := image.NewRGBA(imgRect)
  263.   draw.Draw(img, img.Bounds(), &image.Uniform{color.White}, image.ZP, draw.Src)
  264.   for y := 0; y < height; y++ {
  265.     for x := 0; x < width; x++ {
  266.       r, g, b := (*e).Eval(float64(x)/float64(width), float64(y)/float64(width))
  267.       c := color.RGBA{toByte(r), toByte(g), toByte(b), 255}
  268.       img.SetRGBA(x, y, c)
  269.     }
  270.   }
  271.   return img
  272. }
  273.  
  274. func main() {
  275.   rand.Seed(time.Now().UTC().UnixNano())
  276.   for i:=100;i<=999;i++ {
  277.     out, _ := os.Create(fmt.Sprintf("./output%d.png",i))
  278.     defer out.Close()
  279.     //e := makeSinExpr(ProductExpr{YExpr{}, MaxExpr{XExpr{}, makeConstantExpr()}})
  280.     e := generateExpr(6)
  281.     img := createImage(640, 480, &e)
  282.     png.Encode(out, img)
  283.   }
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement