Getting Visual with Ruby Processing

Preview:

DESCRIPTION

Tutorial on the use of Ruby Processing for developing visual graphics and interactive graphics. Includes conceptual and real-world examples, including use for business data mining.

Citation preview

Getting Visual with Ruby-Processing

Richard LeBeratlrug 2010.11.10

aka

Ooh – pretty pictures!

Capabilities• Grayscale, RGB and HSB color with transparency• Point, line, shapes, curve, Bezier, text• Rotate, translate, scale, matrix transformations• 3D camera, viewport, lighting, texture• Choice of renderers, including OpenGL• Images, image manipulation, pixel-oriented graphics• Video: frame capture, control, creation• Audio: capture, processing, synthesis, output• Real-time interaction: mouse, keyboard, serial, network• Create .svg, .jpg, .tif, .tga, .png, .pdf, .mov, .dxf (CAD)• Cross-platform : *nix, OSX, Windows• Create standalone applications and web applets• Many extension libraries

Let’s get started!

hello_world.rb

def setup size 200, 200 # Set window size fill 0 # Set fill (and text) color to black text_font create_font("SanSerif",30) # Set text fontend def draw text "Hello World!", 10, 105 # Render text at (10,105)end

Installation is easy

> # Check that Java is installed:> jvm -versionjava version "1.6.0_22”…> sudo gem install ruby-processingSuccessfully installed ruby-processing-1.0.9…> rp5 unpack samples> cd samples> rp5 run getting_started.rb

getting_started.rbdef setup size 200, 200 background 0 no_stroke smooth @rotation = 0end

def draw fill 0, 20 rect 0, 0, width, height translate width/2, height/2 rotate @rotation

fill 255 ellipse 0, -60, 20, 20

@rotation += 0.1end

require 'ruby-processing'class Sketch < Processing::App

def setup # Do this once end def draw # Do this over and over... endendSketch.new

Here be magic…

Ruby-Processing adds these, if

they’re missing

getting_started.rbdef setup size 200, 200 background 0 no_stroke smooth @rotation = 0end

def draw fill 0, 20 rect 0, 0, width, height translate width/2, height/2 rotate @rotation

fill 255 ellipse 0, -60, 20, 20

@rotation += 0.1end

A word about coordinates *

* or, why you can’t get there from here

(width-1, 0)(0, 0)

(0, height-1) (width-1, height-1)

Lost in translation

Translated

translate x, y(0, 0)

Rotation

Rotated

rotate x_radians

You spin me right ‘round, baby, right ‘round…

(0, 0)

Examples

def draw background 255 stroke 0 fill 175 translate 25,10 rotate radians(60) image @jarjar, 10,10,50,50end

def draw background 255 stroke 0 fill 175 translate 25,10

image @jarjar, 10,10,50,50end

def draw background 255 stroke 0 fill 175

image @jarjar, 10,10,50,50end

getting_started.rb (again)def setup size 200, 200 # Set canvas size: width, height background 0 # Set background black no_stroke # Disable drawing outlines smooth # Draw smooth (anti-aliased) edges @rotation = 0 # Set initial rotation to 0 radiansend

getting_started.rbdef draw fill 0, 20 # Set fill color to black, # 20% opaque rect 0, 0, width, height # Draw rectangle over entire # window, fading it 20% translate width/2, height/2 # Move drawing origin to # center of window rotate @rotation # Rotate around new origin fill 255 # Set fill color to white ellipse 0, -60, 20, 20 # Draw circle, center at # (0,-60), size 20x20 @rotation += 0.1 # Increase angle of rotationend # and repeat …

Instance variables are our friends

Class Sketch < Processing::App

def setup# Stuff...

@rotation = 0 end def draw # More stuff... @rotation += 0.1 end end

Using an instance variable (@rotation) allows the angle of rotation to persist and increment across redrawings

Putting it all together

Gotta build!

Playing with sketches# bounce.rbBLUE = "#0000FF"GREEN = "#00FF00"RED = "#FF0000"

BALL_COLOR = BLUEBALL_SPEED = 5BALL_SIZE = 32

attr_accessor :ball_speed, :ball_color, :ball_size

def setup # …end

def draw # …end

> rp5 run bounce.rb…> rp5 watch bounce.rb…> rp5 live bounce.rb…> rp5 app bounce.rb…> rp5 applet bounce.rb…> rp5 help…

# follow_mouse.rb def setup color_mode HSB, 1.0 # HSB color, values 0.0..1.0 no_stroke # No outlines ellipse_mode CENTER # Position relative to center end

def draw background 0.0, 0.0, 1.0 # White fill mouse_x.to_f / width, mouse_y.to_f / height, 1.0 ellipse mouse_x, mouse_y, 50, 50 # Draw at mouse positionend

Color and interaction

3D# texture.rbclass Texture < Processing::App def setup size 640, 360, P3D @img = load_image ”yoda.jpg" no_stroke end def draw background 0 translate width/2, height/2 rotate_y map(mouse_x, 0, width, -PI, PI) begin_shape texture @img vertex -100, -100, 0, 0, 0 vertex 100, -40, 0, @img.width, @img.height/3 vertex 0, 100, 0, @img.width/2, @img.height end_shape endendTexture.new :title => "Texture"

data/yoda.jpg

Image processing

data/trex.jpg

# flashlight.rbdef setup size 267, 200 @image = load_image ’trex.jpg' @image_pixels = @image.pixels.

map {|p| [red(p), green(p), blue(p)]}end

