Mandelbrot.hx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #if (!js && !flash)
  2. import haxe.io.Bytes;
  3. #end
  4. #if anon_objects
  5. typedef RGB = { r:Int, g:Int, b:Int };
  6. typedef Complex = { i:Float, j:Float };
  7. #else
  8. class RGB
  9. {
  10. public var r:Int;
  11. public var g:Int;
  12. public var b:Int;
  13. public function new(inR:Int, inG:Int, inB:Int)
  14. {
  15. r = inR;
  16. g = inG;
  17. b = inB;
  18. }
  19. }
  20. class Complex
  21. {
  22. public var i:Float;
  23. public var j:Float;
  24. public function new(inI:Float, inJ:Float)
  25. {
  26. i = inI;
  27. j = inJ;
  28. }
  29. }
  30. #end
  31. class Mandelbrot
  32. {
  33. static inline var SIZE = 25;
  34. static inline var MaxIterations = 1000;
  35. static inline var MaxRad = 1<<16;
  36. static inline var width = 35*SIZE;
  37. static inline var height = 20*SIZE;
  38. public static function main()
  39. {
  40. var t0 = now();
  41. var palette = [];
  42. for(i in 0...MaxIterations+1)
  43. palette.push( createPalette(i/MaxIterations) );
  44. var image = [];
  45. image[ width*height-1 ] = null;
  46. var outPixel = 0;
  47. var scale = 0.1/SIZE;
  48. for(y in 0...height)
  49. {
  50. if ( (y%10)== 0)
  51. trace(y);
  52. for(x in 0...width)
  53. {
  54. var iteration = 0;
  55. #if reduce_allocs
  56. var offsetI = x*scale - 2.5;
  57. var offsetJ = y*scale - 1.0;
  58. var valI = 0.0;
  59. var valJ = 0.0;
  60. while( valI*valI+valJ*valJ<MaxRad && iteration<MaxIterations)
  61. {
  62. var vi = valI;
  63. valI = valI*valI - valJ*valJ + offsetI;
  64. valJ = 2.0*vi*valJ + offsetJ;
  65. iteration++;
  66. }
  67. #else
  68. var offset = createComplex(x*scale - 2.5,y*scale - 1);
  69. var val = createComplex(0.0,0.0);
  70. while( complexLength2(val)<MaxRad && iteration<MaxIterations)
  71. {
  72. val = complexAdd( complexSquare(val), offset );
  73. iteration++;
  74. }
  75. #end
  76. image[outPixel++] = palette[iteration];
  77. }
  78. }
  79. var time = now()-t0;
  80. trace('Mandelbrot $width x $height : $time s');
  81. #if (!js && !flash)
  82. var header = 'P6 $width $height 255\n';
  83. var buffer = Bytes.alloc(header.length + width*height*3);
  84. var pos = header.length;
  85. buffer.blit(0, Bytes.ofString(header), 0, pos );
  86. for(pixel in image)
  87. {
  88. buffer.set(pos++, pixel.r);
  89. buffer.set(pos++, pixel.g);
  90. buffer.set(pos++, pixel.b);
  91. }
  92. sys.io.File.saveBytes("mandelbrot.ppm", buffer);
  93. #end
  94. }
  95. public static function now()
  96. {
  97. return haxe.Timer.stamp();
  98. }
  99. public static function complexLength2(val:Complex) : Float
  100. {
  101. return val.i*val.i + val.j*val.j;
  102. }
  103. public inline static function complexAdd(val0:Complex, val1:Complex)
  104. {
  105. return createComplex( val0.i + val1.i, val0.j + val1.j );
  106. }
  107. public inline static function complexSquare(val:Complex)
  108. {
  109. return createComplex( val.i*val.i - val.j*val.j, 2.0 * val.i * val.j );
  110. }
  111. #if anon_objects
  112. public static function createComplex(inI:Float, inJ:Float) return @:fixed { i:inI, j:inJ };
  113. #else
  114. inline public static function createComplex(inI:Float, inJ:Float) return new Complex(inI, inJ);
  115. #end
  116. public static function createPalette(inFraction:Float)
  117. {
  118. var r = Std.int(inFraction*255);
  119. var g = Std.int((1-inFraction)*255);
  120. var b = Std.int( (0.5-Math.abs(inFraction-0.5))*2*255 );
  121. #if anon_objects
  122. return { r:r, g:g, b:b };
  123. #else
  124. return new RGB(r,g,b);
  125. #end
  126. }
  127. }