rubyonacid 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -1,21 +1,89 @@
1
1
  !http://github.com/jaymcgavren/rubyonacid/raw/master/generators.png!
2
2
 
3
+
3
4
  h1. Ruby On Acid
4
5
 
5
- A Ruby library for making trippy visuals.
6
+ A Ruby library for making trippy visuals and sounds. Need to pick locations and colors to draw in? Let one of Ruby On Acid's "factories" do it for you. Then swap out one factory for another without changing your code. Need to pick a note from a scale or a tempo? Ruby On Acid factories can do that too. And if none of the bundled factories does what you need, it's easy to write your own.
7
+
8
+
9
+ h1. Installation
6
10
 
11
+ <pre>
12
+ sudo gem install rubyonacid
13
+ </pre>
7
14
 
8
- h1. Factories
15
+
16
+ h1. Using Factories
9
17
 
10
18
  The factory is the core concept of Ruby On Acid. You create a factory of a particular type, and then anywhere in your code that you need a value within a certain range, you get it from the factory. For example, if you need x and y coordinates for drawing on a 800 x 600 window, you would tell a factory that you need a value for :x from 0 to 800, and a value for :y from 0 to 600. If you later wanted to change drawing patterns, you could simply swap out factories.
11
19
 
20
+ <pre>
21
+ def draw(factory)
22
+ window.draw_circle(
23
+ factory.get(:x, :max => 800),
24
+ factory.get(:y, :max => 600),
25
+ factory.get(:radius, :max => 100)
26
+ )
27
+ end
28
+
29
+ current_factory = RubyOnAcid::RandomFactory.new
30
+ 10.times {draw(current_factory)}
31
+ current_factory = RubyOnAcid::LoopFactory.new
32
+ 10.times {draw(current_factory)}
33
+ </pre>
34
+
35
+ See the examples directory for usage of the various factories.
36
+
37
+
38
+ h1. Writing Your Own Factories
39
+
40
+ Making new factories is easy - simply make a subclass of RubyOnAcid::Factory. Then write a get_unit() method that takes a key and returns a value between 0 and 1.
41
+
42
+ For example, here's the entire code for the bundled RandomFactory class:
43
+
44
+ <pre>
45
+ class RandomFactory < RubyOnAcid::Factory
46
+ def get_unit(key)
47
+ return rand
48
+ end
49
+ end
50
+ </pre>
51
+
52
+ Of course, when the values you're generating are random, you don't need to know what they'll be used for. For situations where you do care, you can use the "key" parameter, which is an indication from the factory user of the kind of value they need. This class tracks the previously returned value for a key and increments the next one:
53
+
54
+ <pre>
55
+ class CumulativeFactory < RubyOnAcid::Factory
56
+ def initialize
57
+ super #Be sure to call Factory's constructor if you override it!
58
+ @counters = Hash.new {|h, k| h[k] = 0.0}
59
+ end
60
+ def get_unit(key)
61
+ @counters[key] = (@counters[key] + 0.1) % 1.0
62
+ return @counters[key]
63
+ end
64
+ end
65
+
66
+ factory = CumulativeFactory.new
67
+ puts factory.get(:x) # => 0.1
68
+ puts factory.get(:y) # => 0.1
69
+ puts factory.get(:x) # => 0.2
70
+ puts factory.get(:z) # => 0.1
71
+ </pre>
72
+
73
+ Start by looking at the code for the bundled factories in the lib/rubyonacid/factories directory; it should give you some ideas of what's possible.
74
+
75
+
76
+ h1. Resources
77
+
78
+ The project page on GitHub lets you browse the latest code, or clone or fork the source repo for yourself.
79
+
80
+ "GitHub project":http://www.github.com/jaymcgavren/rubyonacid
12
81
 
13
- h1. Roadmap
82
+ The discussion list is the place for questions, problems, bug reports, feature requests, etc. And since working with Ruby On Acid is usually a creative endeavor, be sure to share your ideas and learn from others, too!
14
83
 
