cantor_carpets 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/array2d.rb +95 -0
- data/lib/cantor_carpets.rb +1 -0
- data/lib/carpet.rb +56 -0
- metadata +48 -0
data/lib/array2d.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
class Array2D
|
2
|
+
attr_accessor :state
|
3
|
+
|
4
|
+
def initialize(rows, columns, value=nil)
|
5
|
+
@state = Array.new(rows) { Array.new(columns) { value } }
|
6
|
+
end
|
7
|
+
|
8
|
+
def each(&block)
|
9
|
+
@state.each do |row|
|
10
|
+
row.each do |e|
|
11
|
+
yield e
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def each_with_index(&block)
|
17
|
+
@state.each_with_index do |row, row_index|
|
18
|
+
row.each_with_index do |e, column_index|
|
19
|
+
yield e, [row_index, column_index]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@state.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(o)
|
29
|
+
o.class == self.class && o.state == state
|
30
|
+
end
|
31
|
+
|
32
|
+
def size
|
33
|
+
[@state.size, @state[0].size]
|
34
|
+
end
|
35
|
+
|
36
|
+
def row_size
|
37
|
+
@state.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def column_size
|
41
|
+
@state[0].size
|
42
|
+
end
|
43
|
+
|
44
|
+
def []=(x, y, value)
|
45
|
+
case x
|
46
|
+
when Integer
|
47
|
+
case y
|
48
|
+
when Integer
|
49
|
+
@state[x][y] = value
|
50
|
+
when Range
|
51
|
+
y.each {|yi| @state[x][yi] = value[yi - y.first]}
|
52
|
+
end
|
53
|
+
when Range
|
54
|
+
case y
|
55
|
+
when Integer
|
56
|
+
x.each {|xi| @state[xi][y] = value[xi - x.first]}
|
57
|
+
when Range
|
58
|
+
x.each do |xi|
|
59
|
+
y.each do |yi|
|
60
|
+
@state[xi][yi] = value[xi - x.first, yi - y.first]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def [](x, y)
|
68
|
+
case x
|
69
|
+
when Integer
|
70
|
+
case y
|
71
|
+
when Integer
|
72
|
+
@state[x][y]
|
73
|
+
when Range
|
74
|
+
subarray = Array.new(y.to_a.size)
|
75
|
+
y.each {|yi| subarray[yi - y.first] = @state[x][yi]}
|
76
|
+
subarray
|
77
|
+
end
|
78
|
+
when Range
|
79
|
+
case y
|
80
|
+
when Integer
|
81
|
+
subarray = Array.new(x.to_a.size)
|
82
|
+
x.each {|xi| subarray[xi - x.first] = @state[xi][y]}
|
83
|
+
subarray
|
84
|
+
when Range
|
85
|
+
subarray = Array2D.new(x.to_a.size, y.to_a.size)
|
86
|
+
x.each do |xi|
|
87
|
+
y.each do |yi|
|
88
|
+
subarray.state[xi - x.first][yi - y.first] = @state[xi][yi]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
subarray
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'carpet'
|
data/lib/carpet.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'png'
|
2
|
+
require_relative 'array2d'
|
3
|
+
|
4
|
+
class Carpet
|
5
|
+
attr_reader :seed, :depth, :bits, :image
|
6
|
+
|
7
|
+
def initialize(seed, depth)
|
8
|
+
@seed = seed
|
9
|
+
@depth = depth
|
10
|
+
compute_carpet
|
11
|
+
end
|
12
|
+
|
13
|
+
def compute_carpet
|
14
|
+
@bits = calculate_bits(new_bit_array)
|
15
|
+
@image = create_image
|
16
|
+
end
|
17
|
+
|
18
|
+
def new_bit_array
|
19
|
+
Array2D.new(@seed.row_size ** @depth,
|
20
|
+
@seed.column_size ** @depth, 0)
|
21
|
+
end
|
22
|
+
|
23
|
+
def calculate_bits(bit_array)
|
24
|
+
if bit_array.size == @seed.size
|
25
|
+
return @seed
|
26
|
+
end
|
27
|
+
|
28
|
+
row_chunk = bit_array.row_size / @seed.row_size
|
29
|
+
col_chunk = bit_array.column_size / @seed.column_size
|
30
|
+
|
31
|
+
@seed.each_with_index do |e, index|
|
32
|
+
xi = index[0]
|
33
|
+
yi = index[1]
|
34
|
+
row_range = (row_chunk * xi)...(row_chunk * (xi + 1))
|
35
|
+
column_range = (col_chunk * yi)...(col_chunk * (yi + 1))
|
36
|
+
if e == 1
|
37
|
+
bit_array[row_range, column_range] = calculate_bits(bit_array[row_range, column_range])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
bit_array
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_image
|
44
|
+
canvas = PNG::Canvas.new(@seed.column_size ** @depth,
|
45
|
+
@seed.row_size ** @depth,
|
46
|
+
PNG::Color::White)
|
47
|
+
canvas.each do |x, y, color|
|
48
|
+
canvas[x, y] = PNG::Color::Black if @bits[-y, x] == 1
|
49
|
+
end
|
50
|
+
PNG.new(canvas)
|
51
|
+
end
|
52
|
+
|
53
|
+
def write_image(name='carpet.png')
|
54
|
+
@image.save(name)
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cantor_carpets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Luke Grecki
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-28 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: You can generate cantor dust, sierpinski carpet, and other 2D cantor
|
15
|
+
sets.
|
16
|
+
email: lukegrecki@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/array2d.rb
|
22
|
+
- lib/cantor_carpets.rb
|
23
|
+
- lib/carpet.rb
|
24
|
+
homepage: http://rubygems.org/gems/cantor_carpets
|
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.11
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: Generate images of 2D cantor sets
|
48
|
+
test_files: []
|