mandelbrot 0.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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