mandelbrot 0.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,63 @@
1
+ #include "bmp.h"
2
+
3
+ void new_bmp_header(int width, int height, char* header)
4
+ {
5
+ header[0] = 'B';
6
+ header[1] = 'M';
7
+
8
+ // file size
9
+ *(uint32_t*)&(header[2]) = 54 + (((24 * width + 31)/32) * 4) * height;
10
+
11
+ // reserved
12
+ *(uint32_t*)&(header[6]) = 0;
13
+
14
+ // offset
15
+ *(uint32_t*)&(header[10]) = 54;
16
+
17
+ // dib header size
18
+ *(uint32_t*)&(header[14]) = 40;
19
+
20
+ // width
21
+ *(uint32_t*)&(header[18]) = width;
22
+
23
+ // height
24
+ *(uint32_t*)&(header[22]) = height;
25
+
26
+ // planes
27
+ *(uint16_t*)&(header[26]) = 1;
28
+
29
+ // depth
30
+ *(uint16_t*)&(header[28]) = 24;
31
+
32
+ // compression
33
+ *(uint32_t*)&(header[30]) = 0;
34
+
35
+ // image size
36
+ *(uint32_t*)&(header[34]) = (((24 * width + 31)/32) * 4) * height;
37
+
38
+ // horiz resolution
39
+ *(uint32_t*)&(header[38]) = 72;
40
+
41
+ // vert resolution
42
+ *(uint32_t*)&(header[42]) = 72;
43
+
44
+ // colour palette
45
+ *(uint32_t*)&(header[46]) = 0;
46
+
47
+ // important colours
48
+ *(uint32_t*)&(header[50]) = 0;
49
+
50
+ /*
51
+ header->file_header.magic[0] = 'B';
52
+ header->file_header.magic[1] = 'M';
53
+ header->file_header.file_size = (uint32_t)sizeof(bmp_header_t) + (((24 * width + 31)/32) * 4) * height;
54
+ header->file_header.reserved = 0;
55
+ header->file_header.offset = sizeof(bmp_header_t);
56
+
57
+ header->dib_header.header_size = sizeof(bmp_dib_header_t);
58
+ header->dib_header.image_width = width;
59
+ header->dib_header.image_height = height;
60
+ header->dib_header.color_planes = 1;
61
+ header->dib_header.color_depth = 24;
62
+ */
63
+ }
@@ -0,0 +1,26 @@
1
+ #include <stdlib.h>
2
+ #include <stdint.h>
3
+
4
+ /*
5
+ typedef struct {
6
+ char magic[2];
7
+ uint32_t file_size;
8
+ uint32_t reserved;
9
+ uint32_t offset;
10
+ } __attribute__((packed)) bmp_file_header_t;
11
+
12
+ typedef struct {
13
+ uint32_t header_size;
14
+ uint16_t image_width;
15
+ uint16_t image_height;
16
+ uint16_t color_planes; // must be 1
17
+ uint16_t color_depth;
18
+ } __attribute__((packed)) bmp_dib_header_t;
19
+
20
+ typedef struct {
21
+ bmp_file_header_t file_header;
22
+ bmp_dib_header_t dib_header;
23
+ } __attribute__((packed)) bmp_header_t;
24
+ */
25
+
26
+ void new_bmp_header(int width, int height, char* header);
@@ -1,17 +1,9 @@
1
- #include <stdlib.h>
2
- #include <stdbool.h>
3
- #include <complex.h>
4
- #include "ruby.h"
1
+ #include "mandelbrot.h"
5
2
 
6
3
  static ID i_Complex = Qundef;
7
4
  static ID i_to_f = Qundef;
8
5
  static ID i_INFINITY = Qundef;
9
6
 
10
- static VALUE Float_INFINITY = Qundef;
11
- static VALUE Mandelbrot = Qundef;
12
- static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self);
13
- static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height);
14
-
15
7
  static double rb_complex_re(VALUE cplx)
