rose.lua (2604B)
1 --[[ 2 Rose Art 3 "rose.lua" 4 M. Yamanaka 5 email: myamanaka@live.com 6 website: csmyamanaka.com 7 license: MIT (See included "LICENSE" file for details) 8 ]] 9 10 local ca = require("lgi").cairo 11 require("csconv") 12 13 function neonSet(ctx, p, n, r, c) 14 --[[ 15 draw a set of "neon" points 16 arguments: 17 ctx ... cairo context 18 p ... point in canvas coordinate system 19 n ... number of points 20 r ... max radius 21 c ... colour 22 ]] 23 ctx:set_source_rgb(c[1], c[2], c[3]) 24 for i = 1, n do 25 ctx:arc(p[i][1], p[i][2], r, 0, math.pi*2) 26 ctx:fill() 27 end 28 29 --[[ 30 To give it a "neon" appearance, these points should all 31 have a white centre 32 ]] 33 ctx:set_source_rgb(1, 1, 1) 34 for i = 1, n do 35 ctx:arc(p[i][1], p[i][2], r*0.7, 0, math.pi*2) 36 ctx:fill() 37 end 38 end 39 40 function genPts(n, p0, l, s, t) 41 --[[ 42 Generate a set of points that reside on one continous 43 function at equal intervals. The resulting set of points 44 are in canvas coordinates 45 arguments: 46 n ... total number of points 47 p0 ... initial point in polar coordinates 48 l ... the layer of the rose petals on which these pts reside 49 s ... the scaling factor for domain conversion 50 t ... the translation for domain conversion 51 ]] 52 local pts = {} 53 for i = 1, n do 54 local u = (i - 1)*(2*math.pi)/n 55 local th = u/l + p0[2] 56 local r = p0[1]*0.1*math.abs(math.sin(u*1.5)) + p0[1] 57 pts[i] = xyCanv(polarXY({r, th}), s, t) 58 end 59 return pts 60 end 61 62 function genFibs(n) 63 --[[ 64 It is widely known that fibonacci numbers appear in nature. 65 We will employ these numbers for our designs as well 66 ]] 67 local fibs = {0, 1} 68 for i = 3, n do fibs[i] = fibs[i - 1] + fibs[i - 2] end 69 return fibs 70 end 71 72 function rose() 73 --[[ 74 The "main" function 75 ]] 76 77 local dim = {1920, 1080} 78 local fn = "rose.svg" 79 local ctx = ca.Context.create(ca.SvgSurface.create(fn, dim[1], dim[2])) 80 81 local N = 100 -- set each segment to have 100 points 82 local P1 = {} 83 local idx = 1 -- index number for each set 84 --[[ 85 the use of fibonacci numbers allow for natural looking 86 patterns 87 ]] 88 local fibs = genFibs(7) 89 for i = 4, 7 do 90 for j = 0, fibs[i] - 1 do 91 P1[idx] = genPts(N, {(i - 3)*100, j*2*math.pi/fibs[i]}, fibs[i] + 1, 1, {dim[1]/2, dim[2]/2}) 92 idx = idx + 1 93 end 94 end 95 96 --[[ 97 initialize the scene with a black background 98 ]] 99 ctx:set_source_rgb(0, 0, 0) 100 ctx:rectangle(0, 0, dim[1], dim[2]) 101 ctx:fill() 102 103 --[[ 104 Draw all segments 105 ]] 106 for i = 1, idx - 1 do neonSet(ctx, P1[i], N, 10, {1.0, 0.1, 0.9}) end 107 end 108 109 rose()