barnsley_fern_ifs.sf 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/ruby
  2. # Code from a lesson by Keith Peters.
  3. # See: https://www.youtube.com/watch?v=geqq63WFLr0
  4. require('Imager')
  5. var (width, height) = (500, 500)
  6. var img = %O<Imager>.new(xsize => width, ysize => height)
  7. struct Rule {
  8. a, b, c, d, tx, ty, w
  9. }
  10. var rules = [
  11. Rule(
  12. a: 0.85,
  13. b: 0.04,
  14. c: -0.04,
  15. d: 0.85,
  16. tx: 0,
  17. ty: 1.6,
  18. w: 0.85,
  19. ),
  20. Rule(
  21. a: -0.15,
  22. b: 0.28,
  23. c: 0.26,
  24. d: 0.24,
  25. tx: 0,
  26. ty: 0.44,
  27. w: 0.07,
  28. ),
  29. Rule(
  30. a: 0.2,
  31. b: -0.26,
  32. c: 0.23,
  33. d: 0.22,
  34. tx: 0,
  35. ty: 1.6,
  36. w: 0.07,
  37. ),
  38. Rule(
  39. a: 0,
  40. b: 0,
  41. c: 0,
  42. d: 0.16,
  43. tx: 0,
  44. ty: 0,
  45. w: 0.01,
  46. )
  47. ]
  48. func plot(x, y) {
  49. static green = %O<Imager::Color>.new('#00ff00')
  50. img.setpixel(
  51. x => width/2 + Math.map(2*x, 0, 10, 0, width/2),
  52. y => height - Math.map(2*y, 0, 10, 0, height/2),
  53. color => green
  54. )
  55. }
  56. func getRule {
  57. var r = 1.rand
  58. for rule in (rules) {
  59. if (r < rule.w) {
  60. return rule
  61. }
  62. r -= rule.w
  63. }
  64. }
  65. var (x, y) = 2.of { 1.rand }...
  66. var iterate = {
  67. var rule = getRule()
  68. var x1 = (x*rule.a + y*rule.b + rule.tx)
  69. var y1 = (x*rule.c + y*rule.d + rule.ty)
  70. x = x1
  71. y = y1
  72. plot(x, y)
  73. }
  74. iterate * 2000
  75. img.write(file => 'barnsley_fern.png')