Skip to content

Commit 98c6e75

Browse files
author
monkstone
committed
more samples
1 parent 82cd535 commit 98c6e75

File tree

9 files changed

+407
-30
lines changed

9 files changed

+407
-30
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,5 @@
1-
### Using Toxiclibs jars in JRubyArt
2-
3-
Here we demonstrate how to use Karsten Schmidts (aka toxi, @postspectacular) toxiclibs jars in ruby-processing. Using the [toxiclibs gem][]...
4-
NB: need to use the --nojruby flag when running gray_scott_image.rb (ie use jruby-complete see wiki for why?)
5-
6-
### Web Links
7-
8-
[Post Spectacular Home][]
9-
10-
[Toxiclibs Clone][]
11-
12-
[Toxiclibs Documentation][]
13-
14-
### Licensing
15-
16-
I should be clear that the original toxiclibs is the work of Karsten Schmidt:-
17-
18-
Copyright (c) 2010 Karsten Schmidt
19-
20-
This demo & library is free software you can redistribute it and/or
21-
modify it under the terms of the GNU Lesser General Public
22-
License as published by the Free Software Foundation either
23-
version 2.1 of the License, or (at your option) any later version.
24-
25-
26-
[Post Spectacular Home]:http://postspectacular.com/
27-
[Toxiclibs Clone]:https://github.com/ruby-processing/toxiclibs
28-
[Toxiclibs Documentation]:http://toxiclibs.org/
29-
[toxiclibs gem]:https://github.com/ruby-processing/toxicgem
30-
1+
### Toxiclibs
2+
These examples require installation of the 'toxiclibs' gem. Whilst they work they are mainly a translation exercise and could do with a bit re-factoring for ruby-processing.
3+
```bash
4+
gem install toxiclibs
5+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# The Nature of Code
2+
# Daniel Shiffman
3+
# http://natureofcode.com
4+
# Force directed graph
5+
# Heavily based on: http://code.google.com/p/fidgen/
6+
class Cluster
7+
include Processing::Proxy
8+
attr_reader :nodes, :diameter, :physics
9+
10+
# We initialize a Cluster with a number of nodes, a diameter, and centerpoint
11+
def initialize(physics, n, d, center)
12+
@diameter, @physics = d, physics
13+
# Create the nodes
14+
@nodes = (0..n).map { Node.new(center.add(TVec2D.randomVector)) }
15+
# Connect all the nodes with a Spring
16+
nodes[1..nodes.size - 1].each_with_index do |pi, i|
17+
nodes[0..i].each do |pj|
18+
physics.addSpring(Physics::VerletSpring2D.new(pi, pj, diameter, 0.01))
19+
end
20+
end
21+
end
22+
23+
def display
24+
# Show all the nodes
25+
nodes.each(&:display)
26+
end
27+
28+
# This functons connects one cluster to another
29+
# Each point of one cluster connects to each point of the other cluster
30+
# The connection is a "VerletMinDistanceSpring"
31+
# A VerletMinDistanceSpring is a spring which only enforces its rest length if the
32+
# current distance is less than its rest length. This is handy if you just want to
33+
# ensure objects are at least a certain distance from each other, but don't
34+
# care if it's bigger than the enforced minimum.
35+
def connect(other)
36+
other_nodes = other.nodes
37+
nodes.each do |pi|
38+
other_nodes.each do |pj|
39+
physics.addSpring(Physics::VerletMinDistanceSpring2D.new(pi, pj, (diameter + other.diameter) * 0.5, 0.05))
40+
end
41+
end
42+
end
43+
44+
# Draw all the internal connections
45+
def internal_connections
46+
stroke(200, 0, 0, 80)
47+
nodes[0..nodes.size - 1].each_with_index do |pi, i|
48+
nodes[i + 1..nodes.size - 1].each do |pj|
49+
line(pi.x, pi.y, pj.x, pj.y)
50+
end
51+
end
52+
end
53+
54+
# Draw all the connections between this Cluster and another Cluster
55+
def show_connections(other)
56+
stroke(200, 200, 0, 20)
57+
stroke_weight(2)
58+
other_nodes = other.nodes
59+
nodes.each do |pi|
60+
other_nodes[0..other_nodes.size - 1].each do |pj|
61+
line(pi.x, pi.y, pj.x, pj.y)
62+
end
63+
end
64+
end
65+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#
2+
# <p>Force directed graph,
3+
# heavily based on: <a href="http:#code.google.com/p/fidgen/">fid.gen</a><br/>
4+
# <a href="http:#www.shiffman.net/teaching/nature/toxiclibs/">The Nature of Code</a><br/>
5+
# Spring 2010</p>
6+
#
7+
# Copyright (c) 2010 Daniel Shiffman
8+
#
9+
# This demo & library is free software you can redistribute it and/or
10+
# modify it under the terms of the GNU Lesser General Public
11+
# License as published by the Free Software Foundation either
12+
# version 2.1 of the License, or (at your option) any later version.
13+
#
14+
# http:#creativecommons.org/licenses/LGPL/2.1/
15+
#
16+
# This library is distributed in the hope that it will be useful,
17+
# but WITHOUT ANY WARRANTY without even the implied warranty of
18+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19+
# Lesser General Public License for more details.
20+
#
21+
# You should have received a copy of the GNU Lesser General Public
22+
# License along with this library if not, write to the Free Software
23+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24+
#
25+
require 'toxiclibs'
26+
require_relative 'cluster'
27+
require_relative 'node'
28+
29+
attr_reader :physics, :clusters, :show_physics, :show_particles, :f
30+
31+
def setup
32+
size(640, 360)
33+
@f = create_font('Georgia', 12, true)
34+
@show_physics = true
35+
@show_particles = true
36+
# Initialize the physics
37+
@physics = Physics::VerletPhysics2D.new
38+
physics.setWorldBounds(Toxi::Rect.new(10, 10, width - 20, height - 20))
39+
# Spawn a new random graph
40+
new_graph
41+
end
42+
43+
# Spawn a new random graph
44+
def new_graph
45+
# Clear physics
46+
physics.clear
47+
center = TVec2D.new(width / 2, height / 2)
48+
@clusters = (0..8).map { Cluster.new(physics, rand(3..8), rand(20..100), center) }
49+
# All clusters connect to all clusters
50+
clusters.each_with_index do |ci, i|
51+
clusters[i + 1..clusters.size - 1].each do |cj|
52+
ci.connect(cj)
53+
end
54+
end
55+
end
56+
57+
def draw
58+
# Update the physics world
59+
physics.update
60+
background(255)
61+
# Display all points
62+
clusters.each(&:display) if show_particles
63+
# If we want to see the physics
64+
if show_physics
65+
clusters.each_with_index do |ci, i|
66+
ci.internal_connections
67+
# Cluster connections to other clusters
68+
clusters[1 + i..clusters.size - 1].each do |cj|
69+
ci.show_connections(cj)
70+
end
71+
end
72+
end
73+
# Instructions
74+
fill(0)
75+
text_font(f)
76+
text("'p' to display or hide particles\n'c' to display or hide connections\n'n' for new graph", 10, 20)
77+
end
78+
79+
# Key press commands
80+
def key_pressed
81+
case key
82+
when 'c'
83+
@show_physics = !show_physics
84+
@show_particles = true unless show_physics
85+
when 'p'
86+
@show_particles = !show_particles
87+
@show_physics = true unless show_particles
88+
when 'n'
89+
new_graph
90+
end
91+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# The Nature of Code
2+
# Daniel Shiffman
3+
# http://natureofcode.com
4+
# Force directed graph
5+
# Heavily based on: http:#code.google.com/p/fidgen/
6+
# Notice how we are using inheritance here!
7+
# We could have just stored a reference to a VerletParticle object
8+
# inside the Node class, but inheritance is a nice alternative
9+
class Node < Physics::VerletParticle2D
10+
include Processing::Proxy
11+
12+
def initialize(pos)
13+
super(pos)
14+
end
15+
16+
# All we're doing really is adding a display function to a VerletParticle
17+
def display
18+
fill(50, 200, 200, 150)
19+
stroke(50, 200, 200)
20+
stroke_weight(2)
21+
ellipse(x, y, 16, 16)
22+
end
23+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# The Nature of Code
2+
# Daniel Shiffman
3+
# http://natureofcode.com
4+
# Notice how we are using inheritance here!
5+
# We could have just stored a reference to a VerletParticle2D object
6+
# inside the Particle class, but inheritance is an alternative
7+
class Particle < Physics::VerletParticle2D
8+
include Processing::Proxy
9+
def initialize(loc)
10+
super(loc)
11+
end
12+
13+
# All we're doing really is adding a display function to a VerletParticle
14+
def display
15+
fill(127)
16+
stroke(0)
17+
stroke_weight(2)
18+
ellipse(x, y, 32, 32)
19+
end
20+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# The Nature of Code
2+
# Daniel Shiffman
3+
# http://natureofcode.com
4+
5+
# Simple Toxiclibs Spring requires 'toxiclibs gem'
6+
7+
require 'toxiclibs'
8+
require_relative 'particle'
9+
10+
attr_reader :physics, :p1, :p2
11+
12+
def setup
13+
size(640, 360)
14+
# Initialize the physics
15+
@physics = Physics::VerletPhysics2D.new
16+
physics.addBehavior(Physics::GravityBehavior2D.new(TVec2D.new(0, 0.5)))
17+
# Set the world's bounding box
18+
physics.setWorldBounds(Toxi::Rect.new(0, 0, width, height))
19+
# Make two particles
20+
@p1 = Particle.new(TVec2D.new(width / 2, 20))
21+
@p2 = Particle.new(TVec2D.new(width / 2 + 160, 20))
22+
# Lock one in place
23+
p1.lock
24+
# Make a spring connecting both Particles
25+
spring = Physics::VerletSpring2D.new(p1, p2, 160, 0.01)
26+
# Anything we make, we have to add into the physics world
27+
physics.addParticle(p1)
28+
physics.addParticle(p2)
29+
physics.addSpring(spring)
30+
end
31+
32+
def draw
33+
# Update the physics world
34+
physics.update
35+
background(255)
36+
# Draw a line between the particles
37+
stroke(0)
38+
stroke_weight(2)
39+
line(p1.x, p1.y, p2.x, p2.y)
40+
# Display the particles
41+
p1.display
42+
p2.display
43+
# Move the second one according to the mouse
44+
return unless mouse_pressed?
45+
p2.lock
46+
p2.set_x mouse_x
47+
p2.set_y mouse_y
48+
p2.unlock
49+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# The Nature of Code
2+
# Daniel Shiffman
3+
# http://natureofcode.com
4+
5+
# A soft pendulum (series of connected springs)
6+
class Chain
7+
include Processing::Proxy
8+
# Chain properties
9+
attr_reader :total_length, :num_points, :strength, :radius, :particles, :tail
10+
attr_reader :physics, :dragged, :offset
11+
12+
# Chain constructor
13+
def initialize(p, l, n, r, s)
14+
@particles = []
15+
@physics, @total_length, @num_points, @radius, @strength = p, l, n, r, s
16+
len = total_length / num_points
17+
@offset = Vect.new(0, 0)
18+
# Here is the real work, go through and add particles to the chain itself
19+
num_points.times do |i|
20+
# Make a new particle with an initial starting location
21+
particle = Particle.new($app.width / 2, i * len)
22+
# Redundancy, we put the particles both in physics and in our own Array
23+
physics.addParticle(particle)
24+
particles << particle
25+
# Connect the particles with a Spring (except for the head)
26+
next if (i == 0)
27+
previous = particles[i - 1]
28+
# Add the spring to the physics world
29+
physics.addSpring(Physics::VerletSpring2D.new(particle, previous, len, strength))
30+
end
31+
# Keep the top fixed
32+
particles[0].lock
33+
# Store reference to the tail
34+
@tail = particles[num_points - 1]
35+
tail.radius = radius
36+
end
37+
38+
# Check if a point is within the ball at the end of the chain
39+
# If so, set dragged = true
40+
def contains(x, y)
41+
return if (x - tail.x) * (x - tail.x) + (y - tail.y) * (y - tail.y) < radius * radius
42+
offset.x = tail.x - x
43+
offset.y = tail.y - y
44+
tail.lock
45+
@dragged = true
46+
end
47+
48+
# Release the ball
49+
def release
50+
tail.unlock
51+
@dragged = false
52+
end
53+
54+
# Update tail location if being dragged
55+
def update_tail(x, y)
56+
tail.set(x + offset.x, y + offset.y) if dragged
57+
end
58+
59+
# Draw the chain
60+
def display
61+
# Draw line connecting all points
62+
begin_shape
63+
stroke(0)
64+
stroke_weight(2)
65+
no_fill
66+
particles.each { |p| vertex(p.x, p.y) }
67+
end_shape
68+
tail.display
69+
end
70+
end
71+
72+
Vect = Struct.new(:x, :y)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# The Nature of Code
2+
# Daniel Shiffman
3+
# http://natureofcode.com
4+
5+
# Notice how we are using inheritance here!
6+
# We could have just stored a reference to a VerletPhysics2D object
7+
# inside the Particle class, but inheritance is a nice alternative
8+
9+
class Particle < Physics::VerletParticle2D
10+
include Processing::Proxy
11+
attr_accessor :radius # Adding a radius for each particle
12+
13+
def initialize(x, y)
14+
super(x, y)
15+
@radius = 4
16+
end
17+
18+
# All we're doing really is adding a display function to a VerletParticle2D
19+
def display
20+
fill(127)
21+
stroke(0)
22+
stroke_weight(2)
23+
ellipse(x, y, radius * 2, radius * 2)
24+
end
25+
end

0 commit comments

Comments
 (0)