Skip to content

Commit bd8b95b

Browse files
committed
Add Henon Explorer
1 parent 0f43dda commit bd8b95b

File tree

13 files changed

+551
-2
lines changed

13 files changed

+551
-2
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
# Learning Processing
3+
# Daniel Shiffman
4+
# http://www.learningprocessing.com
5+
6+
# Example 22-2: Polymorphism
7+
8+
# Circle class inherits Processing:Proxy module methods from Shape
9+
# Inherits all instance variables from parent + adding one using the
10+
# post_initialize hook method. Use of change_color makes initialization of @c
11+
# irrelevant, but without example is spoiled.
12+
require_relative 'shape'
13+
14+
class Circle < Shape
15+
16+
attr_reader :c, :x, :y, :r
17+
18+
def post_initialize(args)
19+
# get color :c or default
20+
@c = args.fetch(:c, color(rand(255), 100))
21+
end
22+
23+
# Call the parent jiggle, but do some more stuff too
24+
def jiggle
25+
super
26+
# The Circle jiggles both size and location.
27+
@r += rand(-1..1.0)
28+
@r = r.clamp(0, 100)
29+
end
30+
31+
def display
32+
ellipse_mode(CENTER)
33+
fill(c)
34+
stroke(0)
35+
ellipse(x, y, r, r)
36+
end
37+
38+
def run
39+
jiggle
40+
display
41+
end
42+
end
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Learning Processing
2+
# Daniel Shiffman
3+
# http://www.learningprocessing.com
4+
5+
# Example 22-2: Polymorphism
6+
require_relative 'shape'
7+
# Circle class inherits Processing:Proxy module methods from Shape
8+
# Inherits all instance variables from parent + adding one using the
9+
# post_initialize hook method. Use of change_color makes initilization of @c
10+
# irrelevant, but without example is spoiled.
11+
class Circle2 < Shape
12+
13+
attr_reader :c, :x, :y, :r
14+
15+
def initialize(x:, y:, r:)
16+
super
17+
end
18+
19+
def post_initialize(args)
20+
@c = args[:c] # Also deal with this new instance variable
21+
end
22+
23+
# Call the parent jiggle, but do some more stuff too
24+
def jiggle
25+
super
26+
# The Circle jiggles both size and location.
27+
@r += rand(-1..1.0)
28+
@r = r.clamp(0, 100)
29+
end
30+
31+
# The change_color function is unique to the Circle class.
32+
# @HACK color(COLORS.sample) produces solid color we can add transparency
33+
# for these colors (all negative int)
34+
def change_color
35+
@c = color(COLORS.sample) + (100<<24)
36+
end
37+
38+
def display
39+
ellipse_mode(CENTER)
40+
fill(c)
41+
stroke(0)
42+
ellipse(x, y, r, r)
43+
end
44+
45+
def run
46+
jiggle
47+
change_color
48+
display
49+
end
50+
end
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Learning Processing
2+
# Daniel Shiffman
3+
# http://www.learningprocessing.com
4+
5+
# Example 22-2: Polymorphism
6+
# class Shape does not require Processing::Proxy but can pass it on to
7+
# the inheriting classes Square and Circle (NB: change to using run)
8+
class Shape
9+
include Processing::Proxy
10+
COLORS = %w(#ff0000 #ffff00 #3333ff #33cc33)
11+
attr_reader :x, :y, :r
12+
13+
def initialize(x:, y:, r:, **opts)
14+
@x = x
15+
@y = y
16+
@r = r
17+
post_initialize(opts)
18+
end
19+
20+
def jiggle
21+
@x += rand(-1..1.0)
22+
@y += rand(-1..1.0)
23+
end
24+
25+
def post_initialize(_args)
26+
'not implemented'
27+
end
28+
29+
# A generic shape does not really know how to be displayed.
30+
# This will be overridden in the child classes.
31+
def display
32+
'not implemented'
33+
end
34+
35+
def run
36+
'not implemented'
37+
end
38+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
require_relative 'shape'
2+
require_relative 'circle'
3+
require_relative 'circle2'
4+
require_relative 'square'
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Learning Processing
2+
# Daniel Shiffman
3+
# http://www.learningprocessing.com
4+
5+
# Example 22-2: Polymorphism
6+
require_relative 'shape'
7+
# Square class can inherit Processing::Proxy methods from Shape
8+
# Variables are inherited from the parent.
9+
# We could also add variables unique to the Square class if we so desire
10+
# NB: run could be the only visible method
11+
class Square < Shape
12+
# Inherits constructor from parent
13+
# Inherits jiggle from parent
14+
15+
# The square overrides its parent for display.
16+
def display
17+
rect_mode(CENTER)
18+
fill(175)
19+
stroke(0)
20+
rect(x, y, r, r)
21+
end
22+
23+
def run
24+
jiggle
25+
display
26+
end
27+
end

contributed/decagon_grid.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# frozen_string_literal: true
2+
3+
require 'picrate'
4+
# Example of a grid of decagons with perlin noise after Lenny Herzog
5+
class DecagonGrid < Processing::App
6+
load_library :pdf
7+
NOISE_STRENGTH = 80.0
8+
THETA = 36
9+
attr_reader :version, :save, :noise_generator
10+
11+
def setup
12+
sketch_title 'Decagon Grid'
13+
frame_rate 24
14+
@version = 0
15+
@save = false
16+
@noise_generator = lambda do |x, y, seed|
17+
NOISE_STRENGTH * noise(
18+
x / 150.0,
19+
y / 150.0 + seed * 2,
20+
seed
21+
) - 100
22+
end
23+
end
24+
25+
def draw
26+
begin_record(PDF, data_path("Line_#{version}.pdf")) if save
27+
background(255)
28+
no_fill
29+
stroke(0)
30+
stroke_weight(1)
31+
grid(height + 100, width + 100, 50, 50) do |cy, cx|
32+
begin_shape
33+
(0..360).step(THETA) do |angle|
34+
x = (DegLut.cos(angle) * 60) + cx
35+
y = (DegLut.sin(angle) * 60) + cy
36+
noise_value = noise_generator.call(x, y, millis / 5_000.0)
37+
x += noise_value
38+
y += noise_value
39+
vertex(x, y)
40+
end
41+
end_shape(CLOSE)
42+
end
43+
return unless save
44+
45+
end_record
46+
@version += 1
47+
@save = false
48+
end
49+
50+
def mouse_pressed
51+
@save = true
52+
end
53+
54+
def settings
55+
size(1000, 1000)
56+
end
57+
end
58+
59+
DecagonGrid.new
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# frozen_string_literal: true
2+
3+
require 'picrate'
4+
# Gravitational Attraction (3D)
5+
# by Daniel Shiffman.
6+
# Simulating gravitational attraction
7+
# G ---> universal gravitational constant
8+
# m1 --> mass of object #1
9+
# m2 --> mass of object #2
10+
# d ---> distance between objects
11+
# F = (G*m1*m2)/(d*d)
12+
# For the basics of working with Vec3D, see
13+
# https://ruby-processing.github.io/PiCrate/classes/vec3d/
14+
# as well as examples in library/vecmath/vec3d
15+
16+
class GravitationalAttraction3D < Processing::App
17+
attr_reader :planets, :sun, :angle
18+
19+
def setup
20+
sketch_title 'Gravitational Attraction (3D)'
21+
@planets = (0..10).map do
22+
Planet.new(
23+
rand(0.15..1.8),
24+
rand(-width / 2..width / 2),
25+
rand(-height / 2..height / 2),
26+
rand(-100..100)
27+
)
28+
end
29+
@sun = Sun.new
30+
@angle = 0
31+
end
32+
33+
def draw
34+
background(0, 0, 100)
35+
# Setup the scene
36+
sphere_detail(12)
37+
lights
38+
translate(width / 2, height / 2)
39+
rotate_y(angle)
40+
# Display the Sun
41+
sun.display(g)
42+
# All the Planets
43+
planets.each do |planet|
44+
# Sun attracts Planets
45+
force = sun.attract(planet)
46+
planet.apply_force(force)
47+
# Update and draw Planets
48+
planet.update
49+
planet.display(g)
50+
end
51+
# Rotate around the scene
52+
@angle += 0.005
53+
end
54+
55+
def settings
56+
size(640, 360, P3D)
57+
end
58+
end
59+
60+
GravitationalAttraction3D.new
61+
62+
# Gravitational Attraction (3D)
63+
# Daniel Shiffman <http://www.shiffman.net>
64+
# A class for an orbiting Planet
65+
class Planet
66+
67+
attr_reader :position, :velocity, :acceleration, :mass
68+
69+
def initialize(m, x, y, z)
70+
@mass = m
71+
@position = Vec3D.new(x, y, z)
72+
@velocity = Vec3D.new(1, 0, 0) # Arbitrary starting velocity
73+
@acceleration = Vec3D.new
74+
end
75+
76+
# Newton's 2nd Law (F = M*A) applied
77+
def apply_force(force)
78+
@acceleration += (force / mass)
79+
end
80+
81+
# Our motion algorithm (aka Euler Integration)
82+
def update
83+
@velocity += acceleration # Velocity changes with acceleration
84+
@position += velocity # position changes with velocity
85+
@acceleration *= 0
86+
end
87+
88+
# Draw the Planet
89+
def display(graphics)
90+
graphics.no_stroke
91+
graphics.fill(255)
92+
graphics.push_matrix
93+
graphics.translate(position.x, position.y, position.z)
94+
graphics.sphere(mass * 8)
95+
graphics.pop_matrix
96+
end
97+
end
98+
# Gravitational Attraction (3D)
99+
# Daniel Shiffman <http://www.shiffman.net>
100+
# A class for an attractive body in our world
101+
class Sun
102+
G = 0.4
103+
attr_reader :mass, :position
104+
105+
def initialize
106+
@position = Vec3D.new
107+
@mass = 20
108+
end
109+
110+
def attract(other)
111+
(position - other.position).tap do |force| # Calculate direction of force
112+
# d = force.mag # Distance between objects
113+
# Limit the distance to avoid very close or very far objects
114+
distance = force.mag.clamp(7.0, 25.0) # clamp available since ruby 2.4
115+
# Calculate gravitional force magnitude
116+
strength = (G * mass * other.mass) / (distance * distance)
117+
force.set_mag(strength) # force vector --> magnitude * direction
118+
end
119+
end
120+
121+
# Draw Sun
122+
def display(graphics)
123+
graphics.no_stroke
124+
graphics.fill(200, 200, 0)
125+
graphics.push_matrix
126+
graphics.translate(position.x, position.y, position.z)
127+
graphics.sphere(mass * 2)
128+
graphics.pop_matrix
129+
end
130+
end

data/henon_2.0000.jpg.tif

733 KB
Binary file not shown.

demo/feather_fractal.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env jruby
2+
3+
require 'picrate'
4+
5+
class FeatherFractal < Processing::App
6+
A = -0.48
7+
B = 0.93
8+
9+
def settings
10+
size(640, 480)
11+
end
12+
13+
def setup
14+
background(235, 215, 182)
15+
color_mode(HSB, 360, 1.0, 1.0)
16+
stroke(0)
17+
sketch_title 'Fantastic Feather Fractal'
18+
no_loop
19+
end
20+
21+
def draw
22+
x = 4.0
23+
y = 0.0
24+
120_000.times do |i|
25+
x1 = B * y + func(x)
26+
y = -x + func(x1)
27+
x = x1
28+
fill(i % 360, 1.0, 1.0)
29+
p = 350 + x * 26
30+
q = 280 - y * 26
31+
circle(p, q, 5)
32+
end
33+
end
34+
35+
def func(x)
36+
A * x - (1.0 - A) * ((2 * (x**2)) / (1.0 + x**2))
37+
end
38+
end
39+
40+
FeatherFractal.new

0 commit comments

Comments
 (0)