def draw load_pixels width.times do |x| height.times do |y| loc = x + y * width distance = dist(x, y, mouseX, mouseY) adjustment = (75 - distance) / 75 pixels[loc] = color(*@image_pixels[loc].

map {|rgb| rgb * adjustment }) end end update_pixelsend

Video# manipulate_video.rbrequire 'ruby-processing’class ManipulateVideoImageSketch < Processing::App load_library "video" import "processing.video"

def setup @video = Capture.new(self, width, height, 30) end

def draw @video.read if @video.available tint mouse_x, mouse_y, 255 image @video, 0, 0, mouse_x, mouse_y endend

ManipulateVideoImageSketch.new \ :title => "Manipulate Video Image", :width => 640, :height => 480

How does this

thing work?

In the beginning…

Java

Processing

Ruby-Processing

Method translation

Ruby Javaellipse ellipse

color_mode colorMode()key_pressed? keyPressed()

Methods? We got methods *Control Shapes Images Transform Math Textscreen point create_image translate lerp textheight line load_image rotate lerp_color text_font

width triangle image scale map text_size

color_mode rect load_pixels shear_x norm text_align

background quad pixels[ ] shear_y constrain text_widthfill ellipse get apply_matrix mag text_ascent

stroke arc set push_matrix degrees text_descent

no_stroke curve update_pixels pop_matrix radians load_font

frame_count bezier copy Mouse Keyboard create_font

frame_rate begin_shape filter mouse_x key

save end_shape blend mouse_y key_code

save_frame box pmouse_x

sphere pmouse_y

* My favorites, in no particular order. See http://processing.org/reference/

Call-backs

mouse_moved key_pressedmouse_pressed key_releasedmouse_released key_typedmouse_clickedmouse_dragged

Some libraries

Anar CAD, parametric modeling, … http://anar.chLiveConnect Interface applets to Javascript http://mzl.la/liveconnMinim Sound processing http://bit.ly/minim_SVG Export Save drawings as .svg files * http://bit.ly/svgexTraer Physics (gravity, etc.) * http://bit.ly/traerWiring Device control, robotics * http://wiring.org.co/

* These are Java libraries. I haven’t tested them with ruby

Choosing is hard

Java or Ruby?

Java RubySyntax

Types, classes Java types, POJO, JavaBeans, etc.

Ruby classes

Metaprogramming Limited ExtensiveLibraries Many Some

Speed Faster SlowerWeb applets Integrated Weak

Ruby-Processing: East of Java *

* aka, Why we love Ruby!

// Java// From example 18-3 of Learning Processing by Daniel ShiffmanString[] data = loadStrings("data.txt");bubbles = new Bubble[data.length]; for (int i = 0; i < bubbles.length; i++) { float[] values = float(split(data[i], ",")); bubbles[i] = new Bubble(values[0], values[1], values[2]); }

# rubybubbles = load_strings("data.txt").map do |line| Bubble.new(*line.split(",").map{|num| num.to_f }) end

Ruby + Processing = metaprogramming

Processing::Menu.new (:font=>font, :minimizes=>true) do |m| m.add "Pick year", :pick_year m.add "Pick item", :pick_item m.add "Quit", :quit m.text_size = 14end

Processing::Graph::DateAxis.new( :title=>"Date", :orientation=>:horizontal, :grid=>true, :interval=>:month)

ds.on_highlight do |o| highlight_data(o)end

Equivalent Java:

Speed Benchmark 1

• Java vs. Ruby• 0 and 100 iterations• Average of 5 tests

Each frame

0 iterations

1

1

33.0

5.4

RubyJava

Speed Benchmark 2

• Java vs. Ruby• 0 and 1,000 iterations• Average of 5 tests

Each frame

0 iterations

1

1

1.34

6.83

RubyJava

Do real people use this?

Yes!

• Art and interactive graphics

• Interactive data mining

• Graphing

• Mapping

• Custom graphics

Product quality graph

Product Mix Chart

County meeting map

2008 Presidential Election

election_2008.rb

Logistics map

Finishingup

Geek alert!• Library and gem usage is tricky

• Both Processing and Ruby-Processing are still evolving

• There are bugs. I had to check out the Github master branch to resolve a bug in one of these sketches

• There are some compatibility issues, e.g. with Snow Leopard’s 64-bit JVM, and with $RUBYOPT

• You may need to monkey with the JVM’s runtime parameters

Check these out, too

Processing The original Processing framework in Java

http://processing.org/

Processing.js Javascript port of Processing

http://processingjs.org/

Field An alternative for graphics and visual art, based on Python

http://openendedgroup.com/field/wiki

NodeBox Free Mac application for 2D visuals, based on Python

http://bit.ly/nodebox

Learn more *• http://processing.org/

• https://github.com/jashkenas/ruby-processing/

• Getting Started with Processing, by Casey Reas and Ben Fry

• Learning Processing, by Daniel Shiffmanhttp://www.learningprocessing.com/ https://github.com/jashkenas/learning-processing-with-ruby

• Processing: A Programming Handbook for Visual Artists and Designers, by Casey Reas and Ben Fry

• Visualizing Data, by Ben Fry

* Thanks to all of the above for many of the examples

Slideshare RichardLeBer1: Getting Visual with Ruby Processing

Github (code examples)

https://github.com/rleber/getting_visual_with_ruby_processing

Email Richard.LeBer@gmail.com

Twitter @RichardLeBer

Photo credits Flickr: Matias.Dutto, zen, Travelin’ Librarian, Scott Kinmartin, Kaptain Kobold, bucklava, Jon_Marshall, ChrisGoldNYC, clouserw

Recommended