16
8
  {
17
9
  _Complex ret;
@@ -42,6 +34,7 @@ void Init_mandelbrot()
42
34
  Mandelbrot = rb_define_class("Mandelbrot", rb_cObject);
43
35
  rb_define_method(Mandelbrot, "initialize", Mandelbrot_initialize, -1);
44
36
  rb_define_method(Mandelbrot, "compute", Mandelbrot_compute, 2);
37
+ rb_define_method(Mandelbrot, "bmp", Mandelbrot_bmp, 2);
45
38
  rb_define_attr(Mandelbrot, "min", true, false);
46
39
  rb_define_attr(Mandelbrot, "max", true, false);
47
40
  rb_define_attr(Mandelbrot, "max_iters", true, true);
@@ -64,7 +57,7 @@ static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self)
64
57
 
65
58
  rb_iv_set(self, "@min", min);
66
59
  rb_iv_set(self, "@max", max);
67
- rb_iv_set(self, "@max_iters", INT2NUM(128));
60
+ rb_iv_set(self, "@max_iters", INT2NUM(256));
68
61
 
69
62
  return Qnil;
70
63
  }
@@ -76,6 +69,7 @@ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
76
69
  int width, height;
77
70
  int max_iters;
78
71
  int x, y, iter;
72
+ int* grid;
79
73
  VALUE ary, col, tmp;
80
74
  VALUE r_min;
81
75
  VALUE r_max;
@@ -96,10 +90,10 @@ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
96
90
 
97
91
  ary = rb_ary_new();