15
- * A factory that evaluates the last value for 2 keys and modifies a third based on them. (Example, change the size of rectangles based on their x and y coordinates.
16
- * Skip Factory: Add probability matrix [0.5, 0.9, 0.1...] that causes get_unit() to return true every time rand() is > given value. Also add mask value (0.1, 0.9), etc, that is added to random value to increase likelihood of returning true.
84
+ "Discussion list":http://groups.google.com/group/rubyonacid
17
85
 
18
86
 
19
87
  h1. Copyright
20
88
 
21
- Copyright (c) 2009 Jay McGavren. See LICENSE for details.
89
+ Copyright (c) 2009 Jay McGavren. Released under the MIT license. See the LICENSE file for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
data/examples/ascii.rb ADDED
@@ -0,0 +1,45 @@
1
+ #This method takes any Factory and uses it to determine the length of lines to print.
2
+ def make_lines(factory)
3
+ #Show what factory we're working with.
4
+ puts factory.class.name
5
+ 10.times do
6
+ #Get the length of the line.
7
+ #The :max option scales the returned length to be between 0 and 79.
8
+ line_length = factory.get(:length, :max => 79)
9
+ puts "|" * line_length
10
+ end
11
+ end
12
+
13
+ #Random factories generate a random number between 0 and 1.
14
+ require 'rubyonacid/factories/random'
15
+ make_lines RubyOnAcid::RandomFactory.new
16
+
17
+ #Loop factories loop from 0 to 1 (or 1 to 0 if the increment value is negative).
18
+ require 'rubyonacid/factories/loop'
19
+ make_lines RubyOnAcid::LoopFactory.new(0.2)
20
+ make_lines RubyOnAcid::LoopFactory.new(-0.2)
21
+
22
+ #Constant factories always return the same value,
23
+ require 'rubyonacid/factories/constant'
24
+ make_lines RubyOnAcid::ConstantFactory.new(0.5)
25
+
26
+ #This flash factory returns 0 twice, then 1 twice, then 0 twice, etc.
27
+ require 'rubyonacid/factories/flash'
28
+ make_lines RubyOnAcid::FlashFactory.new(2)
29
+
30
+ #Sine factories produce a "wave" pattern.
31
+ require 'rubyonacid/factories/sine'
32
+ make_lines RubyOnAcid::SineFactory.new(0.3)
33
+
34
+ #A RepeatFactory wraps another factory, queries it, and repeats the same value a certain number of times.
35
+ require 'rubyonacid/factories/repeat'
36
+ factory_to_repeat = RubyOnAcid::LoopFactory.new(0.3)
37
+ make_lines RubyOnAcid::RepeatFactory.new(factory_to_repeat, 2)
38
+
39
+ #A CombinationFactory combines the values of two or more other factories.
40
+ require 'rubyonacid/factories/combination'
41
+ factories_to_combine = [
42
+ RubyOnAcid::SineFactory.new(0.1),
43
+ RubyOnAcid::SineFactory.new(-0.2)
44
+ ]
45
+ make_lines RubyOnAcid::CombinationFactory.new(:source_factories => factories_to_combine)
data/examples/midi.rb CHANGED
@@ -3,7 +3,6 @@ require 'rubyonacid/factories/meta'
3
3
  require 'rubyonacid/factories/constant'
4
4
  require 'rubyonacid/factories/flash'
5
5
  require 'rubyonacid/factories/loop'
6
- require 'rubyonacid/factories/modulo'
7
6
  require 'rubyonacid/factories/random'
8
7
  require 'rubyonacid/factories/repeat'
9
8
  require 'rubyonacid/factories/sine'
@@ -35,7 +34,6 @@ factory.factory_pool << RubyOnAcid::RepeatFactory.new(
35
34
  RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.1, 0.1)),
36
35
  random_factory.within(:interval, 2, 100)
37
36
  )
38
- factory.factory_pool << RubyOnAcid::ModuloFactory.new(RubyOnAcid::LoopFactory.new(0.00001))
39
37
 
40
38
  #A skip factory, in charge of randomly resetting the meta factory.
