ruby-processing 2.4.3 → 2.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/CHANGELOG +5 -0
- data/README.md +4 -2
- data/lib/ruby-processing/exporters/application_exporter.rb +1 -0
- data/lib/ruby-processing/version.rb +1 -1
- data/library/boids/boids.rb +14 -13
- data/library/vecmath/lib/vec.rb +20 -4
- data/samples/contributed/circle_collision.rb +92 -149
- data/samples/contributed/drawolver.rb +13 -27
- data/samples/contributed/elegant_ball.rb +158 -0
- data/samples/contributed/fern.rb +16 -3
- data/samples/contributed/flight_patterns.rb +16 -4
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/bumpy_surface_noise.rb +4 -9
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/data/java_args.txt +0 -0
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/library/custom_shape/custom_shape.rb +1 -1
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/library/particle_system/particle_system.rb +7 -10
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/library/surface/surface.rb +2 -2
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/liquidy.rb +7 -7
- data/samples/external_library/java_processing/{pbox2d → box2d_processing}/polygons.rb +4 -9
- data/samples/external_library/java_processing/custom/README.md +15 -0
- data/samples/external_library/java_processing/custom/Rakefile +28 -0
- data/samples/external_library/java_processing/custom/landscape.rb +58 -0
- data/samples/external_library/java_processing/custom/src/nn/Connection.java +47 -0
- data/samples/external_library/java_processing/custom/src/nn/HiddenNeuron.java +20 -0
- data/samples/external_library/java_processing/custom/src/nn/InputNeuron.java +23 -0
- data/samples/external_library/java_processing/custom/src/nn/Network.java +136 -0
- data/samples/external_library/java_processing/custom/src/nn/Neuron.java +79 -0
- data/samples/external_library/java_processing/custom/src/nn/OutputNeuron.java +7 -0
- data/samples/external_library/java_processing/custom/xor.rb +88 -0
- data/samples/external_library/ruby_gem/README +1 -1
- data/samples/external_library/ruby_gem/data/data.json +8 -0
- data/samples/external_library/ruby_gem/draw_test.rb +171 -0
- data/samples/processing_app/basics/form/icosahedra.rb +39 -0
- data/samples/processing_app/basics/form/library/icosahedron/icosahedron.rb +60 -0
- data/samples/processing_app/basics/form/toroid.rb +78 -92
- data/samples/processing_app/basics/transform/birds.rb +6 -12
- data/samples/processing_app/basics/transform/cubes_in_cube.rb +25 -22
- data/samples/processing_app/basics/transform/library/cube/cube.rb +16 -16
- data/samples/processing_app/basics/transform/rotate_push_pop.rb +1 -1
- data/samples/processing_app/demos/graphics/bezier_patch.rb +18 -31
- data/samples/processing_app/demos/graphics/trefoil.rb +15 -15
- data/samples/processing_app/library/vecmath/acceleration_with_vectors.rb +3 -3
- data/samples/processing_app/library/vecmath/hilbert_fractal.rb +2 -2
- data/samples/processing_app/library/vecmath/library/flock/flock.rb +18 -21
- data/samples/processing_app/library/vecmath/library/hilbert/hilbert.rb +11 -8
- data/samples/processing_app/library/vecmath/library/wiggler/wiggler.rb +7 -15
- data/samples/processing_app/library/vecmath/seeking_neural.rb +172 -0
- data/samples/processing_app/topics/animation/animated_sprite.rb +5 -8
- data/samples/processing_app/topics/animation/sequential.rb +2 -3
- data/samples/processing_app/topics/create_shapes/library/particle/particle_system.rb +7 -7
- data/samples/processing_app/topics/create_shapes/particle_system_pshape.rb +2 -2
- data/samples/processing_app/topics/create_shapes/wiggle_pshape.rb +2 -1
- data/samples/processing_app/topics/lsystems/koch.rb +1 -1
- data/samples/processing_app/topics/lsystems/library/koch/koch_fractal.rb +24 -23
- data/samples/processing_app/topics/motion/circle_collision.rb +117 -160
- data/samples/processing_app/topics/motion/library/cube/cube.rb +1 -1
- data/samples/processing_app/topics/motion/morph.rb +1 -1
- data/samples/processing_app/topics/motion/reflection1.rb +17 -16
- data/samples/processing_app/topics/shaders/conway.rb +2 -2
- data/samples/processing_app/topics/shaders/data/conway.glsl +10 -10
- data/samples/processing_app/topics/shaders/glsl_heightmap_noise.rb +9 -8
- data/samples/processing_app/topics/shaders/landscape.rb +1 -1
- data/samples/processing_app/topics/simulate/flocking.rb +1 -1
- data/samples/processing_app/topics/simulate/library/flock/flock.rb +62 -57
- data/samples/processing_app/topics/simulate/multiple_particle_systems.rb +8 -28
- data/samples/processing_app/topics/simulate/simple_particle_system.rb +9 -7
- data/samples/processing_app/topics/simulate/smoke_particle_system.rb +12 -11
- data/vendors/Rakefile +2 -2
- metadata +26 -21
- data/samples/contributed/pong.rb +0 -177
- data/samples/contributed/simple_buffer.rb +0 -44
- data/samples/external_library/java_processing/pbox2d/contact_test.rb +0 -23
- data/samples/processing_app/basics/form/icosahedra/icosahedra.rb +0 -72
- data/samples/processing_app/basics/form/icosahedra/icosahedron.rb +0 -116
- data/samples/processing_app/basics/form/icosahedra/shape_3D.rb +0 -25
@@ -35,23 +35,26 @@ end
|
|
35
35
|
###########################
|
36
36
|
class Hilbert
|
37
37
|
include Processing::Proxy
|
38
|
-
ADJUSTMENT = [0, 0.5, 1.5, 3.5, 7.5, 15]
|
39
38
|
attr_reader :grammar, :axiom, :production, :premis, :rule,
|
40
|
-
:theta, :distance, :phi, :gen
|
39
|
+
:theta, :distance, :phi, :gen, :adj_array
|
41
40
|
|
42
|
-
def initialize(
|
41
|
+
def initialize(size: 1.0, gen: 1)
|
43
42
|
@axiom = "X" # AXIOM
|
44
43
|
@rule = {"X" => "^<XF^<XFX-F^>>XFX&F+>>XFX-F>X->"} # RULE
|
45
44
|
@gen = gen
|
46
45
|
@grammar = Grammar.new(axiom, rule)
|
47
46
|
@production = grammar.generate gen
|
48
|
-
@distance =
|
49
|
-
@theta =
|
50
|
-
@phi =
|
47
|
+
@distance = size / (gen**2 - 1)
|
48
|
+
@theta = radians 90
|
49
|
+
@phi = radians 90
|
50
|
+
@adj_array = [0, 0.5, 1.5, 3.5, 7.5, 15].map{|x| Vec3D.new(x * -1, x, x * -1)}
|
51
|
+
|
51
52
|
end
|
52
53
|
|
53
54
|
def render()
|
54
|
-
translate( -distance * ADJUSTMENT[gen], distance * ADJUSTMENT[gen], -distance * ADJUSTMENT[gen])
|
55
|
+
#translate( -distance * ADJUSTMENT[gen], distance * ADJUSTMENT[gen], -distance * ADJUSTMENT[gen])
|
56
|
+
adj = adj_array[gen] * distance
|
57
|
+
translate(adj.x, adj.y, adj.z)
|
55
58
|
fill(0, 75, 152)
|
56
59
|
light_specular(204, 204, 204)
|
57
60
|
specular(255, 255, 255)
|
@@ -81,4 +84,4 @@ class Hilbert
|
|
81
84
|
end
|
82
85
|
end
|
83
86
|
|
84
|
-
end
|
87
|
+
end
|
@@ -10,12 +10,8 @@ class Wiggler
|
|
10
10
|
@y = height/2
|
11
11
|
@yoff = 0
|
12
12
|
# The "original" locations of the vertices make up a circle
|
13
|
-
|
14
|
-
(0 ... TAU).
|
15
|
-
v = Vec2D.from_angle(a)
|
16
|
-
v *= 100
|
17
|
-
original << v
|
18
|
-
end
|
13
|
+
|
14
|
+
@original = (0 ... 5 * TAU).map{|a| Vec2D.from_angle(a * 0.2) * 100}
|
19
15
|
|
20
16
|
# Now make the PShape with those vertices
|
21
17
|
@s = create_shape
|
@@ -23,22 +19,18 @@ class Wiggler
|
|
23
19
|
s.fill(127)
|
24
20
|
s.stroke(0)
|
25
21
|
s.stroke_weight(2)
|
26
|
-
original.
|
27
|
-
s.vertex(v.x, v.y)
|
28
|
-
end
|
22
|
+
original.map{ |v| s.vertex(v.x, v.y)}
|
29
23
|
s.end_shape(CLOSE)
|
30
24
|
end
|
31
25
|
|
32
26
|
def wiggle
|
33
27
|
@xoff = 0
|
34
28
|
# Apply an offset to each vertex
|
35
|
-
|
29
|
+
rad = -> (pos){(Vec2D.from_angle(TAU * noise(xoff, yoff)) * 4) + pos}
|
30
|
+
|
31
|
+
original.each_with_index do |pos, i|
|
36
32
|
# Calculate a new vertex location based on noise around "original" location
|
37
|
-
|
38
|
-
a = TAU*noise(xoff,yoff)
|
39
|
-
r = Vec2D.from_angle(a)
|
40
|
-
r *= 4
|
41
|
-
r += pos
|
33
|
+
r = rad.call(pos)
|
42
34
|
# Set the location of each vertex to the new one
|
43
35
|
s.set_vertex(i, r.x, r.y)
|
44
36
|
# increment perlin noise x value
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# Based on SeekingNeural example by Daniel Shiffman
|
2
|
+
# The Nature of Code
|
3
|
+
# http://natureofcode.com
|
4
|
+
|
5
|
+
load_library :vecmath
|
6
|
+
|
7
|
+
|
8
|
+
module SeekingNeural
|
9
|
+
class Perceptron
|
10
|
+
# Perceptron is created with n weights and learning constant
|
11
|
+
def initialize(n, c)
|
12
|
+
@weights = Array.new(n){ rand(0 .. 1.0) }
|
13
|
+
@c = c
|
14
|
+
end
|
15
|
+
|
16
|
+
# Function to train the Perceptron
|
17
|
+
# Weights are adjusted based on vehicle's error
|
18
|
+
def train(forces, error)
|
19
|
+
trained = @weights.zip(forces.map{|f| f.to_a}
|
20
|
+
.map{|a, b| (a * error.x + b * error.y) * @c})
|
21
|
+
.map {|w, c| constrain(w + c, 0.0, 1.0)}
|
22
|
+
@weights = trained
|
23
|
+
end
|
24
|
+
|
25
|
+
# Give me a steering result
|
26
|
+
def feedforward(forces)
|
27
|
+
# Sum all values
|
28
|
+
forces.zip(@weights).map{|a, b| a * b}.inject(Vec2D.new, :+)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Seek
|
33
|
+
# Daniel Shiffman <http://www.shiffman.net>
|
34
|
+
|
35
|
+
class Vehicle
|
36
|
+
|
37
|
+
MAX_SPEED = 4
|
38
|
+
MAX_FORCE = 0.1
|
39
|
+
attr_reader :brain, :sz, :location, :targets, :desired
|
40
|
+
attr_reader :maxforce_squared, :maxspeed_squared
|
41
|
+
|
42
|
+
def initialize(n, x, y)
|
43
|
+
@brain = Perceptron.new(n, 0.001)
|
44
|
+
@acceleration = Vec2D.new
|
45
|
+
@velocity = Vec2D.new
|
46
|
+
@location = Vec2D.new(x, y)
|
47
|
+
@sz = 6.0
|
48
|
+
@maxspeed_squared = MAX_SPEED * MAX_SPEED
|
49
|
+
@maxforce_squared = MAX_FORCE * MAX_FORCE
|
50
|
+
end
|
51
|
+
|
52
|
+
# Method to update location
|
53
|
+
def update(width, height)
|
54
|
+
# Update velocity
|
55
|
+
@velocity += @acceleration
|
56
|
+
# Limit speed
|
57
|
+
@velocity.set_mag(MAX_SPEED) {@velocity.mag_squared > maxspeed_squared}
|
58
|
+
@location += @velocity
|
59
|
+
# Reset acceleration to 0 each cycle
|
60
|
+
@acceleration *= 0
|
61
|
+
|
62
|
+
@location.x = constrain(location.x, 0, width)
|
63
|
+
@location.y = constrain(location.y, 0, height)
|
64
|
+
end
|
65
|
+
|
66
|
+
def apply_force(force)
|
67
|
+
# We could add mass here if we want A = F / M
|
68
|
+
@acceleration += force
|
69
|
+
end
|
70
|
+
|
71
|
+
# Here is where the brain processes everything
|
72
|
+
def steer(targets, desired)
|
73
|
+
# Steer towards all targets
|
74
|
+
forces = targets.map{|target| seek(target) }
|
75
|
+
|
76
|
+
# That array of forces is the input to the brain
|
77
|
+
result = brain.feedforward(forces)
|
78
|
+
|
79
|
+
# Use the result to steer the vehicle
|
80
|
+
apply_force(result)
|
81
|
+
|
82
|
+
# Train the brain according to the error
|
83
|
+
error = desired - location
|
84
|
+
brain.train(forces, error)
|
85
|
+
end
|
86
|
+
|
87
|
+
# A method that calculates a steering force towards a target
|
88
|
+
# STEER = DESIRED MINUS VELOCITY
|
89
|
+
def seek(target)
|
90
|
+
desired = target - location # A vector pointing from the location to the target
|
91
|
+
|
92
|
+
# Normalize desired and scale to the maximum speed
|
93
|
+
desired.normalize!
|
94
|
+
desired *= MAX_SPEED
|
95
|
+
# Steering = Desired minus velocity
|
96
|
+
steer = desired - @velocity
|
97
|
+
steer.set_mag(MAX_FORCE) {steer.mag_squared > maxforce_squared} # Limit to a maximum steering force
|
98
|
+
steer
|
99
|
+
end
|
100
|
+
|
101
|
+
def display
|
102
|
+
|
103
|
+
# Draw a triangle rotated in the direction of velocity
|
104
|
+
theta = @velocity.heading + Math::PI / 2
|
105
|
+
fill(175)
|
106
|
+
stroke(0)
|
107
|
+
stroke_weight(1)
|
108
|
+
push_matrix
|
109
|
+
translate(location.x, location.y)
|
110
|
+
rotate(theta)
|
111
|
+
begin_shape
|
112
|
+
vertex(0, -sz)
|
113
|
+
vertex(-sz * 0.5, sz)
|
114
|
+
vertex(sz * 0.5, sz)
|
115
|
+
end_shape(CLOSE)
|
116
|
+
pop_matrix
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
include SeekingNeural
|
122
|
+
|
123
|
+
# A Vehicle controlled by a Perceptron
|
124
|
+
attr_reader :targets, :desired, :v
|
125
|
+
|
126
|
+
|
127
|
+
def setup
|
128
|
+
size(640, 360)
|
129
|
+
# The Vehicle's desired location
|
130
|
+
@desired = Vec2D.new(width/2, height/2)
|
131
|
+
|
132
|
+
# Create a list of targets
|
133
|
+
make_targets
|
134
|
+
|
135
|
+
# Create the Vehicle (it has to know about the number of targets
|
136
|
+
# in order to configure its brain)
|
137
|
+
@v = Vehicle.new(targets.size, rand(width), rand(height))
|
138
|
+
end
|
139
|
+
|
140
|
+
# Make a random ArrayList of targets to steer towards
|
141
|
+
def make_targets
|
142
|
+
@targets = Array.new(8) { Vec2D.new(rand(width), rand(height)) }
|
143
|
+
end
|
144
|
+
|
145
|
+
def draw
|
146
|
+
background(255)
|
147
|
+
|
148
|
+
# Draw a circle to show the Vehicle's goal
|
149
|
+
stroke(0)
|
150
|
+
stroke_weight(2)
|
151
|
+
fill(0, 100)
|
152
|
+
ellipse(desired.x, desired.y, 36, 36)
|
153
|
+
|
154
|
+
# Draw the targets
|
155
|
+
targets.each do |target|
|
156
|
+
no_fill
|
157
|
+
stroke(0)
|
158
|
+
stroke_weight(2)
|
159
|
+
ellipse(target.x, target.y, 16, 16)
|
160
|
+
line(target.x, target.y - 16, target.x, target.y + 16)
|
161
|
+
line(target.x - 16, target.y, target.x + 16, target.y)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Update the Vehicle
|
165
|
+
v.steer(targets, desired)
|
166
|
+
v.update(width, height)
|
167
|
+
v.display
|
168
|
+
end
|
169
|
+
|
170
|
+
def mouse_pressed
|
171
|
+
make_targets
|
172
|
+
end
|
@@ -15,7 +15,7 @@ attr_reader :xpos, :ypos, :animation1, :animation2
|
|
15
15
|
def setup
|
16
16
|
size(640, 360)
|
17
17
|
background(255, 204, 0)
|
18
|
-
|
18
|
+
frame_rate(24)
|
19
19
|
@animation1 = Animation.new("PT_Shifty_", 38)
|
20
20
|
@animation2 = Animation.new("PT_Teddy_", 60)
|
21
21
|
@ypos = height * 0.25
|
@@ -35,24 +35,21 @@ def draw
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
class Animation
|
38
|
+
class Animation
|
39
39
|
attr_reader :images, :image_count, :frame
|
40
40
|
|
41
41
|
def initialize(image_prefix, count)
|
42
42
|
@image_count = count
|
43
43
|
@frame = 0
|
44
|
-
image_count.
|
45
|
-
# using ruby string format in preference to processing nf function
|
46
|
-
self << load_image("%s%04d%s" % [image_prefix, i, ".gif"])
|
47
|
-
end
|
44
|
+
@images = (0 ... image_count).map{|i| load_image("%s%04d%s" % [image_prefix, i, ".gif"])}
|
48
45
|
end
|
49
46
|
|
50
47
|
def display(xpos, ypos)
|
51
48
|
@frame = (frame + 1) % image_count
|
52
|
-
image(
|
49
|
+
image(images[frame], xpos, ypos)
|
53
50
|
end
|
54
51
|
|
55
52
|
def get_width
|
56
|
-
|
53
|
+
images[0].width
|
57
54
|
end
|
58
55
|
end
|
@@ -6,7 +6,6 @@
|
|
6
6
|
# Twelve images are loaded and each is displayed individually in a loop.
|
7
7
|
#
|
8
8
|
|
9
|
-
|
10
9
|
NUM_FRAMES = 12 # The number of frames in the animation
|
11
10
|
attr_reader :frame, :images
|
12
11
|
|
@@ -35,8 +34,8 @@ def draw
|
|
35
34
|
offset = 0
|
36
35
|
(-100 ... width).step(images[0].width) do |i|
|
37
36
|
image(images[(frame+offset) % NUM_FRAMES], i, -20)
|
38
|
-
offset+=2
|
37
|
+
offset += 2
|
39
38
|
image(images[(frame+offset) % NUM_FRAMES], i, height/2)
|
40
|
-
offset+=2
|
39
|
+
offset += 2
|
41
40
|
end
|
42
41
|
end
|
@@ -42,7 +42,7 @@ end
|
|
42
42
|
class Particle
|
43
43
|
include Processing::Proxy
|
44
44
|
|
45
|
-
GRAVITY =
|
45
|
+
GRAVITY = Vec2D.new(0, 0.1)
|
46
46
|
|
47
47
|
attr_reader :center, :velocity, :lifespan, :s_shape, :part_size,
|
48
48
|
:width, :height, :sprite
|
@@ -64,7 +64,7 @@ class Particle
|
|
64
64
|
s_shape.end_shape
|
65
65
|
|
66
66
|
# Initialize center vector
|
67
|
-
@center =
|
67
|
+
@center = Vec2D.new
|
68
68
|
|
69
69
|
# Set the particle starting location
|
70
70
|
rebirth(width/2, height/2)
|
@@ -74,8 +74,8 @@ class Particle
|
|
74
74
|
theta = rand(-PI .. PI)
|
75
75
|
speed = rand(0.5 .. 4)
|
76
76
|
# A velocity with random angle and magnitude
|
77
|
-
@velocity =
|
78
|
-
@velocity
|
77
|
+
@velocity = Vec2D.from_angle(theta)
|
78
|
+
@velocity *= speed
|
79
79
|
# Set lifespan
|
80
80
|
@lifespan = 255
|
81
81
|
# Set location using translate
|
@@ -83,7 +83,7 @@ class Particle
|
|
83
83
|
s_shape.translate(x, y)
|
84
84
|
|
85
85
|
# Update center vector
|
86
|
-
@center.
|
86
|
+
@center.x, @center.y = x, y
|
87
87
|
end
|
88
88
|
|
89
89
|
# Is it off the screen, or its lifespan is over?
|
@@ -96,12 +96,12 @@ class Particle
|
|
96
96
|
# Decrease life
|
97
97
|
@lifespan = lifespan - 1
|
98
98
|
# Apply gravity
|
99
|
-
velocity
|
99
|
+
@velocity += GRAVITY
|
100
100
|
s_shape.setTint(color(255, lifespan))
|
101
101
|
# Move the particle according to its velocity
|
102
102
|
s_shape.translate(velocity.x, velocity.y)
|
103
103
|
# and also update the center
|
104
|
-
center
|
104
|
+
@center += velocity
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# For guts of implementation see 'particle' library
|
5
5
|
#
|
6
6
|
|
7
|
-
|
7
|
+
load_libraries :vecmath, :particle
|
8
8
|
|
9
9
|
# Particle System object and image
|
10
10
|
attr_reader :ps
|
@@ -32,7 +32,7 @@ def draw
|
|
32
32
|
# Display frame rate
|
33
33
|
fill(255, 0, 255)
|
34
34
|
text_size(16)
|
35
|
-
text("Frame rate: #{frame_rate
|
35
|
+
text("Frame rate: #{format('%.2f', frame_rate)}", 10, 20)
|
36
36
|
|
37
37
|
end
|
38
38
|
|
@@ -7,8 +7,8 @@ class KochFractal
|
|
7
7
|
attr_reader :start, :endk, :lines, :count
|
8
8
|
|
9
9
|
def initialize width, height
|
10
|
-
@start =
|
11
|
-
@endk =
|
10
|
+
@start = Vec2D.new(0, height - 20)
|
11
|
+
@endk = Vec2D.new(width, height - 20)
|
12
12
|
restart
|
13
13
|
end
|
14
14
|
|
@@ -22,7 +22,7 @@ class KochFractal
|
|
22
22
|
def restart
|
23
23
|
@count = 0 # Reset count
|
24
24
|
@lines = [] # Empty the array list
|
25
|
-
lines << KochLine.new(start, endk) # Add the initial line (from one end
|
25
|
+
lines << KochLine.new(start, endk) # Add the initial line (from one end Vector to the other)
|
26
26
|
end
|
27
27
|
|
28
28
|
def get_count
|
@@ -47,13 +47,13 @@ class KochFractal
|
|
47
47
|
def iterate(before)
|
48
48
|
now = [] # Create empty list
|
49
49
|
before.each do |line|
|
50
|
-
# Calculate 5 koch
|
50
|
+
# Calculate 5 koch Vectors (done for us by the line object)
|
51
51
|
a = line.start
|
52
52
|
b = line.kochleft
|
53
53
|
c = line.kochmiddle
|
54
54
|
d = line.kochright
|
55
55
|
e = line.endk
|
56
|
-
# Make line segments between all the
|
56
|
+
# Make line segments between all the Vectors and add them
|
57
57
|
# Note how we can chain '<<' in ruby, could all be in one line.
|
58
58
|
now << KochLine.new(a,b) << KochLine.new(b,c)
|
59
59
|
now << KochLine.new(c,d) << KochLine.new(d,e)
|
@@ -68,18 +68,18 @@ end
|
|
68
68
|
|
69
69
|
# Koch Curve
|
70
70
|
# A class to describe one line segment in the fractal
|
71
|
-
# Includes methods to calculate mid
|
71
|
+
# Includes methods to calculate mid Vectors along the line according to the Koch algorithm
|
72
72
|
|
73
73
|
class KochLine
|
74
74
|
include Processing::Proxy
|
75
75
|
# Two PVectors,
|
76
|
-
# a is the "left"
|
77
|
-
# b is the "right
|
76
|
+
# a is the "left" Vector and
|
77
|
+
# b is the "right Vector
|
78
78
|
attr_reader :start, :endk
|
79
79
|
|
80
80
|
def initialize(start, endk)
|
81
|
-
@start = start.
|
82
|
-
@endk = endk.
|
81
|
+
@start = start.dup
|
82
|
+
@endk = endk.dup
|
83
83
|
end
|
84
84
|
|
85
85
|
def display
|
@@ -89,28 +89,29 @@ class KochLine
|
|
89
89
|
|
90
90
|
# This is easy, just 1/3 of the way
|
91
91
|
def kochleft
|
92
|
-
v =
|
93
|
-
v.
|
94
|
-
v
|
92
|
+
v = endk - start
|
93
|
+
v /= 3.0
|
94
|
+
v += start
|
95
95
|
return v
|
96
96
|
end
|
97
97
|
|
98
|
-
# More complicated, have to use a little trig to figure out where this
|
98
|
+
# More complicated, have to use a little trig to figure out where this Vector is!
|
99
99
|
def kochmiddle
|
100
|
-
v =
|
101
|
-
v.
|
102
|
-
p = start.
|
103
|
-
p
|
104
|
-
|
105
|
-
|
100
|
+
v = endk - start
|
101
|
+
v /= 3.0
|
102
|
+
p = start.dup
|
103
|
+
p += v
|
104
|
+
rot = radians(-60)
|
105
|
+
r = Vec2D.new((v.x * cos(rot)) - v.y * sin(rot), (v.x * sin(rot)) + (v.y * cos(rot)))
|
106
|
+
p += r
|
106
107
|
return p
|
107
108
|
end
|
108
109
|
|
109
110
|
# Easy, just 2/3 of the way
|
110
111
|
def kochright
|
111
|
-
v =
|
112
|
-
v.
|
113
|
-
v
|
112
|
+
v = start - endk
|
113
|
+
v /= 3.0
|
114
|
+
v += endk
|
114
115
|
return v
|
115
116
|
end
|
116
117
|
end
|