mandelbrot 0.1
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.
- data/ext/mandelbrot/extconf.rb +3 -0
- data/ext/mandelbrot/mandelbrot.c +120 -0
- data/lib/mandelbrot.rb +1 -0
- metadata +48 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <stdbool.h>
|
3
|
+
#include <complex.h>
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
static ID i_Complex = Qundef;
|
7
|
+
static ID i_to_f = Qundef;
|
8
|
+
static ID i_INFINITY = Qundef;
|
9
|
+
|
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
|
+
static double rb_complex_re(VALUE cplx)
|
16
|
+
{
|
17
|
+
_Complex ret;
|
18
|
+
VALUE tmp = Qnil;
|
19
|
+
rb_check_type(cplx, T_COMPLEX);
|
20
|
+
|
21
|
+
tmp = rb_funcall(RCOMPLEX(cplx)->real, i_to_f, 0);
|
22
|
+
return NUM2DBL(tmp);
|
23
|
+
}
|
24
|
+
|
25
|
+
static double rb_complex_im(VALUE cplx)
|
26
|
+
{
|
27
|
+
_Complex ret;
|
28
|
+
VALUE tmp = Qnil;
|
29
|
+
rb_check_type(cplx, T_COMPLEX);
|
30
|
+
|
31
|
+
tmp = rb_funcall(RCOMPLEX(cplx)->imag, i_to_f, 0);
|
32
|
+
return NUM2DBL(tmp);
|
33
|
+
}
|
34
|
+
|
35
|
+
void Init_mandelbrot()
|
36
|
+
{
|
37
|
+
i_Complex = rb_intern("Complex");
|
38
|
+
i_to_f = rb_intern("to_f");
|
39
|
+
i_INFINITY = rb_intern("INFINITY");
|
40
|
+
Float_INFINITY = rb_const_get(rb_cFloat, i_INFINITY);
|
41
|
+
|
42
|
+
Mandelbrot = rb_define_class("Mandelbrot", rb_cObject);
|
43
|
+
rb_define_method(Mandelbrot, "initialize", Mandelbrot_initialize, -1);
|
44
|
+
rb_define_method(Mandelbrot, "compute", Mandelbrot_compute, 2);
|
45
|
+
rb_define_attr(Mandelbrot, "min", true, false);
|
46
|
+
rb_define_attr(Mandelbrot, "max", true, false);
|
47
|
+
rb_define_attr(Mandelbrot, "max_iters", true, true);
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE Mandelbrot_initialize(int argc, VALUE* argv, VALUE self)
|
51
|
+
{
|
52
|
+
VALUE min, max;
|
53
|
+
rb_scan_args(argc, argv, "02", &min, &max);
|
54
|
+
|
55
|
+
if(NIL_P(min)) {
|
56
|
+
min = rb_funcall(rb_mKernel, i_Complex, 2, DBL2NUM(-1), DBL2NUM(-1));
|
57
|
+
}
|
58
|
+
if(NIL_P(max)) {
|
59
|
+
max = rb_funcall(rb_mKernel, i_Complex, 2, DBL2NUM(1), DBL2NUM(1));
|
60
|
+
}
|
61
|
+
|
62
|
+
rb_check_type(min, T_COMPLEX);
|
63
|
+
rb_check_type(max, T_COMPLEX);
|
64
|
+
|
65
|
+
rb_iv_set(self, "@min", min);
|
66
|
+
rb_iv_set(self, "@max", max);
|
67
|
+
rb_iv_set(self, "@max_iters", INT2NUM(128));
|
68
|
+
|
69
|
+
return Qnil;
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE Mandelbrot_compute(VALUE self, VALUE _width, VALUE _height)
|
73
|
+
{
|
74
|
+
double min_re, min_im, max_re, max_im;
|
75
|
+
double x0, y0, re, im, retemp;
|
76
|
+
int width, height;
|
77
|
+
int max_iters;
|
78
|
+
int x, y, iter;
|
79
|
+
VALUE ary, col, tmp;
|
80
|
+
VALUE r_min;
|
81
|
+
VALUE r_max;
|
82
|
+
|
83
|
+
rb_check_type(_width, T_FIXNUM);
|
84
|
+
rb_check_type(_height, T_FIXNUM);
|
85
|
+
width = NUM2INT(_width);
|
86
|
+
height = NUM2INT(_height);
|
87
|
+
|
88
|
+
r_min = rb_iv_get(self, "@min");
|
89
|
+
r_max = rb_iv_get(self, "@max");
|
90
|
+
min_re = rb_complex_re(r_min);
|
91
|
+
min_im = rb_complex_im(r_min);
|
92
|
+
max_re = rb_complex_re(r_max);
|
93
|
+
max_im = rb_complex_im(r_max);
|
94
|
+
|
95
|
+
max_iters = NUM2INT(rb_iv_get(self, "@max_iters"));
|
96
|
+
|
97
|
+
ary = rb_ary_new();
|
98
|
+
for(x = 0; x < width; x++) {
|
99
|
+
col = rb_ary_new();
|
100
|
+
rb_ary_push(ary, col);
|
101
|
+
for(y = 0; y < height; y++) {
|
102
|
+
x0 = (max_re - min_re) * ((double)x / (double)width) + min_re;
|
103
|
+
y0 = (max_im - min_im) * ((double)y / (double)height) + min_im;
|
104
|
+
re = 0;
|
105
|
+
im = 0;
|
106
|
+
for(iter = 0; iter < max_iters && (re*re + im*im < 2*2); iter++) {
|
107
|
+
retemp = re*re - im*im + x0;
|
108
|
+
im = 2*re*im + y0;
|
109
|
+
re = retemp;
|
110
|
+
}
|
111
|
+
if(x*x + y*y < 2*2) {
|
112
|
+
rb_ary_push(col, Float_INFINITY);
|
113
|
+
} else {
|
114
|
+
rb_ary_push(col, INT2NUM(iter));
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
return ary;
|
120
|
+
}
|
data/lib/mandelbrot.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'mandelbrot/mandelbrot'
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mandelbrot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Charlie Somerville
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-20 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: charlie@charliesomerville.com
|
16
|
+
executables: []
|
17
|
+
extensions:
|
18
|
+
- ext/mandelbrot/extconf.rb
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- ext/mandelbrot/mandelbrot.c
|
22
|
+
- ext/mandelbrot/extconf.rb
|
23
|
+
- lib/mandelbrot.rb
|
24
|
+
homepage: https://github.com/charliesome/mandelbrot
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 1.8.10
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: A Ruby C extension for rendering Mandelbrot fractals
|
48
|
+
test_files: []
|