Skip to content

Commit

Permalink
more samples
Browse files Browse the repository at this point in the history
  • Loading branch information
monkstone committed Apr 1, 2015
1 parent 82cd535 commit 98c6e75
Show file tree
Hide file tree
Showing 9 changed files with 407 additions and 30 deletions.
35 changes: 5 additions & 30 deletions samples/external_library/ruby_gem/toxiclibs/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
### Using Toxiclibs jars in JRubyArt

Here we demonstrate how to use Karsten Schmidts (aka toxi, @postspectacular) toxiclibs jars in ruby-processing. Using the [toxiclibs gem][]...
NB: need to use the --nojruby flag when running gray_scott_image.rb (ie use jruby-complete see wiki for why?)

### Web Links

[Post Spectacular Home][]

[Toxiclibs Clone][]

[Toxiclibs Documentation][]

### Licensing

I should be clear that the original toxiclibs is the work of Karsten Schmidt:-

Copyright (c) 2010 Karsten Schmidt

This demo & library is free software you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation either
version 2.1 of the License, or (at your option) any later version.


[Post Spectacular Home]:http://postspectacular.com/
[Toxiclibs Clone]:https://github.com/ruby-processing/toxiclibs
[Toxiclibs Documentation]:http://toxiclibs.org/
[toxiclibs gem]:https://github.com/ruby-processing/toxicgem