41
39
  @resetter = RubyOnAcid::SkipFactory.new(0.999)
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), 'wxruby.rb')
2
+
3
+
4
+
5
+ class MyApp
6
+
7
+ WIDTH = 1920
8
+ HEIGHT = 1080
9
+
10
+ def on_init
11
+
12
+ ARGV.each do |file_name|
13
+
14
+ puts "Processing #{file_name}"
15
+
16
+ @f = YAML.load_file(file_name)
17
+
18
+ frame = Wx::Frame.new(nil, :size => [WIDTH, HEIGHT])
19
+
20
+
21
+ #Displays drawing.
22
+ bitmap = Wx::Bitmap.new(WIDTH, HEIGHT)
23
+ bitmap.draw do |surface|
24
+ surface.brush = Wx::BLACK_BRUSH
25
+ surface.draw_rectangle(0, 0, WIDTH, HEIGHT)
26
+ end
27
+ 10000.times do
28
+ bitmap.draw {|surface| render(surface)}
29
+ end
30
+ bitmap.draw do |surface|
31
+ surface.text_foreground = Wx::Colour.new(255, 255, 255, 255)
32
+ surface.draw_text("©2009 Jay McGavren. Licensed under a Creative Commons Attribution-Share Alike 3.0 United States License: http://creativecommons.org/licenses/by-sa/3.0/us/", 10, HEIGHT - 20)
33
+ end
34
+
35
+ bitmap.save_file(file_name + ".png", Wx::BITMAP_TYPE_PNG)
36
+
37
+ end
38
+
39
+ exit
40
+
41
+ end
42
+
43
+ end
44
+
45
+ app = MyApp.new
46
+ app.main_loop
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), 'wxruby.rb')
2
+
3
+
4
+ class MyApp
5
+
6
+ WIDTH = 320
7
+ HEIGHT = 320
8
+
9
+ def on_init
10
+
11
+ (1..1000).each do |file_number|
12
+
13
+ file_name = sprintf("%05d_random.jpg", file_number)
14
+
15
+ @f = create_factory
16
+
17
+ frame = Wx::Frame.new(nil, :size => [WIDTH, HEIGHT])
18
+
19
+ bitmap = Wx::Bitmap.new(WIDTH, HEIGHT)
20
+ bitmap.draw do |surface|
21
+ surface.brush = Wx::BLACK_BRUSH
22
+ surface.draw_rectangle(0, 0, WIDTH, HEIGHT)
23
+ end
24
+ 10000.times do
25
+ bitmap.draw {|surface| render(surface)}
26
+ end
27
+ bitmap.draw do |surface|
28
+ surface.text_foreground = Wx::Colour.new(255, 255, 255, 255)
29
+ y = 0
30
+ @f.to_yaml.split("\n").each do |line|
31
+ surface.draw_text(line, 0, y)
32
+ y += 10
33
+ end
34
+ end
35
+
36
+ File.open(file_name + ".yml", "w") do |file|
37
+ YAML.dump(@f, file)
38
+ end
39
+
40
+ bitmap.save_file(file_name, Wx::BITMAP_TYPE_JPEG)
41
+
42
+ end
43
+
44
+ exit
45
+
46
+ end
47
+
48
+ end
49
+
50
+ app = MyApp.new
51
+ app.main_loop
@@ -3,7 +3,6 @@ require 'rubyonacid/factories/meta'
3
3
  require 'rubyonacid/factories/constant'
4
4
  require 'rubyonacid/factories/flash'
5
5
  require 'rubyonacid/factories/loop'
6
- require 'rubyonacid/factories/modulo'
7
6
  require 'rubyonacid/factories/random'
8
7
  require 'rubyonacid/factories/repeat'
9
8
  require 'rubyonacid/factories/sine'
@@ -31,7 +30,6 @@ def generate_factories
31
30
  RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.1, 0.1)),
32
31
  random_factory.within(:interval, 2, 100)
33
32
  )
34
- factory_pool << RubyOnAcid::ModuloFactory.new(RubyOnAcid::LoopFactory.new(0.00001))
35
33
  factory_pool
36
34
  end
37
35
 
@@ -3,9 +3,9 @@ require 'wx'
3
3
  require 'rubyonacid/factories/meta'
4
4
  require 'rubyonacid/factories/constant'
5
5
  require 'rubyonacid/factories/flash'
6
- require 'rubyonacid/factories/increment'
7
6
  require 'rubyonacid/factories/loop'
8
7
  require 'rubyonacid/factories/random'
8
+ require 'rubyonacid/factories/repeat'
9
9
  require 'rubyonacid/factories/rinda'
10
10
  require 'rubyonacid/factories/sine'
11
11
  require 'rubyonacid/factories/skip'
@@ -19,23 +19,9 @@ class MyApp < Wx::App
19
19
 
20
20
  def on_init
21
21
 
