From 98c6e7529a8332c8b7018f6b5bef6c634586d683 Mon Sep 17 00:00:00 2001 From: monkstone Date: Wed, 1 Apr 2015 11:37:12 +0100 Subject: [PATCH] more samples --- .../ruby_gem/toxiclibs/README.md | 35 +------ .../physics/force_directed_graph/cluster.rb | 65 +++++++++++++ .../force_directed_graph.rb | 91 +++++++++++++++++++ .../physics/force_directed_graph/node.rb | 23 +++++ .../physics/simple_spring/particle.rb | 20 ++++ .../physics/simple_spring/simple_spring.rb | 49 ++++++++++ .../toxiclibs/physics/soft_string/chain.rb | 72 +++++++++++++++ .../toxiclibs/physics/soft_string/particle.rb | 25 +++++ .../soft_string/soft_string_pendulum.rb | 57 ++++++++++++ 9 files changed, 407 insertions(+), 30 deletions(-) create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/cluster.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/force_directed_graph.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/node.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/particle.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/simple_spring.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/soft_string/chain.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/soft_string/particle.rb create mode 100644 samples/external_library/ruby_gem/toxiclibs/physics/soft_string/soft_string_pendulum.rb diff --git a/samples/external_library/ruby_gem/toxiclibs/README.md b/samples/external_library/ruby_gem/toxiclibs/README.md index 2cd19c3..31f66df 100644 --- a/samples/external_library/ruby_gem/toxiclibs/README.md +++ b/samples/external_library/ruby_gem/toxiclibs/README.md @@ -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 +``` diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/cluster.rb b/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/cluster.rb new file mode 100644 index 0000000..c5ea52f --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/cluster.rb @@ -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 diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/force_directed_graph.rb b/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/force_directed_graph.rb new file mode 100644 index 0000000..5bdba1c --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/force_directed_graph.rb @@ -0,0 +1,91 @@ +# +#

Force directed graph, +# heavily based on: fid.gen
+# The Nature of Code
+# Spring 2010

+# +# 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 diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/node.rb b/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/node.rb new file mode 100644 index 0000000..0dcf8cf --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/force_directed_graph/node.rb @@ -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 diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/particle.rb b/samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/particle.rb new file mode 100644 index 0000000..722b58e --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/particle.rb @@ -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 diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/simple_spring.rb b/samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/simple_spring.rb new file mode 100644 index 0000000..85da359 --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/simple_spring/simple_spring.rb @@ -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 diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/chain.rb b/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/chain.rb new file mode 100644 index 0000000..2586467 --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/chain.rb @@ -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) diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/particle.rb b/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/particle.rb new file mode 100644 index 0000000..25920a7 --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/particle.rb @@ -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 diff --git a/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/soft_string_pendulum.rb b/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/soft_string_pendulum.rb new file mode 100644 index 0000000..7e743fe --- /dev/null +++ b/samples/external_library/ruby_gem/toxiclibs/physics/soft_string/soft_string_pendulum.rb @@ -0,0 +1,57 @@ +#

A soft pendulum (series of connected springs)
+# The Nature of Code
+# Spring 2010

+# 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 'particle' +require_relative 'chain' + +attr_reader :physics, :chain + +def setup + size(640, 360) + # Initialize the physics world + @physics = Physics::VerletPhysics2D.new + physics.addBehavior(Physics::GravityBehavior2D.new(TVec2D.new(0, 0.1))) + physics.setWorldBounds(Toxi::Rect.new(0, 0, width, height)) + + # Initialize the chain + @chain = Chain.new(physics, 180, 20, 16, 0.2) +end + +def draw + background(255) + # Update physics + physics.update + # Update chain's tail according to mouse location + chain.update_tail(mouse_x, mouse_y) + # Display chain + chain.display +end + +def mouse_pressed + # Check to see if we're grabbing the chain + chain.contains(mouse_x, mouse_y) +end + +def mouse_released + # Release the chain + chain.release +end