98
92
  for(x = 0; x < width; x++) {
93
+ x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
99
94
  col = rb_ary_new();
100
95
  rb_ary_push(ary, col);
101
96
  for(y = 0; y < height; y++) {
102
- x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
103
97
  y0 = (max_im - min_im) * ((double)y / (double)height) + min_im;
104
98
  re = 0;
105
99
  im = 0;
@@ -108,13 +102,110 @@ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
108
102
  im = 2*re*im + y0;
109
103
  re = retemp;
110
104
  }
111
- if(x*x + y*y < 2*2) {
112
- rb_ary_push(col, Float_INFINITY);
105
+ rb_ary_push(col, INT2NUM(x*x + y*y < 2*2 ? -1 : iter));
106
+ }
107
+ }
108
+
109
+ return ary;
110
+ }
111
+
112
+ static inline void hsv_to_rgb(double h, double s, double v, char* r, char* g, char* b)
113
+ {
114
+ double chroma = v * s;
115
+ double h_dash = h / 60.0;
116
+ double x = chroma * (1 - fabs(fmod(h_dash, 2.0) - 1));
117
+ if(h_dash < 1) {
118
+ *r = (char)(255 * chroma);
119
+ *g = (char)(255 * x);
120
+ *b = 0;
121
+ } else if(h_dash < 2) {
122
+ *r = (char)(255 * x);
123
+ *g = (char)(255 * chroma);
124
+ *b = 0;
125
+ } else if(h_dash < 3) {
126
+ *r = 0;
127
+ *g = (char)(255 * chroma);
128
+ *b = (char)(255 * x);
129
+ } else if(h_dash < 4) {
130
+ *r = 0;
131
+ *g = (char)(255 * x);
132
+ *b = (char)(255 * chroma);
133
+ } else if(h_dash < 5) {
134
+ *r = (char)(255 * x);
135
+ *g = 0;
136
+ *b = (char)(255 * chroma);
137
+ } else if(h_dash < 5) {
138
+ *r = (char)(255 * chroma);
139
+ *g = 0;
140
+ *b = (char)(255 * x);
141
+ } else {
142
+ *r = 0;
143
+ *g = 0;
144
+ *b = 0;
145
+ }
146
+ }
147
+
148
+ static VALUE Mandelbrot_bmp(VALUE self, VALUE _width, VALUE _height)
149
+ {
150
+ char* bmp = NULL;
151
+ char* bmp_image_data = NULL;
152
+
153
+ double min_re, min_im, max_re, max_im;
154
+ double x0, y0, re, im, retemp;
155
+ int width, height;
156
+ int max_iters;
157
+ int x, y, iter;
158
+ int offset;
159
+ int* grid;
160
+ VALUE ary, col, tmp;
161
+ VALUE r_min;
162
+ VALUE r_max;
163
+
164
+ rb_check_type(_width, T_FIXNUM);
165
+ rb_check_type(_height, T_FIXNUM);
166
+ width = NUM2INT(_width);
167
+ height = NUM2INT(_height);
168
+
169
+ r_min = rb_iv_get(self, "@min");
170
+ r_max = rb_iv_get(self, "@max");
171
+ min_re = rb_complex_re(r_min);
172
+ min_im = rb_complex_im(r_min);
173
+ max_re = rb_complex_re(r_max);
174
+ max_im = rb_complex_im(r_max);
175
+
176
+ max_iters = NUM2INT(rb_iv_get(self, "@max_iters"));
177
+
178
+
179
+ bmp = malloc(54 + (((24 * width + 31)/32) * 4) * height);
180
+ new_bmp_header(width, height, bmp);
181
+ bmp_image_data = bmp + 54;
182
+
183
+ for(x = 0; x < width; x++) {
184
+ x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
185
+ for(y = 0; y < height; y++) {
186
+ y0 = (max_im - min_im) * ((double)y / (double)height) + min_im;
187
+ offset = (((24 * width + 31)/32) * 4) * y + x * 3;
188
+ re = 0;
189
+ im = 0;
190
+ for(iter = 0; iter < max_iters && (re*re + im*im < 2*2); iter++) {
191
+ retemp = re*re - im*im + x0;
192
+ im = 2*re*im + y0;
193
+ re = retemp;
194
+ }
195
+ if(re*re + im*im < 2*2) {
196
+ bmp_image_data[offset + 0] = 0;
197
+ bmp_image_data[offset + 1] = 0;
198
+ bmp_image_data[offset + 2] = 0;
113
199
  } else {
114
- rb_ary_push(col, INT2NUM(iter));
200
+ hsv_to_rgb((iter / (double)max_iters) * 360, 1, /*1 - (iter / (double)max_iters),*/ 1 - (iter / (double)max_iters), &bmp_image_data[offset + 2], &bmp_image_data[offset + 1], &bmp_image_data[offset + 0]);
201
+ /*
202
+ bmp_image_data[offset + 0] = 255 - iter % 256;
203
+ bmp_image_data[offset + 1] = 255 - iter % 128;
204
+ bmp_image_data[offset + 2] = 255 - iter % 64;
205
+ */
115
206
  }
116
207
  }
117
208
  }
118
209
 
119
- return ary;
210
+ return rb_str_new(bmp, 54 + (((24 * width + 31)/32) * 4) * height);
120
211
  }
@@ -0,0 +1,13 @@
1
+ #include <stdlib.h>
2
+ #include <stdbool.h>
3
+ #include <math.h>
4
+ #include "bmp.h"
5
+ #include "ruby.h"
6
+
7
+ static VALUE Float_INFINITY = Qundef;
8
+ static VALUE Mandelbrot = Qundef;
9
+ static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self);
10
+ static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height);
11
+ static VALUE Mandelbrot_bmp(VALUE self, VALUE _width, VALUE _height);
12
+
13
+ int* mandelbrot_compute(int w, int h, double min_re, double min_im, double max_re, double max_im, int max_iter);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mandelbrot
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -18,7 +18,10 @@ extensions:
18
18
  - ext/mandelbrot/extconf.rb
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - ext/mandelbrot/bmp.c
21
22
  - ext/mandelbrot/mandelbrot.c
23
+ - ext/mandelbrot/bmp.h
24
+ - ext/mandelbrot/mandelbrot.h
22
25
  - ext/mandelbrot/extconf.rb
23
26
  - lib/mandelbrot.rb
24
27
  homepage: https://github.com/charliesome/mandelbrot