22
- #The MetaFactory assigns factories to requested value types.
23
- @f = RubyOnAcid::MetaFactory.new
24
- #Loop factories loop from 0.0 to 1.0 (or 1.0 to 0.0 if the increment value is negative).
25
- @f.factory_pool << RubyOnAcid::LoopFactory.new(0.01)
26
- @f.factory_pool << RubyOnAcid::LoopFactory.new(-0.01)
27
- #Random factories generate random values.
28
- # @f.factory_pool << RubyOnAcid::RandomFactory.new
29
- #Constant factories always return the same value,
30
- @f.factory_pool << RubyOnAcid::ConstantFactory.new(rand)
31
- #Sine factories produce a "wave" pattern.
32
- @f.factory_pool << RubyOnAcid::SineFactory.new(0.1)
33
- @f.factory_pool << RubyOnAcid::SineFactory.new(-0.1)
34
-
35
- rinda_factory = RubyOnAcid::RindaFactory.new(ARGV[0])
36
- rinda_factory.start_service
37
- @f.assign_factory(:x, rinda_factory)
38
- @f.assign_factory(:y, rinda_factory)
22
+ @f = RubyOnAcid::RindaFactory.new(ARGV[0])
23
+ @f.default_factory = create_factory
24
+ @f.start_service
39
25
 
40
26
  #A skip factory, in charge of randomly resetting the meta factory.
41
27
  @resetter = RubyOnAcid::SkipFactory.new(0.999)
@@ -49,32 +35,109 @@ class MyApp < Wx::App
49
35
 
50
36
  #Animate periodically.
51
37
  t = Wx::Timer.new(self, 55)
52
- evt_timer(55) {animate(window)}
38
+ evt_timer(55) do
39
+ window.paint{|surface| render(surface)}
40
+ @f.default_factory.reset_assignments if @resetter.boolean(:reset)
41
+ end
53
42
  t.start(33)
54
43
 
55
44
  end
56
45
 
57
- def animate(window)
58
- window.paint do |surface|
59
- surface.pen = Wx::Pen.new(
60
- Wx::Colour.new(
61
- @f.within(:red, 0, 255).to_i,
62
- @f.within(:green, 0, 255).to_i,
63
- @f.within(:blue, 0, 255).to_i,
64
- @f.within(:alpha, 50, 255).to_i
65
- ),
66
- @f.within(:width, 1, 5).to_i
67
- )
68
- surface.draw_line(
69
- @f.within(:x, 0, WIDTH).to_i,
70
- @f.within(:y, 0, HEIGHT).to_i,
71
- @f.within(:x2, 0, WIDTH).to_i,
72
- @f.within(:y2, 0, HEIGHT).to_i
73
- )
74
- end
75
- # @f.reset_assignments if @resetter.boolean(:reset)
46
+ def create_factory
47
+ random_factory = RubyOnAcid::RandomFactory.new
48
+
49
+ #The MetaFactory assigns factories to requested value types.
50
+ meta_factory = RubyOnAcid::MetaFactory.new
51
+ #Loop factories loop from 0.0 to 1.0 (or 1.0 to 0.0 if the increment value is negative).
52
+ meta_factory.factory_pool << RubyOnAcid::LoopFactory.new(0.01)
53
+ meta_factory.factory_pool << RubyOnAcid::LoopFactory.new(-0.01)
54
+ meta_factory.factory_pool << RubyOnAcid::LoopFactory.new(0.001)
55
+ meta_factory.factory_pool << RubyOnAcid::LoopFactory.new(-0.001)
56
+ #Constant factories always return the same value,
57
+ meta_factory.factory_pool << RubyOnAcid::ConstantFactory.new(rand)
58
+ meta_factory.factory_pool << RubyOnAcid::ConstantFactory.new(rand)
59
+ meta_factory.factory_pool << RubyOnAcid::FlashFactory.new(rand(100))
60
+ #Sine factories produce a "wave" pattern.
61
+ meta_factory.factory_pool << RubyOnAcid::SineFactory.new(0.1)
62
+ meta_factory.factory_pool << RubyOnAcid::SineFactory.new(-0.1)
63
+ meta_factory.factory_pool << RubyOnAcid::SineFactory.new(0.01)
64
+ meta_factory.factory_pool << RubyOnAcid::SineFactory.new(-0.01)
65
+ meta_factory.factory_pool << RubyOnAcid::RepeatFactory.new(
66
+ RubyOnAcid::LoopFactory.new(random_factory.within(:increment, -0.1, 0.1)),
67
+ random_factory.within(:interval, 2, 100)
68
+ )
69
+ meta_factory.factory_pool << RubyOnAcid::RepeatFactory.new(
70
+ RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.1, 0.1)),
71
+ random_factory.within(:interval, 2, 100)
72
+ )
73
+
74
+ meta_factory
76
75
  end