### Toxiclibs
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.
```bash
gem install toxiclibs
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com
# Force directed graph
# Heavily based on: http://code.google.com/p/fidgen/
class Cluster
include Processing::Proxy
attr_reader :nodes, :diameter, :physics

# We initialize a Cluster with a number of nodes, a diameter, and centerpoint
def initialize(physics, n, d, center)
@diameter, @physics = d, physics
# Create the nodes
@nodes = (0..n).map { Node.new(center.add(TVec2D.randomVector)) }
# Connect all the nodes with a Spring
nodes[1..nodes.size - 1].each_with_index do |pi, i|
nodes[0..i].each do |pj|
physics.addSpring(Physics::VerletSpring2D.new(pi, pj, diameter, 0.01))
end
end
end

def display
# Show all the nodes
nodes.each(&:display)
end

# This functons connects one cluster to another
# Each point of one cluster connects to each point of the other cluster
# The connection is a "VerletMinDistanceSpring"
# A VerletMinDistanceSpring is a spring which only enforces its rest length if the
# current distance is less than its rest length. This is handy if you just want to
# ensure objects are at least a certain distance from each other, but don't
# care if it's bigger than the enforced minimum.
def connect(other)
other_nodes = other.nodes
nodes.each do |pi|
other_nodes.each do |pj|
physics.addSpring(Physics::VerletMinDistanceSpring2D.new(pi, pj, (diameter + other.diameter) * 0.5, 0.05))
end
end
end

# Draw all the internal connections
def internal_connections
stroke(200, 0, 0, 80)
nodes[0..nodes.size - 1].each_with_index do |pi, i|
nodes[i + 1..nodes.size - 1].each do |pj|
line(pi.x, pi.y, pj.x, pj.y)
end
end
end

# Draw all the connections between this Cluster and another Cluster
def show_connections(other)
stroke(200, 200, 0, 20)
stroke_weight(2)
other_nodes = other.nodes
nodes.each do |pi|
other_nodes[0..other_nodes.size - 1].each do |pj|
line(pi.x, pi.y, pj.x, pj.y)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#
# <p>Force directed graph,
# heavily based on: <a href="http:#code.google.com/p/fidgen/">fid.gen</a><br/>
# <a href="http:#www.shiffman.net/teaching/nature/toxiclibs/">The Nature of Code</a><br/>
# Spring 2010</p>
#
# Copyright (c) 2010 Daniel Shiffman
#
# This demo & library is free software you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation either
# version 2.1 of the License, or (at your option) any later version.
#
# http:#creativecommons.org/licenses/LGPL/2.1/
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
require 'toxiclibs'
require_relative 'cluster'
require_relative 'node'

attr_reader :physics, :clusters, :show_physics, :show_particles, :f

def setup
size(640, 360)
@f = create_font('Georgia', 12, true)
@show_physics = true
@show_particles = true
# Initialize the physics
@physics = Physics::VerletPhysics2D.new
physics.setWorldBounds(Toxi::Rect.new(10, 10, width - 20, height - 20))
# Spawn a new random graph
new_graph
end

# Spawn a new random graph
def new_graph
# Clear physics
physics.clear
center = TVec2D.new(width / 2, height / 2)
@clusters = (0..8).map { Cluster.new(physics, rand(3..8), rand(20..100), center) }
# All clusters connect to all clusters
clusters.each_with_index do |ci, i|
clusters[i + 1..clusters.size - 1].each do |cj|
ci.connect(cj)
end
end
end

def draw
# Update the physics world
physics.update
background(255)
# Display all points
clusters.each(&:display) if show_particles
# If we want to see the physics
if show_physics
clusters.each_with_index do |ci, i|
ci.internal_connections
# Cluster connections to other clusters
clusters[1 + i..clusters.size - 1].each do |cj|
ci.show_connections(cj)
end
end
end
# Instructions
fill(0)
text_font(f)
text("'p' to display or hide particles\n'c' to display or hide connections\n'n' for new graph", 10, 20)
end

# Key press commands
def key_pressed
case key
when 'c'
@show_physics = !show_physics
@show_particles = true unless show_physics
when 'p'
@show_particles = !show_particles
@show_physics = true unless show_particles
when 'n'
new_graph
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com
# Force directed graph
# Heavily based on: http:#code.google.com/p/fidgen/
# Notice how we are using inheritance here!
# We could have just stored a reference to a VerletParticle object
# inside the Node class, but inheritance is a nice alternative
class Node < Physics::VerletParticle2D
include Processing::Proxy

def initialize(pos)
super(pos)
end

# All we're doing really is adding a display function to a VerletParticle
def display
fill(50, 200, 200, 150)
stroke(50, 200, 200)
stroke_weight(2)
ellipse(x, y, 16, 16)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com
# Notice how we are using inheritance here!
# We could have just stored a reference to a VerletParticle2D object
# inside the Particle class, but inheritance is an alternative
class Particle < Physics::VerletParticle2D
include Processing::Proxy
def initialize(loc)
super(loc)
end

# All we're doing really is adding a display function to a VerletParticle
def display
fill(127)
stroke(0)
stroke_weight(2)
ellipse(x, y, 32, 32)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com

# Simple Toxiclibs Spring requires 'toxiclibs gem'

require 'toxiclibs'
require_relative 'particle'

attr_reader :physics, :p1, :p2

def setup
size(640, 360)
# Initialize the physics
@physics = Physics::VerletPhysics2D.new
physics.addBehavior(Physics::GravityBehavior2D.new(TVec2D.new(0, 0.5)))
# Set the world's bounding box
physics.setWorldBounds(Toxi::Rect.new(0, 0, width, height))
# Make two particles
@p1 = Particle.new(TVec2D.new(width / 2, 20))
@p2 = Particle.new(TVec2D.new(width / 2 + 160, 20))
# Lock one in place
p1.lock
# Make a spring connecting both Particles
spring = Physics::VerletSpring2D.new(p1, p2, 160, 0.01)
# Anything we make, we have to add into the physics world
physics.addParticle(p1)
physics.addParticle(p2)
physics.addSpring(spring)
end

def draw
# Update the physics world
physics.update
background(255)
# Draw a line between the particles
stroke(0)
stroke_weight(2)
line(p1.x, p1.y, p2.x, p2.y)
# Display the particles
p1.display
p2.display
# Move the second one according to the mouse
return unless mouse_pressed?
p2.lock
p2.set_x mouse_x
p2.set_y mouse_y
p2.unlock
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com

# A soft pendulum (series of connected springs)
class Chain
include Processing::Proxy
# Chain properties
attr_reader :total_length, :num_points, :strength, :radius, :particles, :tail
attr_reader :physics, :dragged, :offset

# Chain constructor
def initialize(p, l, n, r, s)
@particles = []
@physics, @total_length, @num_points, @radius, @strength = p, l, n, r, s
len = total_length / num_points
@offset = Vect.new(0, 0)
# Here is the real work, go through and add particles to the chain itself
num_points.times do |i|
# Make a new particle with an initial starting location
particle = Particle.new($app.width / 2, i * len)
# Redundancy, we put the particles both in physics and in our own Array
physics.addParticle(particle)
particles << particle
# Connect the particles with a Spring (except for the head)
next if (i == 0)
previous = particles[i - 1]
# Add the spring to the physics world
physics.addSpring(Physics::VerletSpring2D.new(particle, previous, len, strength))
end
# Keep the top fixed
particles[0].lock
# Store reference to the tail
@tail = particles[num_points - 1]
tail.radius = radius
end

# Check if a point is within the ball at the end of the chain
# If so, set dragged = true
def contains(x, y)
return if (x - tail.x) * (x - tail.x) + (y - tail.y) * (y - tail.y) < radius * radius
offset.x = tail.x - x
offset.y = tail.y - y
tail.lock
@dragged = true
end

# Release the ball
def release
tail.unlock
@dragged = false
end

# Update tail location if being dragged
def update_tail(x, y)
tail.set(x + offset.x, y + offset.y) if dragged
end

# Draw the chain
def display
# Draw line connecting all points
begin_shape
stroke(0)
stroke_weight(2)
no_fill
particles.each { |p| vertex(p.x, p.y) }
end_shape
tail.display
end
end

Vect = Struct.new(:x, :y)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com

# Notice how we are using inheritance here!
# We could have just stored a reference to a VerletPhysics2D object
# inside the Particle class, but inheritance is a nice alternative

class Particle < Physics::VerletParticle2D
include Processing::Proxy
attr_accessor :radius # Adding a radius for each particle

def initialize(x, y)
super(x, y)
@radius = 4
end

# All we're doing really is adding a display function to a VerletParticle2D
def display
fill(127)
stroke(0)
stroke_weight(2)
ellipse(x, y, radius * 2, radius * 2)
end
end
Loading

0 comments on commit 98c6e75

Please sign in to comment.