77
76
 
77
+ def render(surface)
78
+ color = Wx::Colour.new(
79
+ @f.get(:red, :max => 255).to_i,
80
+ @f.get(:green, :max => 255).to_i,
81
+ @f.get(:blue, :max => 255).to_i,
82
+ @f.get(:alpha, :min => 50, :max => 200).to_i
83
+ )
84
+ surface.pen = Wx::Pen.new(color, @f.within(:width, 1, 5).to_i)
85
+ surface.brush = Wx::Brush.new(color, Wx::SOLID)
86
+ case @f.choose(:shape,
87
+ :arc,
88
+ :polygon,
89
+ :line,
90
+ # :rectangle,
91
+ :circle,
92
+ :spline
93
+ )
94
+ when :line
95
+ surface.draw_line(
96
+ @f.get(:x0, :max => WIDTH).to_i,
97
+ @f.get(:y0, :max => HEIGHT).to_i,
98
+ @f.get(:x1, :max => WIDTH).to_i,
99
+ @f.get(:y1, :max => HEIGHT).to_i
100
+ )
101
+ when :rectangle
102
+ surface.draw_rectangle(
103
+ @f.get(:x0, :max => WIDTH).to_i,
104
+ @f.get(:y0, :max => HEIGHT).to_i,
105
+ @f.get(:x1, :max => WIDTH).to_i,
106
+ @f.get(:y1, :max => HEIGHT).to_i
107
+ )
108
+ when :circle
109
+ surface.draw_circle(
110
+ @f.get(:x0, :max => WIDTH).to_i,
111
+ @f.get(:y0, :max => HEIGHT).to_i,
112
+ @f.get(:width, :max => WIDTH).to_i
113
+ )
114
+ when :arc
115
+ surface.draw_elliptic_arc(
116
+ @f.get(:x0, :max => WIDTH).to_i,
117
+ @f.get(:y0, :max => HEIGHT).to_i,
118
+ @f.get(:width, :max => WIDTH).to_i,
119
+ @f.get(:height, :max => HEIGHT).to_i,
120
+ @f.get(:arc_start, :max => 360).to_i,
121
+ @f.get(:arc_end, :max => 360).to_i
122
+ )
123
+ when :polygon
124
+ surface.draw_polygon(make_point_array)
125
+ when :spline
126
+ surface.draw_spline(make_point_array)
127
+ end
128
+ end
129
+
130
+ def make_point_array
131
+ points = []
132
+ @f.get(:points, :min => 3, :max => 6).to_i.times do |i|
133
+ points << Wx::Point.new(
134
+ @f.get("x#{i}".to_sym, :max => WIDTH).to_i,
135
+ @f.get("y#{i}".to_sym, :max => HEIGHT).to_i
136
+ )
137
+ end
138
+ points
139
+ end
140
+
78
141
  end
79
142
 
80
143
  app = MyApp.new
@@ -0,0 +1,158 @@
1
+ require 'rubygems'
2
+ require 'wx'
3
+ require 'rubyonacid/factories/meta'
4
+ require 'rubyonacid/factories/combination'
5
+ require 'rubyonacid/factories/constant'
6
+ require 'rubyonacid/factories/flash'
7
+ require 'rubyonacid/factories/loop'
8
+ require 'rubyonacid/factories/random'
9
+ require 'rubyonacid/factories/repeat'
10
+ require 'rubyonacid/factories/sine'
11
+ require 'rubyonacid/factories/skip'
12
+
13
+
14
+
15
+ class MyApp < Wx::App
16
+
17
+ WIDTH = 480
18
+ HEIGHT = 480
19
+
20
+ def on_init
21
+
22
+ @f = create_factory
23
+
24
+ #A skip factory, in charge of randomly resetting the meta factory.
25
+ @resetter = RubyOnAcid::SkipFactory.new(0.999)
26
+
27
+ #Containing frame.
28
+ frame = Wx::Frame.new(nil, :size => [WIDTH, HEIGHT])
29
+ frame.show
30
+
31
+ #Displays drawing.
32
+ window = Wx::Window.new(frame, :size => [WIDTH, HEIGHT])
33
+
34
+ #Animate periodically.
35
+ t = Wx::Timer.new(self, 55)
36
+ evt_timer(55) do
37
+ window.paint{|surface| render(surface)}
38
+ @f.reset_assignments if @resetter.boolean(:reset)
39
+ end
40
+ t.start(33)
41
+
42
+ end
43
+
44
+
45
+ def create_factory
46
+
47
+ random_factory = RubyOnAcid::RandomFactory.new
48
+
49
+ source_factories = []
50
+ #Loop factories loop from 0.0 to 1.0 (or 1.0 to 0.0 if the increment value is negative).
51
+ source_factories << RubyOnAcid::LoopFactory.new(0.01)
52
+ source_factories << RubyOnAcid::LoopFactory.new(-0.01)
53
+ source_factories << RubyOnAcid::LoopFactory.new(0.001)
54
+ source_factories << RubyOnAcid::LoopFactory.new(-0.001)
55
+ #Constant factories always return the same value,
56
+ source_factories << RubyOnAcid::ConstantFactory.new(rand)
57
+ source_factories << RubyOnAcid::ConstantFactory.new(rand)
58
+ source_factories << RubyOnAcid::FlashFactory.new(rand(100))
59
+ #Sine factories produce a "wave" pattern.
60
+ source_factories << RubyOnAcid::SineFactory.new(0.1)
61
+ source_factories << RubyOnAcid::SineFactory.new(-0.1)
62
+ source_factories << RubyOnAcid::SineFactory.new(0.01)
63
+ source_factories << RubyOnAcid::SineFactory.new(-0.01)
64
+ #A RepeatFactory wraps another factory, queries it, and repeats the same value a certain number of times.
65
+ source_factories << RubyOnAcid::RepeatFactory.new(
66
+ RubyOnAcid::LoopFactory.new(random_factory.within(:increment, -0.1, 0.1)),
67
+ random_factory.get(:interval, :min => 2, :max => 100)
68
+ )
69
+ source_factories << RubyOnAcid::RepeatFactory.new(
70
+ RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.1, 0.1)),
71
+ random_factory.get(:interval, :min => 2, :max => 100)
72
+ )
73
+ #A CombinationFactory combines the values of two or more other factories.
74
+ combination_factory = RubyOnAcid::CombinationFactory.new
75
+ 2.times do
76
+ combination_factory.source_factories << source_factories[rand(source_factories.length)]
77
+ end
78
+ source_factories << combination_factory
79
+
80
+ #The MetaFactory pulls requested value types from the other factories.
81
+ meta_factory = RubyOnAcid::MetaFactory.new
82
+ meta_factory.factory_pool = source_factories
83
+
84
+ meta_factory
85
+
86
+ end
87
+
88
+
89
+ def render(surface)
90
+ color = Wx::Colour.new(
91
+ @f.get(:red, :max => 255).to_i,
92
+ @f.get(:green, :max => 255).to_i,
93
+ @f.get(:blue, :max => 255).to_i,
94
+ @f.get(:alpha, :min => 50, :max => 200).to_i
95
+ )
96
+ surface.pen = Wx::Pen.new(color, @f.within(:width, 1, 5).to_i)
97
+ surface.brush = Wx::Brush.new(color, Wx::SOLID)
98
+ case @f.choose(:shape,
99
+ :arc,
100
+ :polygon,
101
+ :line,
102
+ :rectangle,
103
+ :circle,
104
+ :spline
105
+ )
106
+ when :line
107
+ surface.draw_line(
108
+ @f.get(:x0, :max => WIDTH).to_i,
109
+ @f.get(:y0, :max => HEIGHT).to_i,
110
+ @f.get(:x1, :max => WIDTH).to_i,
111
+ @f.get(:y1, :max => HEIGHT).to_i
112
+ )
113
+ when :rectangle
114
+ surface.draw_rectangle(
115
+ @f.get(:x0, :max => WIDTH).to_i,
116
+ @f.get(:y0, :max => HEIGHT).to_i,
117
+ @f.get(:x1, :max => WIDTH).to_i,
118
+ @f.get(:y1, :max => HEIGHT).to_i
119
+ )
120
+ when :circle
121
+ surface.draw_circle(
122
+ @f.get(:x0, :max => WIDTH).to_i,
123
+ @f.get(:y0, :max => HEIGHT).to_i,
124
+ @f.get(:width, :max => 100).to_i
125
+ )
126
+ when :arc
127
+ surface.draw_elliptic_arc(
128
+ @f.get(:x0, :max => WIDTH).to_i,
129
+ @f.get(:y0, :max => HEIGHT).to_i,
130
+ @f.get(:width, :max => 100).to_i,
131
+ @f.get(:height, :max => 100).to_i,
132
+ @f.get(:arc_start, :max => 360).to_i,
133
+ @f.get(:arc_end, :max => 360).to_i
134
+ )
135
+ when :polygon
136
+ surface.draw_polygon(make_point_array)
137
+ when :spline
138
+ surface.draw_spline(make_point_array)
139
+ end
140
+ end
141
+
142
+
143
+ def make_point_array
144
+ points = []
145
+ 3.times do |i|
146
+ points << Wx::Point.new(
147
+ @f.get("x#{i}".to_sym, :max => WIDTH).to_i,
148
+ @f.get("y#{i}".to_sym, :max => HEIGHT).to_i
149
+ )
150
+ end
151
+ points
152
+ end
153
+
154
+
155
+ end
156
+
157
+ app = MyApp.new
158
+ app.main_loop
data/generators.png ADDED
Binary file
@@ -0,0 +1,66 @@
1
+ require 'rubyonacid/factory'
2
+
3
+ module RubyOnAcid
4
+
5
+ class CombinationFactory < Factory
6
+
7
+ ADD = :add
8
+ SUBTRACT = :subtract
9
+ MULTIPLY = :multiply
10
+ DIVIDE = :divide
11
+ CONSTRAIN = :constrain
12
+ WRAP = :wrap
13
+
14
+ attr_accessor :source_factories
15
+ attr_accessor :operation
16
+ attr_accessor :constrain_mode
17
+
18
+ def initialize(options = {})
19
+ super
20
+ @source_factories = options[:source_factories] || []
21
+ @operation = options[:operation] || ADD
22
+ @constrain_mode = options[:constrain_mode] || WRAP
23
+ end
24
+
25
+ def get_unit(key)
26
+ combined_value = combine(key)
27
+ constrain(combined_value)
28
+ end
29
+
30
+ private
31
+
32
+ def combine(key)
33
+ initial_value = @source_factories.first.get_unit(key)
34
+ additional_values = @source_factories.slice(1, @source_factories.length - 1).map {|f| f.get_unit(key)}
35
+ case @operation
36
+ when ADD
37
+ return additional_values.inject(initial_value) {|sum, value| sum + value}
38
+ when SUBTRACT
39
+ return additional_values.inject(initial_value) {|sum, value| sum - value}
40
+ when MULTIPLY
41
+ return additional_values.inject(initial_value) {|product, value| product * value}
42
+ when DIVIDE
43
+ return additional_values.inject(initial_value) {|product, value| product / value}
44
+ else
45
+ raise "invalid operation - must be ADD, MULTIPLY, SUBTRACT, or DIVIDE"
46
+ end
47
+ end
48
+
49
+ def constrain(value)
50
+ case @constrain_mode
51
+ when CONSTRAIN
52
+ if value > 1.0
53
+ return 1.0
54
+ elsif value < 0.0
55
+ return 0.0
56
+ else
57
+ return value
58
+ end
59
+ when WRAP
60
+ return value % 1.0
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -3,7 +3,8 @@ require 'rubyonacid/factory'
3
3
  module RubyOnAcid
4
4
 
5
5
  class IncrementFactory < Factory
6
-
6
+
7
+ #The amount to increment counters by.
7
8
  attr_accessor :interval
8
9
  def interval=(value)
9
10
  @interval = value
@@ -18,7 +19,7 @@ class IncrementFactory < Factory
18
19
  @interval = interval
19
20
  end
20
21
 
21
- #Increment counter for key and get its sine, then scale it between 0 and 1.
22
+ #Increment counter for given key and return it. Constrain between 0 and 1.
22
23
  def get_unit(key)
23
24
  @counters[key] ||= @start_value
24
25
  @counters[key] += @interval