<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8424170917240137669</id><updated>2012-01-22T22:10:09.202Z</updated><category term='Staffordshire Knot'/><category term='path'/><category term='MPeano fractal'/><category term='live'/><category term='Sierpinski triangle'/><category term='watch'/><category term='fractal art'/><category term='pixel array'/><category term='flower'/><category term='pushing and popping'/><category term='koch curve'/><category term='Sierpinski variant'/><category term='Islands fractal'/><category term='tessellation'/><category term='rewind context'/><category term='testing the code'/><category term='fern fractal'/><category term='java threads'/><category term='povray'/><category term='fractal'/><category term='ruby processing'/><category term='portrait application'/><category term='DSL'/><category term='Spirograph type fractal'/><category term='ruby-processing'/><category term='probability'/><category term='PGraphicsPDF'/><category term='live edting'/><category term='3D stuff'/><category term='rod hilbert'/><category term='sunflow raytracing'/><category term='square fractal'/><category term='stabby-syntax'/><category term='l-systems'/><category term='isoceles triangle'/><category term='Gray-Scott diffusion'/><category term='generative'/><category term='painting pixels'/><category term='CAD'/><category term='java'/><category term='alhambra'/><category term='terminals'/><category term='cesaro'/><category term='sunflowAPIAPI'/><category term='Lindenmayer system'/><category term='transformation'/><category term='logarithmic spiral'/><category term='Levy curve'/><category term='fileInput'/><category term='developing shapes'/><category term='snake kolam'/><category term='ruby splat'/><category term='algorithm'/><category term='lambda'/><category term='mouse_wheel_listener'/><category term='gui'/><category term='java_args.txt'/><category term='dynamic random'/><category term='context-sensitive'/><category term='moire fringes'/><category term='voronoi'/><category term='parallax'/><category term='GLGraphics'/><category term='PCR gel'/><category term='GLSL shader'/><category term='color'/><category term='rotating cube'/><category term='toxiclibs'/><category term='screen saver'/><category term='fish-eye'/><category term='java2d'/><category term='menger sponge'/><category term='simple tree'/><category term='weighted rules'/><category term='recursion'/><category term='nautilus'/><category term='ruby'/><category term='inner class'/><category term='penrose snowflake'/><category term='loop'/><category term='interactive mode'/><category term='torn square fractal'/><category term='sunflow'/><category term='Hilbert fractal'/><category term='red dwarf'/><category term='re-factor'/><category term='HSB'/><category term='ruby1.9'/><category term='context free'/><category term='irb'/><category term='3D context free DSL'/><category term='jashkenas'/><category term='fish eye lens'/><category term='vertex'/><category term='inflate mesh'/><category term='custom shape'/><category term='zoom'/><category term='Peano curve'/><category term='heighway dragon'/><category term='prototyping'/><category term='opengl'/><category term='terminal shapes'/><category term='animation'/><category term='l-system'/><category term='raytracing'/><category term='cfdg'/><category term='tail recursion'/><category term='ternary operator'/><category term='LUT'/><category term='perlin noise'/><category term='physics'/><category term='infinity'/><category term='preston lee'/><category term='travelling salesman'/><category term='mouse wheel listener'/><category term='line strip'/><category term='pentagonal fractal'/><category term='multidimensional array'/><category term='l-system fractal'/><category term='escher'/><category term='stochastic l-system rules'/><category term='voronoi mesh'/><category term='starfield'/><category term='seaweed'/><category term='PeasyCam library'/><category term='random'/><category term='control panel'/><category term='custom terminal'/><category term='povwriter'/><category term='affine transforms'/><category term='find_method'/><category term='jvm'/><category term='jedit'/><category term='libraries'/><category term='anar+ library'/><category term='fake menger sponge'/><category term='modelX'/><category term='LSystems'/><category term='tune ups'/><category term='3D'/><category term='context free DSL'/><category term='bit-shifting color'/><category term='pop art'/><category term='penrose tiling'/><category term='caliper'/><category term='camel-case'/><category term='tunnel'/><category term='screenX'/><category term='jruby'/><category term='context sensitive'/><category term='plant structure'/><category term='pseudo 3D'/><category term='StructureSynth'/><category term='hemesh'/><category term='Minkowski island'/><category term='3D Hilbert'/><category term='evolving l-system fractal'/><title type='text'>Ruby Processing</title><subtitle type='html'>Here is my blog in which I will describe my experiments with ruby-processing, find out more about ruby-processing at:- 
&lt;a href="http://wiki.github.com/jashkenas/ruby-processing"&gt;http://wiki.github.com/jashkenas/ruby-processing&lt;/a&gt; and &lt;a href="http://github.com/jashkenas/context_free"&gt;http://github.com/jashkenas/context_free&lt;/a&gt; for the cfdg DSL (&lt;i&gt;context-free-art&lt;/i&gt;)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default?start-index=101&amp;max-results=100'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>135</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-5822566304882085520</id><published>2011-12-01T19:34:00.008Z</published><updated>2011-12-05T07:39:55.461Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby-processing'/><category scheme='http://www.blogger.com/atom/ns#' term='GLSL shader'/><category scheme='http://www.blogger.com/atom/ns#' term='fish-eye'/><category scheme='http://www.blogger.com/atom/ns#' term='GLGraphics'/><title type='text'>GLGraphics in ruby-processing post processing (GLSL Fish Eye shader)</title><content type='html'>&lt;style type="text/css"&gt;&lt;!--pre { font-family: monospace; color: #ffffff; background-color: #000000; }body { font-family: monospace; color: #ffffff; background-color: #000000; }.Type { color: #00ff00; font-weight: bold; }.Identifier { color: #00ffff; font-weight: bold; }.PreProc { color: #8080ff; font-weight: bold; }.Statement { color: #ffff00; font-weight: bold; }.Constant { color: #ff40ff; font-weight: bold; }.Special { color: #ff6060; font-weight: bold; }.Comment { color: #00ffff; font-weight: bold; }--&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="Comment"&gt;# This example applies a post-processing texture filter to the offscreen canvas&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# in order to generate an angular fish-eye effect.&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# Based on the following discussion thread in the Processing forum:&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# http:#forum.processing.org/topic/angular-fisheye&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# Some other resources about fish-eye projections:&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# 1) Excellent article from Paul Bourke on the math behind the angular fish-eye mapping  &lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# http:#paulbourke.net/miscellaneous/domefisheye/fisheye/&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# 2) Fish-eye effect implemented as a GLSL vertex shader:&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# http:#pixelsorcery.wordpress.com/2010/07/13/fisheye-vertex-shader/&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# 3) Another fish-eye GLSL shader (didn't test it though):&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# http:#pages.cpsc.ucalgary.ca/~brosz/wiki/pmwiki.php/CSharp/08022008&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;opengl&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;GLGraphics&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;include_package &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;codeanticode.glgraphics&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Statement"&gt;attr_reader&lt;/span&gt; &lt;span class="Constant"&gt;:canvas&lt;/span&gt;, &lt;span class="Constant"&gt;:fisheye&lt;/span&gt;, &lt;span class="Constant"&gt;:tex&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;setup&lt;/span&gt;()&lt;br /&gt;  size(&lt;span class="Constant"&gt;300&lt;/span&gt;, &lt;span class="Constant"&gt;300&lt;/span&gt;, &lt;span class="Type"&gt;GLConstants&lt;/span&gt;.GLGRAPHICS)&lt;br /&gt;  &lt;span class="Comment"&gt;# If your video card isn't up to it use following (no antialias)&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;#@canvas = GLGraphicsOffScreen.new(self, width, height)    &lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@canvas&lt;/span&gt; = &lt;span class="Type"&gt;GLGraphicsOffScreen&lt;/span&gt;.new(&lt;span class="Constant"&gt;self&lt;/span&gt;, width, height, &lt;span class="Constant"&gt;true&lt;/span&gt;, &lt;span class="Constant"&gt;4&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# Destination texture to store the fisheye image.&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@tex&lt;/span&gt; = &lt;span class="Type"&gt;GLTexture&lt;/span&gt;.new(&lt;span class="Constant"&gt;self&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@fisheye&lt;/span&gt; = &lt;span class="Type"&gt;GLTextureFilter&lt;/span&gt;.new(&lt;span class="Constant"&gt;self&lt;/span&gt;, &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;FishEye.xml&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;  &lt;span class="Comment"&gt;# The aperture angle is specified in degrees. Values&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# greater than 180 can be specified, but the result won't&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# be consistent since the mapping is not one-to-one in&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# that case.&lt;/span&gt;&lt;br /&gt;  fisheye.set_parameter_value(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;aperture&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;, &lt;span class="Constant"&gt;180.0&lt;/span&gt;)&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw&lt;/span&gt;()&lt;br /&gt;  &lt;span class="Comment"&gt;# Generating offscreen rendering:&lt;/span&gt;&lt;br /&gt;  canvas.begin_draw&lt;br /&gt;  canvas.background(&lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;  canvas.lights&lt;br /&gt;  canvas.stroke(&lt;span class="Constant"&gt;255&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;  (&lt;span class="Constant"&gt;0&lt;/span&gt;...height).step(&lt;span class="Constant"&gt;10&lt;/span&gt;) {|&lt;span class="Identifier"&gt;i&lt;/span&gt;| canvas.line(i, &lt;span class="Constant"&gt;0&lt;/span&gt;, i, height)}&lt;br /&gt;  (&lt;span class="Constant"&gt;0&lt;/span&gt;...width).step(&lt;span class="Constant"&gt;10&lt;/span&gt;) {|&lt;span class="Identifier"&gt;j&lt;/span&gt;| canvas.line(&lt;span class="Constant"&gt;0&lt;/span&gt;, j, width, j)}&lt;br /&gt;  canvas.no_stroke&lt;br /&gt;  canvas.translate(mouse_x, mouse_y, &lt;span class="Constant"&gt;100&lt;/span&gt;)&lt;br /&gt;  canvas.rotate_x(frame_count * &lt;span class="Constant"&gt;0.01&lt;/span&gt;)&lt;br /&gt;  canvas.rotate_y(frame_count * &lt;span class="Constant"&gt;0.01&lt;/span&gt;)&lt;br /&gt;  canvas.box(&lt;span class="Constant"&gt;50&lt;/span&gt;)&lt;br /&gt;  canvas.end_draw&lt;br /&gt;  fisheye.apply(canvas.get_texture(), tex)&lt;br /&gt;  image(tex, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, width, height)&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is is an example included with vanilla processing GLGraphics library be sure to copy the shader files from the GLGraphics/Examples/Output/FishEye/data into a data folder (where fish_eye.rb is saved). See also faux fish eye &lt;a href="http://learning-ruby-processing.blogspot.com/2011/06/faux-fish-eye-lens-in-ruby-processing.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-k3LSc0OQybQ/TtfWjl0uwaI/AAAAAAAADeo/Me63UfYHmj0/s1600/fish_eye.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="328" src="http://2.bp.blogspot.com/-k3LSc0OQybQ/TtfWjl0uwaI/AAAAAAAADeo/Me63UfYHmj0/s400/fish_eye.png" width="308" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-5822566304882085520?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/5822566304882085520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/12/glgraphics-in-ruby-processing-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5822566304882085520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5822566304882085520'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/12/glgraphics-in-ruby-processing-post.html' title='GLGraphics in ruby-processing post processing (GLSL Fish Eye shader)'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-k3LSc0OQybQ/TtfWjl0uwaI/AAAAAAAADeo/Me63UfYHmj0/s72-c/fish_eye.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-2610338389975730480</id><published>2011-11-26T14:45:00.011Z</published><updated>2011-12-22T10:55:00.742Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='povray'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='prototyping'/><title type='text'>Further Prototyping of my Povwriter Library in ruby-processing</title><content type='html'>&lt;span style="background-color: yellow; color: #cc0000;"&gt;Update 22 December&lt;/span&gt; I have gone on to modify my java &lt;a href="https://github.com/monkstone/povrender/wiki"&gt;povwriter library&lt;/a&gt;, incorporating some of ideas developed here. This sketch is incompatible with that new library, however old library is still available &lt;a href="http://java.net/projects/povwriter/downloads"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It really is much easier to prototype in ruby/ruby processing vs java/vanilla processing. Recently I had the idea of splitting up the povray files as follows:-&lt;br /&gt;&lt;ol&gt;&lt;li&gt;pov.ini to hold size (resolution) and quality (ray-trace parameter&lt;/li&gt;&lt;li&gt;pov.pov to hold template (camera/background etc)&lt;/li&gt;&lt;li&gt;pov.inc to hold mesh data etc from the processing sketch&lt;/li&gt;&lt;/ol&gt;In this iteration of prototyping I get to do 1 and 2, as 3 will involve a rewrite of my povwriter library, which I'm putting off until is clear whether beginRaw/endRaw will work in processing 2.0 (scheduled for release in Spring 2012?). I have decided less is definetly more for my gui, there are now only 3 quality options and the raytrace button now also initiates the recording of the PovRAY files as well as starting PovRAY. Further I've split the ini writer/povray runner into a new class as follows:-&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;!--pre { font-family: monospace; color: #ffffff; background-color: #000000; }body { font-family: monospace; color: #ffffff; background-color: #000000; }.Type { color: #00ff00; font-weight: bold; }.Statement { color: #ffff00; font-weight: bold; }.Identifier { color: #00ffff; font-weight: bold; }.PreProc { color: #8080ff; font-weight: bold; }.Constant { color: #ff40ff; font-weight: bold; }.Special { color: #ff6060; font-weight: bold; }.Comment { color: #00ffff; font-weight: bold; }--&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="Comment"&gt;# Demonstrates how you can use my povwriter libary&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# in Ruby-Processing, to export to PovRAY&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;povwriter&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;control_panel&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;import &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;povexport&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;require&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;ini_writer&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;DATA&lt;/span&gt; = [&lt;span class="Constant"&gt;-1&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;1&lt;/span&gt;]&lt;br /&gt;&lt;span class="Statement"&gt;attr_reader&lt;/span&gt; &lt;span class="Constant"&gt;:exporter&lt;/span&gt;, &lt;span class="Constant"&gt;:precord&lt;/span&gt;, &lt;span class="Constant"&gt;:pquality&lt;/span&gt;, &lt;span class="Constant"&gt;:type&lt;/span&gt;, &lt;span class="Constant"&gt;:pview&lt;/span&gt;, &lt;span class="Constant"&gt;:povfile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;setup&lt;/span&gt;&lt;br /&gt;  size &lt;span class="Constant"&gt;1000&lt;/span&gt;, &lt;span class="Constant"&gt;1000&lt;/span&gt;, &lt;span class="Type"&gt;P3D&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@povfile&lt;/span&gt; = &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;balls.pov&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@precord&lt;/span&gt; = &lt;span class="Constant"&gt;false&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@pview&lt;/span&gt; = &lt;span class="Constant"&gt;false&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@exporter&lt;/span&gt; = &lt;span class="Type"&gt;PovExporter&lt;/span&gt;.new &lt;span class="Constant"&gt;self&lt;/span&gt;&lt;br /&gt;  control_panel &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;c&lt;/span&gt;|&lt;br /&gt;    c.title = &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Render as PovRAY&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;    c.menu(&lt;span class="Constant"&gt;:quality&lt;/span&gt;, [&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;instant&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;medium&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;], &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;instant&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;) {|&lt;span class="Identifier"&gt;m&lt;/span&gt;| load_quality_choice(m) }&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:choose_template&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:raytrace&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:exit!&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# uncomment next enter the path to povray executable on mac/windows/linux (or possibly jedit linux)  &lt;/span&gt;&lt;br /&gt;  exporter.set_povray_path(&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;/usr/local/bin/povray&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;) &lt;span class="Comment"&gt;# choice is saved in '.povwriter/povwriter.properties'&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# uncomment following line to adjust degenerate triangle cut off (area squared)&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# export.set_epsilon("0.001")&lt;/span&gt;&lt;br /&gt;  exporter.store_settings    &lt;span class="Comment"&gt;# uncomment this line to save settings   &lt;/span&gt;&lt;br /&gt;  no_stroke&lt;br /&gt;  sphere_detail(&lt;span class="Constant"&gt;18&lt;/span&gt;)&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw&lt;/span&gt;&lt;br /&gt;  lights          &lt;span class="Comment"&gt;# this needs to be outside the record loop&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (precord)&lt;br /&gt;    no_lights     &lt;span class="Comment"&gt;# let PovRAY do the lighting&lt;/span&gt;&lt;br /&gt;    no_loop       &lt;span class="Comment"&gt;# don't loop while recording sketch&lt;/span&gt;&lt;br /&gt;    begin_raw(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;povexport.RawPovray&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;, data_path(povfile))&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; pview&lt;br /&gt;    pov_image = load_image(data_path(povfile.gsub(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;pov&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;, &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;png&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)))&lt;br /&gt;    update_pixels&lt;br /&gt;    background(&lt;span class="Constant"&gt;255&lt;/span&gt;) &lt;span class="Comment"&gt;# clear the screen   &lt;/span&gt;&lt;br /&gt;    image(pov_image, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;  &lt;span class="Statement"&gt;else&lt;/span&gt;&lt;br /&gt;    render&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (precord)&lt;br /&gt;    end_raw&lt;br /&gt;    &lt;span class="Identifier"&gt;@precord&lt;/span&gt; = &lt;span class="Constant"&gt;false&lt;/span&gt;&lt;br /&gt;    puts &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;done recording&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;    trace = &lt;span class="Type"&gt;IniWriter&lt;/span&gt;.new(data_path(povfile), width, height, pquality)&lt;br /&gt;    trace.raytrace exporter.get_povray_path&lt;br /&gt;    &lt;span class="Identifier"&gt;@pview&lt;/span&gt; = &lt;span class="Constant"&gt;true&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;exit!&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;exit&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;render&lt;/span&gt;()&lt;br /&gt;  background(&lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;  translate(width*&lt;span class="Constant"&gt;0.7&lt;/span&gt;, height/&lt;span class="Constant"&gt;2&lt;/span&gt;, -width)&lt;br /&gt;  &lt;span class="Identifier"&gt;DATA&lt;/span&gt;.each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;y&lt;/span&gt;|&lt;br /&gt;    &lt;span class="Identifier"&gt;DATA&lt;/span&gt;.each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;x&lt;/span&gt;|&lt;br /&gt;      &lt;span class="Identifier"&gt;DATA&lt;/span&gt;.each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;z&lt;/span&gt;|&lt;br /&gt;        push_matrix&lt;br /&gt;        translate(&lt;span class="Constant"&gt;120&lt;/span&gt;*x, &lt;span class="Constant"&gt;120&lt;/span&gt;*y, &lt;span class="Constant"&gt;120&lt;/span&gt;*z)&lt;br /&gt;        fill(rand * &lt;span class="Constant"&gt;255&lt;/span&gt;, rand * &lt;span class="Constant"&gt;255&lt;/span&gt;, rand * &lt;span class="Constant"&gt;255&lt;/span&gt;) &lt;span class="Comment"&gt;# a nice test for my colorFactory class&lt;/span&gt;&lt;br /&gt;        exporter.sphere(&lt;span class="Constant"&gt;60&lt;/span&gt;) &lt;span class="Comment"&gt;# use a better sphere primitive for ray tracing&lt;/span&gt;&lt;br /&gt;        pop_matrix&lt;br /&gt;      &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Comment"&gt;################################### Independent of sketch ############################&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;raytrace&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@precord&lt;/span&gt; = &lt;span class="Constant"&gt;true&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;choose_template&lt;/span&gt;&lt;br /&gt;  exporter.choose_template&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;load_quality_choice&lt;/span&gt;(item)&lt;br /&gt;  &lt;span class="Identifier"&gt;@pquality&lt;/span&gt; = item&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is the ini writer class..................&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="PreProc"&gt;require&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;pathname&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Type"&gt;INI&lt;/span&gt; = {&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;instant&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;quick.ini&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;medium&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;medium.ini&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;quality.ini&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;}&lt;br /&gt;&lt;span class="Type"&gt;QUALITY&lt;/span&gt; = {&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;instant&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;4&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;medium&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;6&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;11&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;class&lt;/span&gt; &lt;span class="Type"&gt;IniWriter&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;attr_reader&lt;/span&gt; &lt;span class="Constant"&gt;:name&lt;/span&gt;, &lt;span class="Constant"&gt;:width&lt;/span&gt;, &lt;span class="Constant"&gt;:height&lt;/span&gt;, &lt;span class="Constant"&gt;:qual&lt;/span&gt;, &lt;span class="Constant"&gt;:base&lt;/span&gt;, &lt;span class="Constant"&gt;:ini&lt;/span&gt;&lt;br /&gt; &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;initialize&lt;/span&gt; name, width, height, qual&lt;br /&gt;   &lt;span class="Identifier"&gt;@name&lt;/span&gt;, &lt;span class="Identifier"&gt;@width&lt;/span&gt;, &lt;span class="Identifier"&gt;@height&lt;/span&gt;, &lt;span class="Identifier"&gt;@qual&lt;/span&gt; = name, width, height, qual&lt;br /&gt;   init&lt;br /&gt; &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;init&lt;/span&gt;&lt;br /&gt;   &lt;span class="Identifier"&gt;@base&lt;/span&gt; = &lt;span class="Type"&gt;File&lt;/span&gt;.dirname(name)&lt;br /&gt;   &lt;span class="Statement"&gt;if&lt;/span&gt; (&lt;span class="Type"&gt;QUALITY&lt;/span&gt;[qual] &amp;lt; &lt;span class="Constant"&gt;6&lt;/span&gt; &amp;amp;&amp;amp; width &amp;gt; &lt;span class="Constant"&gt;300&lt;/span&gt;)&lt;br /&gt;     &lt;span class="Identifier"&gt;@height&lt;/span&gt; *= &lt;span class="Constant"&gt;300.0&lt;/span&gt;/width&lt;br /&gt;     &lt;span class="Identifier"&gt;@width&lt;/span&gt; = &lt;span class="Constant"&gt;300&lt;/span&gt;&lt;br /&gt;   &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;write&lt;/span&gt;&lt;br /&gt;   &lt;span class="Identifier"&gt;@ini&lt;/span&gt; = &lt;span class="Type"&gt;File&lt;/span&gt;.join(base, &lt;span class="Type"&gt;INI&lt;/span&gt;[qual])&lt;br /&gt;   file = open(ini, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;w&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;; &lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;ini&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Input_File_Name='&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;name&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt;'&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;width=&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;width&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;height=&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;height&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;quality=&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;&lt;span class="Type"&gt;QUALITY&lt;/span&gt;[qual]&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Antialias=true&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;) &lt;span class="Statement"&gt;unless&lt;/span&gt; &lt;span class="Type"&gt;QUALITY&lt;/span&gt;[qual] &amp;lt; &lt;span class="Constant"&gt;10&lt;/span&gt;&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Output_File_Type=N8&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.puts(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Output_File_Name='&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;name.gsub(&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;pov&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;png&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;)&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt;'&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;   file.close&lt;br /&gt; &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;raytrace&lt;/span&gt; povray_path&lt;br /&gt;   write&lt;br /&gt;   system([povray_path, ini].join(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt; &lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;))&lt;br /&gt; &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-2610338389975730480?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/2610338389975730480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/11/further-prototyping-of-my-povwriter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/2610338389975730480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/2610338389975730480'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/11/further-prototyping-of-my-povwriter.html' title='Further Prototyping of my Povwriter Library in ruby-processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-6419154931435430753</id><published>2011-11-16T14:41:00.028Z</published><updated>2011-11-18T13:43:47.457Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='povray'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='control panel'/><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><category scheme='http://www.blogger.com/atom/ns#' term='povwriter'/><title type='text'>Exporting Sketches from Ruby-Processing to PovRAY, features control panel</title><content type='html'>It has taken a lot longer that it should have done, but finally I got round to exploring my vanilla  processing &lt;a href="http://java.net/projects/povwriter/pages/Home"&gt;povwriter&lt;/a&gt; library in ruby processing. Thanks to the latest version of ruby-processing, we can use the vanilla processing library from the sketchbook folder. This works fine and dandy at present, but I can foresee potential conflicts with libraries that have been modified to run with processing-2.0, but then lots of libraries are probably going to get screwed along the way to the new version (&lt;i&gt;my povwriter library for one does not work with processing-2.0&lt;/i&gt;). Here's one of my povwriter example files translated to ruby:-&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;!--pre { font-family: monospace; color: #ffffff; background-color: #000000; }body { font-family: monospace; color: #ffffff; background-color: #000000; }.Type { color: #00ff00; font-weight: bold; }.PreProc { color: #8080ff; font-weight: bold; }.Statement { color: #ffff00; font-weight: bold; }.Identifier { color: #00ffff; font-weight: bold; }.Constant { color: #ff40ff; font-weight: bold; }.Special { color: #ff6060; font-weight: bold; }.Comment { color: #00ffff; font-weight: bold; }--&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="Comment"&gt;# Demonstrates how you can use my povwriter libary&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# in Ruby-Processing, to export to PovRAY&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;povwriter&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;control_panel&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;import &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;povexport&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Identifier"&gt;DATA&lt;/span&gt; = [&lt;span class="Constant"&gt;-1&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;1&lt;/span&gt;]&lt;br /&gt;&lt;span class="Statement"&gt;attr_reader&lt;/span&gt; &lt;span class="Constant"&gt;:exporter&lt;/span&gt;, &lt;span class="Constant"&gt;:precord&lt;/span&gt;, &lt;span class="Constant"&gt;:pquality&lt;/span&gt;, &lt;span class="Constant"&gt;:type&lt;/span&gt;, &lt;span class="Constant"&gt;:pview&lt;/span&gt;, &lt;span class="Constant"&gt;:memory&lt;/span&gt;, &lt;span class="Constant"&gt;:povfile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;setup&lt;/span&gt;&lt;br /&gt;  size &lt;span class="Constant"&gt;300&lt;/span&gt;, &lt;span class="Constant"&gt;300&lt;/span&gt;, &lt;span class="Type"&gt;P3D&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@povfile&lt;/span&gt; = &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;balls.pov&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@precord&lt;/span&gt; = &lt;span class="Constant"&gt;false&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@exporter&lt;/span&gt; = &lt;span class="Type"&gt;PovExporter&lt;/span&gt;.new &lt;span class="Constant"&gt;self&lt;/span&gt;&lt;br /&gt;  control_panel &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;c&lt;/span&gt;|&lt;br /&gt;    c.title = &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Render as PovRAY&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;    c.menu(&lt;span class="Constant"&gt;:quality&lt;/span&gt;, [&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;low&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;medium&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;highest&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;], &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;) {|&lt;span class="Identifier"&gt;m&lt;/span&gt;| load_quality_choice(m) }&lt;br /&gt;    c.menu(&lt;span class="Constant"&gt;:image_type&lt;/span&gt;, [&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;png&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;jpeg&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;tga&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;], &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;png&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;) {|&lt;span class="Identifier"&gt;m&lt;/span&gt;| load_image_type(m) }&lt;br /&gt;    c.menu(&lt;span class="Constant"&gt;:memory&lt;/span&gt;, [&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;low&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;default&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;none&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;], &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;default&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;) {|&lt;span class="Identifier"&gt;m&lt;/span&gt;| load_memory_choice(m) }&lt;br /&gt;    c.checkbox &lt;span class="Constant"&gt;:antialias&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:choose_template&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:record&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:raytrace&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:view&lt;/span&gt;&lt;br /&gt;    c.button &lt;span class="Constant"&gt;:exit!&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# uncomment next enter the path to povray executable on mac/windows/linux (or possibly jedit linux)  &lt;/span&gt;&lt;br /&gt;  exporter.set_povray_path(&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;/usr/local/bin/povray&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;) &lt;span class="Comment"&gt;# choice is saved in '.povwriter/povwriter.properties'&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# uncomment following line to adjust degenerate triangle cut off (area squared)&lt;/span&gt;&lt;br /&gt;  &lt;span class="Comment"&gt;# export.set_epsilon("0.001")&lt;/span&gt;&lt;br /&gt;  exporter.store_settings    &lt;span class="Comment"&gt;# uncomment this line to save settings   &lt;/span&gt;&lt;br /&gt;  no_stroke&lt;br /&gt;  sphere_detail(&lt;span class="Constant"&gt;18&lt;/span&gt;)&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw&lt;/span&gt;&lt;br /&gt;  lights          &lt;span class="Comment"&gt;# this needs to be outside the record loop&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (precord)&lt;br /&gt;    no_lights   &lt;span class="Comment"&gt;# let PovRAY do the lighting&lt;/span&gt;&lt;br /&gt;    no_loop       &lt;span class="Comment"&gt;# don't loop while recording sketch&lt;/span&gt;&lt;br /&gt;    begin_raw(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;povexport.RawPovray&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;, data_path(povfile))&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; pview&lt;br /&gt;    background(&lt;span class="Constant"&gt;0&lt;/span&gt;) &lt;span class="Comment"&gt;# clear the screen&lt;/span&gt;&lt;br /&gt;    image(load_image(data_path(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;balls.png&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)), &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;    no_loop&lt;br /&gt;  &lt;span class="Statement"&gt;else&lt;/span&gt;&lt;br /&gt;    render&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (precord)&lt;br /&gt;    end_raw&lt;br /&gt;    &lt;span class="Identifier"&gt;@precord&lt;/span&gt; = &lt;span class="Constant"&gt;false&lt;/span&gt;&lt;br /&gt;    puts &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;done recording&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;loop&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;exit!&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;exit&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;render&lt;/span&gt;()&lt;br /&gt;  background(&lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;  translate(width*&lt;span class="Constant"&gt;0.7&lt;/span&gt;, height/&lt;span class="Constant"&gt;2&lt;/span&gt;, -width)&lt;br /&gt;  &lt;span class="Identifier"&gt;DATA&lt;/span&gt;.each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;y&lt;/span&gt;|&lt;br /&gt;    &lt;span class="Identifier"&gt;DATA&lt;/span&gt;.each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;x&lt;/span&gt;|&lt;br /&gt;      &lt;span class="Identifier"&gt;DATA&lt;/span&gt;.each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;z&lt;/span&gt;|&lt;br /&gt;        push_matrix&lt;br /&gt;        translate(&lt;span class="Constant"&gt;120&lt;/span&gt;*x, &lt;span class="Constant"&gt;120&lt;/span&gt;*y, &lt;span class="Constant"&gt;120&lt;/span&gt;*z)&lt;br /&gt;        fill(rand * &lt;span class="Constant"&gt;255&lt;/span&gt;, rand * &lt;span class="Constant"&gt;255&lt;/span&gt;, rand * &lt;span class="Constant"&gt;255&lt;/span&gt;) &lt;span class="Comment"&gt;# a nice test for my colorFactory class&lt;/span&gt;&lt;br /&gt;        exporter.sphere(&lt;span class="Constant"&gt;60&lt;/span&gt;) &lt;span class="Comment"&gt;# use a better sphere primitive for ray tracing&lt;/span&gt;&lt;br /&gt;        pop_matrix&lt;br /&gt;      &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Comment"&gt;################################### Independent of sketch ############################&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;record&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@precord&lt;/span&gt; = &lt;span class="Constant"&gt;true&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;raytrace&lt;/span&gt;&lt;br /&gt;  &lt;span class="Type"&gt;Kernel&lt;/span&gt;.system([exporter.get_povray_path, povray_options, povray_scene].join(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt; &lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;))&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;choose_template&lt;/span&gt;&lt;br /&gt;  exporter.choose_template&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;view&lt;/span&gt;&lt;br /&gt;  &lt;span class="Identifier"&gt;@pview&lt;/span&gt; = &lt;span class="Constant"&gt;true&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;povray_scene&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;+I&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;data_path(povfile)&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;povray_options&lt;/span&gt;&lt;br /&gt;  aa = &lt;span class="Identifier"&gt;@antialias&lt;/span&gt; ? &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;+A&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt; : &lt;span class="Special"&gt;""&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;+IM&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;memory&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt; +W&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;width&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt; +H&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;height&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt; +Q&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;pquality&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt; &lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;aa&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Constant"&gt; +F&lt;/span&gt;&lt;span class="Special"&gt;#{&lt;/span&gt;type&lt;span class="Special"&gt;}&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;load_quality_choice&lt;/span&gt;(item)&lt;br /&gt;  map = {&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;low&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;medium&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;5&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;9&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;highest&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;11&lt;/span&gt;}&lt;br /&gt;  &lt;span class="Identifier"&gt;@pquality&lt;/span&gt; = map[item]&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;load_memory_choice&lt;/span&gt;(item)&lt;br /&gt;  map = {&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;low&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;56&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;default&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;128&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;high&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;1024&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;none&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;0&lt;/span&gt;}&lt;br /&gt;  &lt;span class="Identifier"&gt;@memory&lt;/span&gt; = map[item]&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;load_image_type&lt;/span&gt;(item)&lt;br /&gt;  map = {&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;png&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;N&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;jpeg&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;J&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;tga&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;C&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;}&lt;br /&gt;  &lt;span class="Identifier"&gt;@type&lt;/span&gt; = map[item]&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sketch now modified to use the excellent control panel of ruby-processing. Here I am using a custom sphere for raytracing, ideally I would just call the PovRAY sphere primitive, but that is a bit more complicated than it appears at first sight (see my vanilla processing blog). Presently everything is exported as a simple triangle mesh (ideally this would be a PovRAY mesh2 object). Make life easy for yourself and wrap drawing logic in a function such as render. Click on images below to see full size....&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-BGWbFDaQHkc/TsV2i_poQlI/AAAAAAAADeA/7aA2GQFvVz4/s1600/two.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-BGWbFDaQHkc/TsV2i_poQlI/AAAAAAAADeA/7aA2GQFvVz4/s320/two.png" width="247" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Live Display of PovRAY rendering&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-GXj30uQcKPw/TsV2nloI0WI/AAAAAAAADeI/9JAWfkVInrU/s1600/three.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-GXj30uQcKPw/TsV2nloI0WI/AAAAAAAADeI/9JAWfkVInrU/s320/three.png" width="300" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Viewing Rendered image in processing sketch&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-6419154931435430753?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/6419154931435430753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/11/export-sketches-from-ruby-processing-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6419154931435430753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6419154931435430753'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/11/export-sketches-from-ruby-processing-to.html' title='Exporting Sketches from Ruby-Processing to PovRAY, features control panel'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-BGWbFDaQHkc/TsV2i_poQlI/AAAAAAAADeA/7aA2GQFvVz4/s72-c/two.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-4975496528242897443</id><published>2011-07-12T19:28:00.005+01:00</published><updated>2011-11-17T21:51:45.474Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rod hilbert'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='LUT'/><title type='text'>Rod Hilbert in Ruby-Processing (using homebaked libraries)</title><content type='html'>Here is sketch where I have created two small libraries, one in java that I have archived as jar, and one in ruby that is library just because I put in the library folder. The java library provides fast lookup tables for sin and cos, and the ruby library provides some code that is re-used a lot when I create lystems in ruby-processing.&amp;nbsp; Se the vanilla processing animation on &lt;a href="http://martinpblogformasswritingproject.blogspot.com/2011/07/negative-modulus-in-python-ruby-and.html"&gt;my other blog&lt;/a&gt;. For your convenience I have provided these libaries here as a gist (NB: &lt;i&gt;raw view of gist is required google has done something to the formatted code&lt;/i&gt;), as well as the sketch code:-&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1078584.js?file=lut.LUT.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1078578.js?file=grammar.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1078591.js?file=rod_hilbert.rb"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-4975496528242897443?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/4975496528242897443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/07/rod-hilbert-in-ruby-processing-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4975496528242897443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4975496528242897443'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/07/rod-hilbert-in-ruby-processing-using.html' title='Rod Hilbert in Ruby-Processing (using homebaked libraries)'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-776992332051737031</id><published>2011-06-16T15:23:00.010+01:00</published><updated>2011-12-01T19:46:13.493Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='fish eye lens'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='control panel'/><title type='text'>Faux Fish Eye Lens in ruby-processing, features control panel</title><content type='html'>Sketches below show an unadulterated grid, a partial grid with fish eye 'filter' and some text with fish eye 'filter'. Unfortunately the mouse was doing two things (adjusting view and selecting image for 'the gimp') so actual captured image was a bit hit and miss. View the vanilla processing version at &lt;a href="http://www.openprocessing.org/visuals/?visualID=12140"&gt;openprocessing&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;!--pre { font-family: monospace; color: #ffffff; background-color: #000000; }body { font-family: monospace; color: #ffffff; background-color: #000000; }.Todo { color: #808080; background-color: #ffff00; }.Identifier { color: #00ffff; font-weight: bold; }.Statement { color: #ffff00; font-weight: bold; }.Type { color: #00ff00; font-weight: bold; }.Constant { color: #ff40ff; font-weight: bold; }.Special { color: #ff6060; font-weight: bold; }.PreProc { color: #8080ff; font-weight: bold; }.Comment { color: #00ffff; font-weight: bold; }--&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="Comment"&gt;############################&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# fish_eye.rb &lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# [Pseudo fisheye simulation]&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# by Jonsku, September 2010&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# From the article by Paul Bourke : &lt;a href="http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/domefisheye/fisheye/"&gt;http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/domefisheye/fisheye/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# translated to ruby-processing by Martin Prout (June 2011) &lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# Toggle fisheye, select view, adjust aperture using 'Control Panel'&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# Move mouse to change camera position.&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;############################&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;require&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;beauty&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;class&lt;/span&gt; &lt;span class="Type"&gt;Fish_Eye&lt;/span&gt; &amp;lt; &lt;span class="Type"&gt;Processing&lt;/span&gt;::&lt;span class="Type"&gt;App&lt;/span&gt;&lt;br /&gt;  load_library &lt;span class="Constant"&gt;:control_panel&lt;/span&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;attr_reader&lt;/span&gt; &lt;span class="Constant"&gt;:b_pass&lt;/span&gt;, &lt;span class="Constant"&gt;:fish_eye_filter&lt;/span&gt;, &lt;span class="Constant"&gt;:aperture&lt;/span&gt;, &lt;span class="Constant"&gt;:options&lt;/span&gt;, &lt;span class="Constant"&gt;:some_text&lt;/span&gt;, &lt;span class="Constant"&gt;:img&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;setup&lt;/span&gt;()&lt;br /&gt;    size(&lt;span class="Constant"&gt;300&lt;/span&gt;, &lt;span class="Constant"&gt;300&lt;/span&gt;)&lt;br /&gt;    setup_control&lt;br /&gt;    text_font(load_font(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Ubuntu-Regular-48.vlw&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;))&lt;br /&gt;    &lt;span class="Identifier"&gt;@some_text&lt;/span&gt; = &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Whatever it is,&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt; it was inside the Sphere.&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt; Now it's out, free to act. &lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;@img&lt;/span&gt; = load_image(&lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;pattern.png&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Identifier"&gt;@fish_eye_filter&lt;/span&gt; = &lt;span class="Constant"&gt;false&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt; = &lt;span class="Type"&gt;BeautyPass&lt;/span&gt;.new&lt;br /&gt;    smooth&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw&lt;/span&gt;()&lt;br /&gt;    background(&lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Statement"&gt;case&lt;/span&gt; options&lt;br /&gt;    &lt;span class="Statement"&gt;when&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;grid&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;      draw_grid(&lt;span class="Constant"&gt;20&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Statement"&gt;when&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;text&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;      draw_text&lt;br /&gt;    &lt;span class="Statement"&gt;when&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;image&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;      display_image&lt;br /&gt;    &lt;span class="Statement"&gt;when&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;noise&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br /&gt;      draw_noise&lt;br /&gt;    &lt;span class="Statement"&gt;else&lt;/span&gt;&lt;br /&gt;      draw_grid(&lt;span class="Constant"&gt;20&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; fish_eye_filter&lt;br /&gt;      fisheye&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;setup_control&lt;/span&gt;&lt;br /&gt;    control_panel &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;c&lt;/span&gt;|&lt;br /&gt;      c.title = &lt;span class="Special"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Control Panel&lt;/span&gt;&lt;span class="Special"&gt;"&lt;/span&gt;&lt;br /&gt;      c.button &lt;span class="Constant"&gt;:t_fisheye&lt;/span&gt;&lt;br /&gt;      c.menu(&lt;span class="Constant"&gt;:options&lt;/span&gt;, [&lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;grid&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;text&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;image&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;, &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;noise&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt; ], &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;grid&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;)&lt;br /&gt;      c.slider &lt;span class="Constant"&gt;:aperture&lt;/span&gt;, &lt;span class="Constant"&gt;0.5&lt;/span&gt;..&lt;span class="Type"&gt;Math&lt;/span&gt;::&lt;span class="Type"&gt;PI&lt;/span&gt;, &lt;span class="Constant"&gt;3.142&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;t_fisheye&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;@fish_eye_filter&lt;/span&gt; = !fish_eye_filter&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw_grid&lt;/span&gt;(row)&lt;br /&gt;    stroke(&lt;span class="Constant"&gt;255&lt;/span&gt;)&lt;br /&gt;    stroke_weight(&lt;span class="Constant"&gt;2&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; i &lt;span class="Statement"&gt;in&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;...row&lt;br /&gt;      line(&lt;span class="Constant"&gt;0&lt;/span&gt;, i * height / row, width, i * height / row)&lt;br /&gt;      line(i * height / row, &lt;span class="Constant"&gt;0&lt;/span&gt;, i * height / row, height)&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw_text&lt;/span&gt;&lt;br /&gt;    fill(&lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;255&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;    text(some_text,sin(frame_count * &lt;span class="Constant"&gt;0.1&lt;/span&gt;)*(width - text_width(some_text)), &lt;span class="Constant"&gt;180&lt;/span&gt;+&lt;span class="Type"&gt;Math&lt;/span&gt;.sin(&lt;span class="Type"&gt;Math&lt;/span&gt;::&lt;span class="Type"&gt;PI&lt;/span&gt;/&lt;span class="Constant"&gt;2&lt;/span&gt; + frame_count*&lt;span class="Constant"&gt;0.01&lt;/span&gt;)*(height-&lt;span class="Constant"&gt;170&lt;/span&gt;))&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;display_image&lt;/span&gt;&lt;br /&gt;    image(img, &lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, width, height)&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;draw_noise&lt;/span&gt;&lt;br /&gt;    push_style&lt;br /&gt;    color_mode(&lt;span class="Type"&gt;RGB&lt;/span&gt;,&lt;span class="Constant"&gt;1.0&lt;/span&gt;)&lt;br /&gt;    load_pixels&lt;br /&gt;    (&lt;span class="Constant"&gt;0&lt;/span&gt;...width).each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;i&lt;/span&gt;|&lt;br /&gt;      (&lt;span class="Constant"&gt;0&lt;/span&gt;...height).each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;j&lt;/span&gt;|&lt;br /&gt;        pixels[i+j*width] = color(noise((frame_count+i)*&lt;span class="Constant"&gt;0.1&lt;/span&gt;,j*&lt;span class="Constant"&gt;0.1&lt;/span&gt;),noise((frame_count+i)*&lt;span class="Constant"&gt;0.1&lt;/span&gt;,j*&lt;span class="Constant"&gt;0.1&lt;/span&gt;,&lt;span class="Constant"&gt;0.3&lt;/span&gt;),noise((frame_count+i)*&lt;span class="Constant"&gt;0.05&lt;/span&gt;,j*&lt;span class="Constant"&gt;0.05&lt;/span&gt;,&lt;span class="Constant"&gt;0.6&lt;/span&gt;))&lt;br /&gt;      &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    update_pixels&lt;br /&gt;    pop_style&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;fisheye&lt;/span&gt;&lt;br /&gt;    half_aperture = aperture / &lt;span class="Constant"&gt;2&lt;/span&gt;&lt;br /&gt;    &lt;span class="Comment"&gt;# define camera positioning normalized coordinates&lt;/span&gt;&lt;br /&gt;    cam_x = (&lt;span class="Constant"&gt;2.0&lt;/span&gt; * mouse_x) / (width - &lt;span class="Constant"&gt;1&lt;/span&gt;)&lt;br /&gt;    cam_y = (&lt;span class="Constant"&gt;2.0&lt;/span&gt; * mouse_y) / (width - &lt;span class="Constant"&gt;1&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;    load_pixels&lt;br /&gt;    (&lt;span class="Constant"&gt;0&lt;/span&gt;...width).each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;i&lt;/span&gt;|&lt;br /&gt;      &lt;span class="Comment"&gt;#transform pixel coordinates to normalised coordinates, range -1 to 1&lt;/span&gt;&lt;br /&gt;      x = (&lt;span class="Constant"&gt;2.0&lt;/span&gt; * i) / (width - &lt;span class="Constant"&gt;1&lt;/span&gt;)&lt;br /&gt;      (&lt;span class="Constant"&gt;0&lt;/span&gt;...height).each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;j&lt;/span&gt;|&lt;br /&gt;        y = (&lt;span class="Constant"&gt;2.0&lt;/span&gt; * j) / (height - &lt;span class="Constant"&gt;1&lt;/span&gt;)&lt;br /&gt;        &lt;span class="Comment"&gt;#radius r to camera&lt;/span&gt;&lt;br /&gt;        r = dist(cam_x, cam_y, x, y)&lt;br /&gt;        &lt;span class="Comment"&gt;#at this stage any pixels where r &amp;gt; 1 are ignored&lt;/span&gt;&lt;br /&gt;        &lt;span class="Statement"&gt;if&lt;/span&gt; (r.abs &amp;gt; &lt;span class="Constant"&gt;1&lt;/span&gt;)&lt;br /&gt;          &lt;span class="Statement"&gt;next&lt;/span&gt;&lt;br /&gt;        &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;#angle phi to x axis&lt;/span&gt;&lt;br /&gt;        phi = &lt;span class="Type"&gt;Math&lt;/span&gt;.atan2(y - cam_y, x - cam_x)&lt;br /&gt;        &lt;span class="Comment"&gt;#r is mapped onto theta and phi is used directly as the polar coordinates of the direction vector &lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;# from the camera into the scene&lt;/span&gt;&lt;br /&gt;        theta = half_aperture * r&lt;br /&gt;        &lt;span class="Comment"&gt;#transform normalised coordinates to pixel coordinates&lt;/span&gt;&lt;br /&gt;        dx = map(&lt;span class="Type"&gt;Math&lt;/span&gt;.sin(theta) * &lt;span class="Type"&gt;Math&lt;/span&gt;.cos(phi), &lt;span class="Constant"&gt;-1.0&lt;/span&gt;, &lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, width)&lt;br /&gt;        dy = map(&lt;span class="Type"&gt;Math&lt;/span&gt;.sin(theta) * &lt;span class="Type"&gt;Math&lt;/span&gt;.sin(phi), &lt;span class="Constant"&gt;-1.0&lt;/span&gt;, &lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;0&lt;/span&gt;, height)&lt;br /&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;##############&lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;# Because the pixel array uses integer coordinates, black empty pixels will appear in the resulting image.&lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;# To attempt to fix this, the destination pixel is calculated with 3x3 combinations of roundings (round-round, &lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;# the final value will be the average colors. See BeautyPass, it will become clearer.&lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;# round.floor, round.ceil, floor.floor, floor-round, etc.). Thus one pixel might have several colors but that &lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;# is taken into account and &lt;/span&gt;&lt;span class="Todo"&gt;NOTE&lt;/span&gt;&lt;span class="Comment"&gt;: This works ok for aperture up to 180 but above that it is not enough.&lt;/span&gt;&lt;br /&gt;        &lt;span class="Comment"&gt;###############&lt;/span&gt;&lt;br /&gt;        fx = dx.round&lt;br /&gt;        fy = dy.round&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.round&lt;br /&gt;        fy = dy.floor&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.round&lt;br /&gt;        fy = dy.ceil&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.floor&lt;br /&gt;        fy = dy.floor&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.floor&lt;br /&gt;        fy = dy.round&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.floor&lt;br /&gt;        fy = dy.ceil&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.ceil&lt;br /&gt;        fy = dy.ceil&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.ceil&lt;br /&gt;        fy = dy.round&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;        fx = dx.ceil&lt;br /&gt;        fy = dy.floor&lt;br /&gt;        &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.add_color(fx + fy * width, pixels[(i + j * width)])&lt;br /&gt;      &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.render&lt;br /&gt;    &lt;span class="Identifier"&gt;@b_pass&lt;/span&gt;.reset&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="Comment"&gt;############################&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# beauty.rb (helper class), part of&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# --=[Angular fisheye simulation]=--&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# by Jonsku, September 2010&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# From the article by Paul Bourke : &lt;a href="http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/domefisheye/fisheye/"&gt;http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/domefisheye/fisheye/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# translated to ruby-processing by Martin Prout&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;# Move mouse to change camera position.&lt;/span&gt;&lt;br /&gt;&lt;span class="Comment"&gt;############################&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;class&lt;/span&gt; &lt;span class="Type"&gt;BeautyPass&lt;/span&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="Type"&gt;Processing&lt;/span&gt;::&lt;span class="Type"&gt;Proxy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="Statement"&gt;attr_reader&lt;/span&gt; &lt;span class="Constant"&gt;:counts&lt;/span&gt;, &lt;span class="Constant"&gt;:rSums&lt;/span&gt;, &lt;span class="Constant"&gt;:gSums&lt;/span&gt;, &lt;span class="Constant"&gt;:bSums&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;initialize&lt;/span&gt;()&lt;br /&gt;    reset()&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;reset&lt;/span&gt;()&lt;br /&gt;    &lt;span class="Identifier"&gt;@counts&lt;/span&gt; = &lt;span class="Type"&gt;Array&lt;/span&gt;.new(width * height, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Identifier"&gt;@rSums&lt;/span&gt; = &lt;span class="Type"&gt;Array&lt;/span&gt;.new(width * height, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Identifier"&gt;@gSums&lt;/span&gt; = &lt;span class="Type"&gt;Array&lt;/span&gt;.new(width * height, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;    &lt;span class="Identifier"&gt;@bSums&lt;/span&gt; = &lt;span class="Type"&gt;Array&lt;/span&gt;.new(width * height, &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;add_color&lt;/span&gt;(i, c)&lt;br /&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (i&amp;gt;&lt;span class="Constant"&gt;0&lt;/span&gt; &amp;amp;&amp;amp; i&amp;lt; width * height)&lt;br /&gt;      &lt;span class="Identifier"&gt;@rSums&lt;/span&gt;[i] += c &amp;gt;&amp;gt; &lt;span class="Constant"&gt;16&lt;/span&gt; &amp;amp; &lt;span class="Constant"&gt;0xFF&lt;/span&gt;&lt;br /&gt;      &lt;span class="Identifier"&gt;@gSums&lt;/span&gt;[i] += c &amp;gt;&amp;gt; &lt;span class="Constant"&gt;8&lt;/span&gt; &amp;amp; &lt;span class="Constant"&gt;0xFF&lt;/span&gt;&lt;br /&gt;      &lt;span class="Identifier"&gt;@bSums&lt;/span&gt;[i] += c &amp;amp; &lt;span class="Constant"&gt;0xFF&lt;/span&gt;&lt;br /&gt;      &lt;span class="Identifier"&gt;@counts&lt;/span&gt;[i] +=  &lt;span class="Constant"&gt;1&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="PreProc"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;render&lt;/span&gt;()&lt;br /&gt;    load_pixels()&lt;br /&gt;    (&lt;span class="Constant"&gt;0&lt;/span&gt;...width * height).each &lt;span class="Statement"&gt;do&lt;/span&gt; |&lt;span class="Identifier"&gt;i&lt;/span&gt;|&lt;br /&gt;      &lt;span class="Statement"&gt;if&lt;/span&gt; (counts[i]&amp;gt;&lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br /&gt;        pixels[i] = color(rSums[i] / counts[i], gSums[i] / counts[i], bSums[i] / counts[i])&lt;br /&gt;      &lt;span class="Statement"&gt;else&lt;/span&gt;&lt;br /&gt;        pixels[i] = color(&lt;span class="Constant"&gt;0&lt;/span&gt;) &lt;span class="Comment"&gt;#background color&lt;/span&gt;&lt;br /&gt;      &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="Statement"&gt;end&lt;/span&gt;&lt;br /&gt;    update_pixels()&lt;br /&gt;  &lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="PreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-b1ld31A8hF0/TfoRUWEGKrI/AAAAAAAADR0/JplHwqVvVi4/s1600/fisheye1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="211" src="http://4.bp.blogspot.com/-b1ld31A8hF0/TfoRUWEGKrI/AAAAAAAADR0/JplHwqVvVi4/s320/fisheye1.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-U2A98IQ3Sns/TfoRYCEdj7I/AAAAAAAADR4/aH8gi6rd9eQ/s1600/fisheye2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-U2A98IQ3Sns/TfoRYCEdj7I/AAAAAAAADR4/aH8gi6rd9eQ/s320/fisheye2.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-ytRfu7NVRTU/TfoRbNkbbsI/AAAAAAAADR8/qL7y7ucA-TA/s1600/fisheye3.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-ytRfu7NVRTU/TfoRbNkbbsI/AAAAAAAADR8/qL7y7ucA-TA/s320/fisheye3.png" width="300" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-776992332051737031?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/776992332051737031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/06/faux-fish-eye-lens-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/776992332051737031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/776992332051737031'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/06/faux-fish-eye-lens-in-ruby-processing.html' title='Faux Fish Eye Lens in ruby-processing, features control panel'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-b1ld31A8hF0/TfoRUWEGKrI/AAAAAAAADR0/JplHwqVvVi4/s72-c/fisheye1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-3561450737148839079</id><published>2011-05-05T20:32:00.000+01:00</published><updated>2011-05-05T20:32:23.110+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='modelX'/><title type='text'>Exploring modelX in ruby processing</title><content type='html'>&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;############################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# processing modelX&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# examples in ruby processing&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;###########################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;size &lt;font color="#ff40ff"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;no_fill&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;push_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# start at the middle of the screen&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;translate(width/&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, height/&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, -&lt;font color="#ff40ff"&gt;&lt;b&gt;200&lt;/b&gt;&lt;/font&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# some pseudo random rotation to make things interesting&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;rotate_y &lt;font color="#ff40ff"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# yrot&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;rotate_z &lt;font color="#ff40ff"&gt;&lt;b&gt;2.0&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# zrot&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# rotate in X a little more each frame&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;rotate_x(frame_count / &lt;font color="#ff40ff"&gt;&lt;b&gt;100.0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# offset from center&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;translate(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;150&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# draw a white box outline at (0, 0, 0)&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;stroke &lt;font color="#ff40ff"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;box &lt;font color="#ff40ff"&gt;&lt;b&gt;80&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# the box was drawn at (0, 0, 0), store that location&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;x = model_x(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;y = model_y(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;z = model_z(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# clear out all the transformations&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;pop_matrix&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# draw another box at the same (x, y, z) coordinate as the other&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;push_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;translate(x, y, z)&lt;br /&gt;&amp;nbsp;&amp;nbsp;stroke(&lt;font color="#ff40ff"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;box &lt;font color="#ff40ff"&gt;&lt;b&gt;80&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;pop_matrix&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-3561450737148839079?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/3561450737148839079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/exploring-modelx-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/3561450737148839079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/3561450737148839079'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/exploring-modelx-in-ruby-processing.html' title='Exploring modelX in ruby processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-1884099115189384648</id><published>2011-05-05T20:10:00.000+01:00</published><updated>2011-05-05T20:10:16.180+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='screenX'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='parallax'/><title type='text'>Exploring screenX in ruby processing</title><content type='html'>I think there is a mistake in the version at the processing wiki (which I have flagged) because the 2D lines mentioned in the comments have six parameters (in my book that is 3D line even if Z is zero). You still get to see the parallax in my amended version, try it.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;###################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# processing screenX example&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# in ruby processing&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;###################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;size &lt;font color="#ff40ff"&gt;&lt;b&gt;100&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;100&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;font color="#ff40ff"&gt;&lt;b&gt;204&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;x = mouse_x&lt;br /&gt;&amp;nbsp;&amp;nbsp;y = mouse_y&lt;br /&gt;&amp;nbsp;&amp;nbsp;z = -&lt;font color="#ff40ff"&gt;&lt;b&gt;100&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# Draw &amp;quot;X&amp;quot; at z = -100&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;stroke &lt;font color="#ff40ff"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;line(x - &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, y - &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, z, x + &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, y + &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, z) &lt;br /&gt;&amp;nbsp;&amp;nbsp;line(x + &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, y - &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, z, x - &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, y + &lt;font color="#ff40ff"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/font&gt;, z) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# Draw line in 2D at same x value&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# Notice the parallax&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;stroke &lt;font color="#ff40ff"&gt;&lt;b&gt;102&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;line(x, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, x, height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# Draw 2D line to match the x value&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# element drawn at z = -100 &lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;stroke(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;the_x = screen_x(x, y, z)&lt;br /&gt;&amp;nbsp;&amp;nbsp;line(the_x, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, the_x, height)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-1884099115189384648?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/1884099115189384648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/exploring-screenx-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1884099115189384648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1884099115189384648'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/exploring-screenx-in-ruby-processing.html' title='Exploring screenX in ruby processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-1872788420684452007</id><published>2011-05-03T07:42:00.005+01:00</published><updated>2011-11-17T21:08:59.043Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='inflate mesh'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='toxiclibs'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><title type='text'>Winged Edge Mesh and Physics from Toxiclibs</title><content type='html'>Here is the toxiclibs InflateMesh verlet physics example demonstrating winged mesh class functionality. Although this was a P3D sketch in the example it looks best using OPENGL. Because there is still an issue with linux and ruby-processing OPENGL at less than full_screen, I have scaled some of the variables in the sketch (mainly annotated I think), anyway you should &lt;a href="http://hg.postspectacular.com/toxiclibs/wiki/Home"&gt;probably look at the original&lt;/a&gt; (included in the library download toxiclibs-complete version 0020).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;p&amp;gt;This example uses the attraction behavior to inflate a 3D mesh.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The mesh vertices are re-created as physics particles and connected&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# using springs. Upon mouse press the inflation force is applied,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# counteracting the forces created by the springs, causing the mesh to&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# expand and deform.&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;p&amp;gt;Usage: Click and hold mouse button to inflate mesh&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;############ &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Copyright (c) 2010 Karsten Schmidt translated to ruby processing by Martin Prout (Spring 2011)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# This demo &amp;amp; library is free software you can redistribute it and/or&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# modify it under the terms of the GNU Lesser General Public&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# License as published by the Free Software Foundation either&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# version 2.1 of the License, or (at your option) any later version.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# http:#creativecommons.org/licenses/LGPL/2.1/&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# This library is distributed in the hope that it will be useful,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# but WITHOUT ANY WARRANTY without even the implied warranty of&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&amp;nbsp;&amp;nbsp;See the GNU&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Lesser General Public License for more details.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# You should have received a copy of the GNU Lesser General Public&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# License along with this library if not, write to the Free Software&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA&amp;nbsp;&amp;nbsp;02110-1301&amp;nbsp;&amp;nbsp;USA&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;InflateMesh&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxiclibs_p5&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxiclibscore&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;verletphysics&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;processing.opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.geom&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.geom.mesh.subdiv&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.geom.mesh&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.physics&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.physics.behaviors&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.physics.constraints&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.processing&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:physics&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:inflate&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:box&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:gfx&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;full_screen&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setup_opengl&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gfx&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ToxiclibsSupport&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;init_physics&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.update()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;nbsp;vert &lt;span style="color: yellow;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt;&amp;nbsp;box.vertices.values&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vert.set(physics.particles.get(vert.id))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;box.center(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# nil means centre at 0, 0, 0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;nbsp;vert &lt;span style="color: yellow;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt;&amp;nbsp;box.vertices.values&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.particles.get(vert.id).set(vert)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;box.compute_face_normals&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;box.face_outwards&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;box.compute_vertex_normals&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;51&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;translate(width / &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, height / &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotate_x((height / &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- mouse_y) * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotate_y((width / &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- mouse_x) * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_fill&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;directional_light(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;200&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1000&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;specular(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shininess(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;16&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gfx&lt;/b&gt;&lt;/span&gt;.origin(&lt;span style="color: lime;"&gt;&lt;b&gt;Vec3D&lt;/b&gt;&lt;/span&gt;.new, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;300&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# scaled up axes display from 50&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fill(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;192&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_stroke&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gfx&lt;/b&gt;&lt;/span&gt;.mesh(box, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;true&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# scaled up normals display from 5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;init_physics&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@box&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;WETriangleMesh&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# create a simple start mesh&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;#box.add_mesh(Cone.new(Vec3D.new(0, 0, 0), Vec3D.new(0, 1, 0), 10, 50, 100).to_mesh(4))&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@box&lt;/b&gt;&lt;/span&gt;.add_mesh(&lt;span style="color: lime;"&gt;&lt;b&gt;AABB&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: lime;"&gt;&lt;b&gt;Vec3D&lt;/b&gt;&lt;/span&gt;.new, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;150&lt;/b&gt;&lt;/span&gt;).to_mesh)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# scaled up from 50&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# then subdivide a few times...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@box&lt;/b&gt;&lt;/span&gt;.subdivide&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@box&lt;/b&gt;&lt;/span&gt;.subdivide&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@box&lt;/b&gt;&lt;/span&gt;.subdivide&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@box&lt;/b&gt;&lt;/span&gt;.subdivide&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;VerletPhysics&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.set_world_bounds(&lt;span style="color: lime;"&gt;&lt;b&gt;AABB&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: lime;"&gt;&lt;b&gt;Vec3D&lt;/b&gt;&lt;/span&gt;.new, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;540&lt;/b&gt;&lt;/span&gt;))&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# scaled up from 180&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# turn mesh vertices into physics particles&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;nbsp;vert &lt;span style="color: yellow;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt;&amp;nbsp;box.vertices.values&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.add_particle(&lt;span style="color: lime;"&gt;&lt;b&gt;VerletParticle&lt;/b&gt;&lt;/span&gt;.new(vert))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# turn mesh edges into springs&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;nbsp;w_edge &lt;span style="color: yellow;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt;&amp;nbsp;box.edges.values&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vp_a = physics.particles.get(w_edge.a.id)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vp_b = physics.particles.get(w_edge.b.id)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.add_spring(&lt;span style="color: lime;"&gt;&lt;b&gt;VerletSpring&lt;/b&gt;&lt;/span&gt;.new(vp_a, vp_b, vp_a.distance_to(vp_b), &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.05&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;key_pressed&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# using a switch anticipating more key actions &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;init_physics&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;s&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;save_frame &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;inflate.png&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;mouse_pressed&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@inflate&lt;/b&gt;&lt;/span&gt;=&lt;span style="color: lime;"&gt;&lt;b&gt;AttractionBehavior&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: lime;"&gt;&lt;b&gt;Vec3D&lt;/b&gt;&lt;/span&gt;.new, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;400&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.001&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.add_behavior(inflate)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;mouse_released&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@physics&lt;/b&gt;&lt;/span&gt;.remove_behavior(inflate)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_opengl&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render_mode &lt;span style="color: lime;"&gt;&lt;b&gt;OPENGL&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint &lt;span style="color: lime;"&gt;&lt;b&gt;ENABLE_OPENGL_4X_SMOOTH&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint &lt;span style="color: lime;"&gt;&lt;b&gt;DISABLE_OPENGL_ERROR_REPORT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-o_SPQSmRteY/Tb-jik_a4lI/AAAAAAAADL4/kHxH03Qfpto/s1600/inflate.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="365" src="http://3.bp.blogspot.com/-o_SPQSmRteY/Tb-jik_a4lI/AAAAAAAADL4/kHxH03Qfpto/s400/inflate.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-1872788420684452007?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/1872788420684452007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/winged-edge-mesh-and-physics-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1872788420684452007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1872788420684452007'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/winged-edge-mesh-and-physics-from.html' title='Winged Edge Mesh and Physics from Toxiclibs'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-o_SPQSmRteY/Tb-jik_a4lI/AAAAAAAADL4/kHxH03Qfpto/s72-c/inflate.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-4118878674817973400</id><published>2011-05-02T17:07:00.002+01:00</published><updated>2011-05-02T17:20:22.322+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hemesh'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='libraries'/><title type='text'>Using Hemesh Library in ruby-processing</title><content type='html'>It has been positively ages since I last posted any ruby-processing sketches here is one processing library that you might like to experiment with it is the Hemesh library by &lt;a href="http://www.wblut.com/"&gt;Frederik Vanhoutte aka W:Blut&lt;/a&gt;. Over on my other blog I have been describing the development of my latest processing library "povwriter" a tool for exporting processing sketches to the povray format and this is one of the sketches I have used. &amp;nbsp;Next I will attempt to get my "povwriter" library working in ruby processing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# RandomCage.rb is a processing sketch that shows&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# how you can use the Hemesh library in Ruby-Processing.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;RandomCage&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;hemesh&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;wblut.hemesh&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;wblut.hemesh.creators&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;wblut.hemesh.iterators&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;wblut.hemesh.modifiers&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;wblut.hemesh.subdividors&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;import &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;processing.opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;full_screen&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;TWO_PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cage&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configure_opengl&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@cage&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;HE_Mesh&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: lime;"&gt;&lt;b&gt;HEC_Box&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;).set_depth(height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;).set_height(height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;).set_width(height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@cage&lt;/b&gt;&lt;/span&gt;.modify(&lt;span style="color: lime;"&gt;&lt;b&gt;HEM_ChamferCorners&lt;/b&gt;&lt;/span&gt;.new.set_distance(height*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.1&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;#HES_Planar() subdivision can include a measure of randomness&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@cage&lt;/b&gt;&lt;/span&gt;.subdivide(&lt;span style="color: lime;"&gt;&lt;b&gt;HES_Planar&lt;/b&gt;&lt;/span&gt;.new.set_random(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;true&lt;/b&gt;&lt;/span&gt;).set_range(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.4&lt;/b&gt;&lt;/span&gt;),&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;#A save choice after introducing any kind of randomness is to triangulate possible concave faces.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;#Concave faces do not invalidate the mesh but can give unexpected results.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@cage&lt;/b&gt;&lt;/span&gt;.triangulate_concave_faces() &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@cage&lt;/b&gt;&lt;/span&gt;.modify(&lt;span style="color: lime;"&gt;&lt;b&gt;HEM_Lattice&lt;/b&gt;&lt;/span&gt;.new.set_depth(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.016&lt;/b&gt;&lt;/span&gt;*height).set_width(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.016&lt;/b&gt;&lt;/span&gt;*height).set_fuse(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;true&lt;/b&gt;&lt;/span&gt;)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sel = &lt;span style="color: lime;"&gt;&lt;b&gt;HE_Selection&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;nbsp;f &lt;span style="color: yellow;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt;&amp;nbsp;cage.f_itr&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# using ruby syntax here&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sel.add f&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cage.subdivide_selected(&lt;span style="color: lime;"&gt;&lt;b&gt;HES_CatmullClark&lt;/b&gt;&lt;/span&gt;.new(),sel,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;120&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;translate(width/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotate_y(mouse_x * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;/ width * &lt;span style="color: lime;"&gt;&lt;b&gt;TWO_PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotate_x(mouse_y * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;/ height * &lt;span style="color: lime;"&gt;&lt;b&gt;TWO_PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fill(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_stroke&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cage.draw_faces&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stroke(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cage.draw_edges&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;configure_opengl&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render_mode &lt;span style="color: lime;"&gt;&lt;b&gt;OPENGL&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint &lt;span style="color: lime;"&gt;&lt;b&gt;ENABLE_OPENGL_4X_SMOOTH&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint &lt;span style="color: lime;"&gt;&lt;b&gt;DISABLE_OPENGL_ERROR_REPORT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-BODZHOsCgKo/Tb7Wlj8gnHI/AAAAAAAADL0/92lgSMv0NBQ/s1600/hemesh.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="370" src="http://1.bp.blogspot.com/-BODZHOsCgKo/Tb7Wlj8gnHI/AAAAAAAADL0/92lgSMv0NBQ/s400/hemesh.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-4118878674817973400?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/4118878674817973400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/using-hemesh-library-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4118878674817973400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4118878674817973400'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/05/using-hemesh-library-in-ruby-processing.html' title='Using Hemesh Library in ruby-processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-BODZHOsCgKo/Tb7Wlj8gnHI/AAAAAAAADL0/92lgSMv0NBQ/s72-c/hemesh.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-3299815066194931306</id><published>2011-03-03T10:56:00.017Z</published><updated>2011-03-10T16:55:24.695Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='LSystems'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context-sensitive'/><title type='text'>The 'growing' of a context-sensitive L-system plant (ruby-processing)</title><content type='html'>LSystem rules from a paper by Tong Lin at &lt;a href="http://www.cs.umbc.edu/~ebert/693/TLin/top.html"&gt;UMBC&lt;/a&gt; Maryland. The following code could be simplified if you could rely on string index being a char (ruby 1.9) rather than ascii value (ruby 1.8), tripped me up at first, ruby-processing is still at 1.8 (it depends on JRuby which will start supporting ruby 1.9 from JRuby version 1.6?)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: yellow;"&gt;Update 10 March 2011 just tried jruby-complete-1.6-RC3 still get old behaviour ie ascii value rather than char when indexing a string, nor is ord method supported still requires Jeremys shim to string&lt;/span&gt;.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;########################################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# cs_test.rb&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# A 3D Plant implemented using a Context Sensitive&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Lindenmayer System in ruby-processing &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# by Martin Prout (3 March 2011)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;########################################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;CS_Test&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;full_screen &lt;span style="color: cyan;"&gt;&lt;b&gt;# NB: All distances are relative to screen height&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;csplant&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;PeasyCam&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;import &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;peasy&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;import &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;processing.opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;library_loaded? &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;opengl&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:csplant&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cam&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;library_loaded?(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:opengl&lt;/b&gt;&lt;/span&gt;) ? configure_opengl : render_mode(&lt;span style="color: lime;"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configure_peasycam&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@csplant&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;CSPlant&lt;/b&gt;&lt;/span&gt;.new(height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;csplant.create_grammar &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_stroke&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;configure_peasycam&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cam = &lt;span style="color: lime;"&gt;&lt;b&gt;PeasyCam&lt;/b&gt;&lt;/span&gt;.new &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;, height / &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cam.set_minimum_distance height / &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cam.set_maximum_distance height&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;configure_opengl&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render_mode &lt;span style="color: lime;"&gt;&lt;b&gt;OPENGL&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint &lt;span style="color: lime;"&gt;&lt;b&gt;ENABLE_OPENGL_4X_SMOOTH&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hint &lt;span style="color: lime;"&gt;&lt;b&gt;DISABLE_OPENGL_ERROR_REPORT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;csplant.render&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The PeasyCam and csplant libraries need to be nested in the usual way in a library folder.  This code is much more complicated than my previous post. This is mainly due to the need to ignore certain symbols when determining context, and hence need to navigate along the production string. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;######################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# csplant.rb &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# A library used to implement&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# a context sensitive&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# 1-L lsystem grammar in &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# ruby-processing&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# by Martin Prout (4 March 2011)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;######################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;################################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# A helper class stores cs prefix idx, and cchar&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# uses idx and char to determine context and&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# pre to access context sensitive rule from rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;###############################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;CSRule&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_accessor&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:pre&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;&amp;nbsp;pre&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@pre&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= pre&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;idx&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;(pre[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;] == &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;60&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# NB comparing ascii values until ruby 1.9 support&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x -= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;(pre[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;] == &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;62&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# "&amp;gt;"[0] = 62, "&amp;lt;"[0] = 60&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x += &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;cchar&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;pre[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The grammar class stores lsystem rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# in rules Hash, and context Hash if applicable&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# In production context is checked (and applied) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# using get_rule method&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##################################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;CSGrammar&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;IGNORE&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;[]+-^&amp;amp;3&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# characters to ignore for context as a constant string&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:axiom&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:context&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rules&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:count&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;(axiom)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@axiom&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= axiom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Hash&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@context&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Hash&lt;/b&gt;&lt;/span&gt;.new &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;add_rule&lt;/b&gt;&lt;/span&gt;(pre, rule)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;pre.length == &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context.store(pre[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: lime;"&gt;&lt;b&gt;CSRule&lt;/b&gt;&lt;/span&gt;.new(pre)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rules.store pre, rule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;generate&lt;/b&gt;&lt;/span&gt;(repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;) &lt;span style="color: cyan;"&gt;&lt;b&gt;# repeat iteration grammar rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prod = axiom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prod = new_production(prod)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;prod&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;new_production&lt;/b&gt;&lt;/span&gt;&amp;nbsp;prod&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# single iteration grammar rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@count&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# initialise count on axiom or new prod&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prod.gsub!(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;) &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;ch&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get_rule(prod, ch) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;get_rule&lt;/b&gt;&lt;/span&gt;&amp;nbsp;prod, ch&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = ch&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# default is to return original character as rule (ie no change)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;idx = count &lt;span style="color: cyan;"&gt;&lt;b&gt;# idx is a local index, used to navigate the production string&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;(context.has_key?(ch[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;IGNORE&lt;/b&gt;&lt;/span&gt;.include?(prod[context[ch[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]].idx + idx].chr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;idx += context[ch[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]].idx&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;prod[context[ch[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]].idx + idx] == context[ch[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]].cchar&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = rules[context[ch[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;]].pre]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = rules[ch] &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rules.has_key?(ch) &lt;span style="color: cyan;"&gt;&lt;b&gt;# context free rule if it exists&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = rules[ch] &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rules.has_key?(ch) &lt;span style="color: cyan;"&gt;&lt;b&gt;# context free rule if it exists&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@count&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# increment the index of axiom/production as a side effect&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;############&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# CSPlant &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;############&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;CSPlant&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;include&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Proxy&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:grammar&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:axiom&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:production&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:premis&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rule&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:theta&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:scale_factor&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:distance&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:phi&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:len&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;(len)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@axiom&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;F&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@grammar&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;CSGrammar&lt;/b&gt;&lt;/span&gt;.new(axiom)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@production&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= axiom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@len&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= len&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@distance&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= len/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# distance value relative to screen height&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@theta&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;180&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;25&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@phi&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;180&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;25&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grammar.add_rule(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;F&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;F[-EF[3&amp;amp;A]]E[+F[3^A]]&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grammar.add_rule(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;F&amp;lt;E&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;F[&amp;amp;F[3+A]][^F[3-A]]&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# context sensitive rule&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_stroke()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;render&lt;/b&gt;&lt;/span&gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fill(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;75&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;152&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;light_specular(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;204&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;204&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;204&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;specular(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shininess(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;production.scan(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;) &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;ch&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/span&gt;(ch)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;F&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;translate(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, distance/-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;box(distance/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;, distance, distance/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;translate(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, distance/-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;+&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotateX(-theta * repeat)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;-&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotateX(theta * repeat)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;amp;&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotateZ(-phi * repeat)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;^&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotateZ(phi * repeat)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;[&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;push_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;]&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pop_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;E&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;A&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;puts(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;character '&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;ch&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;' not in grammar&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;##############################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# create grammar from axiom and&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# rules (adjust scale)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;##############################&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;create_grammar&lt;/b&gt;&lt;/span&gt;(gen)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@distance&lt;/b&gt;&lt;/span&gt;&amp;nbsp;*= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;**gen&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@production&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= grammar.generate gen&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-X9vrrLHac2g/TW91UPvd-kI/AAAAAAAADH0/D-DoRtZgfok/s1600/plant.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="305" src="https://lh5.googleusercontent.com/-X9vrrLHac2g/TW91UPvd-kI/AAAAAAAADH0/D-DoRtZgfok/s400/plant.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-3299815066194931306?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/3299815066194931306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/03/growing-of-context-sensitive-l-system.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/3299815066194931306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/3299815066194931306'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/03/growing-of-context-sensitive-l-system.html' title='The &apos;growing&apos; of a context-sensitive L-system plant (ruby-processing)'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-X9vrrLHac2g/TW91UPvd-kI/AAAAAAAADH0/D-DoRtZgfok/s72-c/plant.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-2621521867824169604</id><published>2011-03-01T20:09:00.002Z</published><updated>2011-03-05T08:11:55.948Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby-processing'/><category scheme='http://www.blogger.com/atom/ns#' term='l-system'/><category scheme='http://www.blogger.com/atom/ns#' term='context sensitive'/><title type='text'>Exploring Context Sensitive LSystem rules in ruby / ruby-processing</title><content type='html'>&lt;b&gt;Warning the following code depends on ruby 1.9, where string index returns a char rather than an ascii value (ruby 1.8) see following post for how this tripped me up at first when exploring a proper ruby-processing example.&lt;/b&gt; (&lt;i&gt;Update 5 March 2011&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;######################################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# cs_grammar.rb a context sensitive&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# 1-L lsystem grammar for &lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# ruby/ruby-processing&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# by Martin Prout (1 March 2011)&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;######################################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;#######################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# A helper class stores&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# cs rules idx, and cchar&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# methods extract cs data&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;#######################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;CSRule&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;attr_accessor&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;:pre&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:crule&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/font&gt;&amp;nbsp;pre, crule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@pre&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ffff"&gt;&lt;b&gt;@crule&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= pre, crule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;idx&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x = &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(pre[&lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;] == &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;&amp;lt;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x -= &lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;cchar&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;pre[&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;##################################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# The grammar class stores rules&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# in two Hashes, one for cs rules,&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# one for context free rules. Rules&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# are filtered on input, and context&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# is checked using get_rule in production&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;##################################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;CSGrammar&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;:axiom&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:context&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:no_context&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:idx&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/font&gt;(axiom)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@axiom&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= axiom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@no_context&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#00ff00"&gt;&lt;b&gt;Hash&lt;/b&gt;&lt;/font&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@context&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#00ff00"&gt;&lt;b&gt;Hash&lt;/b&gt;&lt;/font&gt;.new &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;add_rule&lt;/b&gt;&lt;/font&gt;(pre, rule)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;pre.length&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@context&lt;/b&gt;&lt;/font&gt;.store(pre[&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;], &lt;font color="#00ff00"&gt;&lt;b&gt;CSRule&lt;/b&gt;&lt;/font&gt;.new(pre, rule)) &lt;font color="#00ffff"&gt;&lt;b&gt;# index, context, rule&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@no_context&lt;/b&gt;&lt;/font&gt;.store pre, rule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;&amp;nbsp;print &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;unrecognized grammar '&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/font&gt;pre&lt;font color="#ff6060"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;generate&lt;/b&gt;&lt;/font&gt;(repeat = &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;) &lt;font color="#00ffff"&gt;&lt;b&gt;# repeat iteration grammar rules&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prod = axiom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat.times &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prod = new_production(prod)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;prod&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;new_production&lt;/b&gt;&lt;/font&gt;&amp;nbsp;prod&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# single iteration grammar rules&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@idx&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prod.gsub!(&lt;font color="#ff6060"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/font&gt;) &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;ch&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get_rule(prod, ch) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;get_rule&lt;/b&gt;&lt;/font&gt;&amp;nbsp;prod, ch&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = ch &lt;font color="#00ffff"&gt;&lt;b&gt;# default is return original character as rule (no change)&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@idx&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+= &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# increment the index of axiom/production as a side effect&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(context.has_key?(ch)) &amp;amp;&amp;amp; (prod[context[ch].idx + idx] == context[ch].cchar)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = context[ch].crule&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# use context sensitive rule&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = no_context[ch] &lt;font color="#ffff00"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;no_context.has_key?(ch) &lt;font color="#00ffff"&gt;&lt;b&gt;# context free rule if it exists&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;rule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# Test data taken from ABOP&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;7&lt;/b&gt;&lt;/font&gt;.times &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp; grammar = &lt;font color="#00ff00"&gt;&lt;b&gt;CSGrammar&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;baaaaaa&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; grammar.add_rule(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;b&amp;lt;a&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;b&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;)&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# context sensitive rule replace a when preceded by b&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; grammar.add_rule(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;b&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; result = grammar.generate(i)&lt;br /&gt;&amp;nbsp;&amp;nbsp; print result &amp;lt;&amp;lt; &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;\n&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;pre&gt;Test Output:&lt;br /&gt;&lt;br /&gt;baaaaaa&lt;br /&gt;abaaaaa&lt;br /&gt;aabaaaa&lt;br /&gt;aaabaaa&lt;br /&gt;aaaabaa&lt;br /&gt;aaaaaba&lt;br /&gt;aaaaaab&lt;br /&gt;&lt;/pre&gt;&lt;/b&gt;&lt;br /&gt;Note the way b 'travels' from left to right through the production string in the test output.&lt;br /&gt;&lt;br /&gt;Reference: &lt;br /&gt;&lt;br /&gt;The Algorithmic Beauty of Plants &lt;br /&gt;&lt;br /&gt;Przemyslaw Prusinkiewicz&lt;br /&gt;Aristid Lindenmayer&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-2621521867824169604?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/2621521867824169604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/03/exploring-context-sensitive-lsystem.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/2621521867824169604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/2621521867824169604'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/03/exploring-context-sensitive-lsystem.html' title='Exploring Context Sensitive LSystem rules in ruby / ruby-processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-5586042415140387644</id><published>2011-01-21T06:57:00.005Z</published><updated>2011-01-21T14:12:22.574Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby-processing'/><category scheme='http://www.blogger.com/atom/ns#' term='java2d'/><category scheme='http://www.blogger.com/atom/ns#' term='java_args.txt'/><title type='text'>Accelerating java2d sketches in ruby processing</title><content type='html'>Graphics acceleration of java2d is apparently &lt;a href="http://download.oracle.com/javase/1.5.0/docs/guide/2d/new_features.html#ogl"&gt;turned off by default&lt;/a&gt;. To enable it add the following to java_args.txt in the data folder (of the sketch you wish to accelerate).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;-Dsun.java2d.opengl=true &amp;nbsp;(use True instead for verbose output informs you that the graphics pipeline is open)&lt;/pre&gt;&lt;div&gt;Which sketches will benefit from such acceleration could be determined empirically, although this &lt;a href="http://today.java.net/pub/a/today/2004/11/12/graphics2d.html"&gt;article&lt;/a&gt; gives some guidance. &amp;nbsp;I was alerted to this information by one of phi.lho responses (&lt;i&gt;on the processing discussion board&lt;/i&gt;) to a query about relative speed of some sketches on Windows and Ubuntu (which were different Ubuntu slower, until the use of this java option).&lt;/div&gt;&lt;br /&gt;This article is only of interest if you've got a decent graphics card and are &lt;b&gt;not&lt;/b&gt; using software emulated graphics acceleration (eg &lt;b&gt;mesa&lt;/b&gt; on linux). Doesn't seem to play well with control panel sketches such as jwishy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-5586042415140387644?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/5586042415140387644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/01/accelerating-java2d-sketches-in-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5586042415140387644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5586042415140387644'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2011/01/accelerating-java2d-sketches-in-ruby.html' title='Accelerating java2d sketches in ruby processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-7166471799103233908</id><published>2010-11-30T15:03:00.000Z</published><updated>2010-11-30T15:03:04.781Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby-processing'/><category scheme='http://www.blogger.com/atom/ns#' term='LSystems'/><category scheme='http://www.blogger.com/atom/ns#' term='PGraphicsPDF'/><title type='text'>Another Snake Kolam in ruby-processing demonstrates the use of PGraphicsPDF</title><content type='html'>&lt;script src="https://gist.github.com/721792.js"&gt; &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-7166471799103233908?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/7166471799103233908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/11/another-snake-kolam-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7166471799103233908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7166471799103233908'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/11/another-snake-kolam-in-ruby-processing.html' title='Another Snake Kolam in ruby-processing demonstrates the use of PGraphicsPDF'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-5067508432805211952</id><published>2010-10-30T14:01:00.002+01:00</published><updated>2010-11-08T06:22:12.551Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pixel array'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='perlin noise'/><title type='text'>Revised Perlin Noise Sketch (to use pixel array)</title><content type='html'>A somewhat optimized sketch, makes use of processing pixel array&amp;nbsp;functionality, takes a little time to "warm-up". Original used P3D mode, probably should have been P2D (apparently better than default for pixel array type sketches)....&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;##################################################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# amp_zoom_in.rb&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# adapted from a sketch at &lt;a href="http://www.biothing.org"&gt;http://www.biothing.org&lt;/a&gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;##################################################&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffff00"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;:col&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:a&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:b&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:c&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:k&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:amp&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:time&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/font&gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;size(&lt;font color="#ff40ff"&gt;&lt;b&gt;640&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;480&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;P2D&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;color_mode(&lt;font color="#00ff00"&gt;&lt;b&gt;RGB&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;frame_rate(&lt;font color="#ff40ff"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_pixels()&lt;br /&gt;&amp;nbsp;&amp;nbsp;reset&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/font&gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@time&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+= &lt;font color="#ff40ff"&gt;&lt;b&gt;0.1&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#00ffff"&gt;&lt;b&gt;#step ahead in time with each frame&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;#now go through each pixel in the window:&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;...width).each &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;x&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;...height).each &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;y&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;#create values with trig functions, noise, etc acting on x,y and time.&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;#experiment with how these values are modulating over time.&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@a&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= dist(x, y, width/&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, height/&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@b&lt;/b&gt;&lt;/font&gt;= (cos(x/&lt;font color="#ff40ff"&gt;&lt;b&gt;360.0&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ time)).abs&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#00ffff"&gt;&lt;b&gt;# frequency larger means less&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@c&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= noise(y/&lt;font color="#ff40ff"&gt;&lt;b&gt;180.0&lt;/b&gt;&lt;/font&gt;*cos(time/&lt;font color="#ff40ff"&gt;&lt;b&gt;20.0&lt;/b&gt;&lt;/font&gt;))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# inteference, larger means less&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@amp&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= k&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# amplitude&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@col&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= color((cos(a/&lt;font color="#ff40ff"&gt;&lt;b&gt;120.0&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ b + c * &lt;font color="#ff40ff"&gt;&lt;b&gt;10.0&lt;/b&gt;&lt;/font&gt;).abs)) * amp&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;#combine values into a color somehow.&amp;nbsp;&amp;nbsp;again the possibilities are limitless&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pixels[y * width + x] = col&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;rescue&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reset&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;update_pixels()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@k&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+= &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;reset&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@k&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@time&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_DUDH0kznFTA/TMwW6Q6uVaI/AAAAAAAAC_A/kD1pXpgs4Q8/s1600/biothing.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://2.bp.blogspot.com/_DUDH0kznFTA/TMwW6Q6uVaI/AAAAAAAAC_A/kD1pXpgs4Q8/s400/biothing.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-5067508432805211952?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/5067508432805211952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/revised-perlin-noise-sketch-to-use.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5067508432805211952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5067508432805211952'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/revised-perlin-noise-sketch-to-use.html' title='Revised Perlin Noise Sketch (to use pixel array)'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_DUDH0kznFTA/TMwW6Q6uVaI/AAAAAAAAC_A/kD1pXpgs4Q8/s72-c/biothing.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-150893828118605621</id><published>2010-10-30T11:45:00.005+01:00</published><updated>2010-10-30T13:08:35.221+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='voronoi mesh'/><category scheme='http://www.blogger.com/atom/ns#' term='portrait application'/><title type='text'>Revisiting My Voronoi Application</title><content type='html'>I had the idea for sometime to optimize this application. As &lt;a href="http://learning-ruby-processing.blogspot.com/2010/04/using-voronoi-library-in-ruby.html"&gt;before&lt;/a&gt; the application uses &lt;a href="http://http://www.leebyron.com/else/mesh/"&gt;Lee Byrons&lt;/a&gt; library which in turn depends on John Lloyds QuickHull3D library (both can be accessed at the Lee Byron link). One day I might re-write the application to use a 3D mesh library directly. The major optimization here is to use processings built in pixels array functionality. The app will work best if the aspect ratio of the image is the same as the frame size (1:1 is probably optimal?). I have introduced an auto-scale feature that seems to work...&lt;br /&gt;&lt;br /&gt;Use the &lt;i&gt;&lt;b&gt;view raw&lt;/b&gt;&lt;/i&gt; feature (below) if you want to copy the code.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/655189.js"&gt; &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-150893828118605621?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/150893828118605621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/revisiting-my-voronoi-application.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/150893828118605621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/150893828118605621'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/revisiting-my-voronoi-application.html' title='Revisiting My Voronoi Application'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-5674638044395019144</id><published>2010-10-14T14:13:00.004+01:00</published><updated>2010-10-23T16:54:11.051+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='sunflow raytracing'/><title type='text'>Creating simple animations using the SunflowAPIAPI library and jruby</title><content type='html'>Here I explore the animation possibilities of the SunflowAPIAPI library (nothing on the scale of the one by &lt;a href="http://vimeo.com/15366906"&gt;amnon.owed&lt;/a&gt;). &lt;br /&gt;It is very simple to use ruby syntax to create different views of a scene by changing the camera position, and use sunflow to render each image. Rather than modify each frame, I had the idea of using 20 incremental views, and crudely converting them to 200 frames by copying each view 10 times. I then used mencoder to stitch the frames together to produce a short movie. Here is the result:-&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://player.vimeo.com/video/15835238" width="400" height="300" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/15835238"&gt;Changing the camera Sunflow Hair&lt;/a&gt; from &lt;a href="http://vimeo.com/user4783150"&gt;monkstone&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#00ffff"&gt;&lt;b&gt;# hair.rb NB: run this script directly with jruby&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;library/sunflow_api/library/sunflow_api.jar&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;library/sunflow/library/sunflow.jar&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;library/sunflow/library/janino.jar&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;library/sunflow/library/commons-compiler.jar&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;BasicHair&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#00ff00"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Com&lt;/b&gt;&lt;/font&gt;::briansteen::&lt;font color="#00ff00"&gt;&lt;b&gt;SunflowAPIAPI&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#00ff00"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Org&lt;/b&gt;&lt;/font&gt;::sunflow::math&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= java.awt.Color&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;:width&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:height&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:n_particles&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:sunflow&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/font&gt;&amp;nbsp;width = &lt;font color="#ff40ff"&gt;&lt;b&gt;640&lt;/b&gt;&lt;/font&gt;, height = &lt;font color="#ff40ff"&gt;&lt;b&gt;480&lt;/b&gt;&lt;/font&gt;, cam_x = &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@width&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= width&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@height&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= height&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@n_particles&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#ff40ff"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# create a new API instance&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#00ff00"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/font&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set width and height&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_width(width)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_height(height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set background color&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_background(&lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set camera&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_camera_position(cam_x, &lt;font color="#ff40ff"&gt;&lt;b&gt;7&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_camera_target(&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_thinlens_camera(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;thinLensCamera&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/font&gt;, width/height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set basic light&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_point_light(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;myPointLight&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/font&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/font&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.set_directional_light(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;myDirectionalLight&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/font&gt;.new(-&lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;), &lt;font color="#ff40ff"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# @sunflow.setSphereLight(&amp;quot;mySphereLight&amp;quot;, SMath::Point3.new(0, 30, -5), &lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# JColor.new(0, 0, 255), 32, 10)&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# draw a ground plane&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.draw_plane(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;ground&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;), &lt;font color="#00ff00"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# coordinates array &lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.draw_box(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;boxname&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;create_scene&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_widths = [&lt;font color="#ff40ff"&gt;&lt;b&gt;0.025&lt;/b&gt;&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# create particle coordinates&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff40ff"&gt;&lt;b&gt;350&lt;/b&gt;&lt;/font&gt;.times &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;j&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# particle start position&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_x = &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.cos(j * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/font&gt;) * j * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.0015&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_y = &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_z = &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.sin(j * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/font&gt;) * j * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.0015&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates = &lt;font color="#00ff00"&gt;&lt;b&gt;Array&lt;/b&gt;&lt;/font&gt;.new(n_particles * &lt;font color="#ff40ff"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;array_index = -&lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n_particles.times &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_x += &lt;font color="#ff40ff"&gt;&lt;b&gt;0.1&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.cos(i * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.15&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ j * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.05&lt;/b&gt;&lt;/font&gt;) * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.13&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_y -= &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.sin(particle_z * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ j * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.05&lt;/b&gt;&lt;/font&gt;) * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.125&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.cos(i * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ particle_y) * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.125&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_z += &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.sin(i) * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.25&lt;/b&gt;&lt;/font&gt;&amp;nbsp;+ particle_y * &lt;font color="#ff40ff"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates[array_index += &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;] = particle_x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates[array_index += &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;] = particle_y&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates[array_index += &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;] = particle_z&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set ambient occlusion shader&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.setAmbientOcclusionShader(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;myAmbientOcclusionShader&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/font&gt;j&lt;font color="#ff6060"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, &lt;font color="#00ff00"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;55&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;55&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;55&lt;/b&gt;&lt;/font&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ff00"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/font&gt;.new(&lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/font&gt;), &lt;font color="#ff40ff"&gt;&lt;b&gt;16&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set glass shader&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# @sunflow.setGlassShader(&amp;quot;myGlassShader&amp;quot;, JColor.new(1, 1, 1), 2.5, 3, JColor.new(1, 1, 1))&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# set shiny-diffuse shader&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# @sunflow.setShinyDiffuseShader(&amp;quot;myShinyShader&amp;quot;, JColor.new(55, 55, 55), 0.8)&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# draw object&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/font&gt;.draw_hair(&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;hair&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/font&gt;j&lt;font color="#ff6060"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;, n_particles - &lt;font color="#ff40ff"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/font&gt;, hair_coordinates.to_java(&lt;font color="#ff40ff"&gt;&lt;b&gt;:float&lt;/b&gt;&lt;/font&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_widths.to_java(&lt;font color="#ff40ff"&gt;&lt;b&gt;:float&lt;/b&gt;&lt;/font&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;render_scene&lt;/b&gt;&lt;/font&gt;&amp;nbsp;filename = &lt;font color="#ff40ff"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.setIrradianceCacheGIEngine(&lt;font color="#ff40ff"&gt;&lt;b&gt;32&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;0.4&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;15&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/font&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# render&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.render() &lt;font color="#ffff00"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/font&gt;&amp;nbsp;filename&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;filename&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# test for dodgy filename/path&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;file = &lt;font color="#00ff00"&gt;&lt;b&gt;File&lt;/b&gt;&lt;/font&gt;.new(filename, &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;w&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;file.close&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.render(filename) &lt;font color="#00ffff"&gt;&lt;b&gt;# save as png image&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;rescue&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;puts &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;Warning &lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/font&gt;filename&lt;font color="#ff6060"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;&amp;nbsp;is not writable&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;font color="#8080ff"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/font&gt;.times &lt;font color="#ffff00"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/font&gt;&amp;nbsp;|&lt;font color="#00ffff"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/font&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;hair = &lt;font color="#00ff00"&gt;&lt;b&gt;BasicHair&lt;/b&gt;&lt;/font&gt;.new &lt;font color="#ff40ff"&gt;&lt;b&gt;640&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;480&lt;/b&gt;&lt;/font&gt;, i&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#00ffff"&gt;&lt;b&gt;# preferred render size for vimeo&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;hair.create_scene&lt;br /&gt;&amp;nbsp;&amp;nbsp;hair.render_scene &lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;/home/tux/ruby_sunflow/frame-&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/font&gt;i&lt;font color="#ff6060"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff40ff"&gt;&lt;b&gt;.png&lt;/b&gt;&lt;/font&gt;&lt;font color="#ff6060"&gt;&lt;b&gt;&amp;quot;&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#00ffff"&gt;&lt;b&gt;# default is to render in sunflow frame ie not to file&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffff00"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-5674638044395019144?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/5674638044395019144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/creating-simple-animations-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5674638044395019144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5674638044395019144'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/creating-simple-animations-using.html' title='Creating simple animations using the SunflowAPIAPI library and jruby'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-4718678914666168456</id><published>2010-10-03T14:33:00.007+01:00</published><updated>2010-10-03T16:07:17.302+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tune ups'/><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sunflow raytracing'/><title type='text'>Performance tune-ups (or not) for jruby sunflow raytracing</title><content type='html'>When I realised that sunflow is multi-threaded I thought there may be some performance tune-ups possible.&lt;br /&gt;&lt;br /&gt;These are the steps I tried:-&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I've updated my sunflow to use the latest janino compiler, only a small amount of re-factoring was required essentially deprecating two types of error and revising one because it has been re-factored to the commons-compiler.&lt;/li&gt;&lt;li&gt;I'm using the --server option&lt;/li&gt;&lt;li&gt;I'm using the --fast option&lt;/li&gt;&lt;li&gt;I've increased the heap space -J-Xmx1024m&lt;/li&gt;&lt;li&gt;I've enabled thread pooling -J-Djruby.thread.pooling=true&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I'm not sure what effect if any updating the janino compiler has but to my mind it makes the application a bit more future-proof (there is the option to upgrade from java 1.4 syntax see janino web site). The windows 0.073 version of sunflow is claimed to be faster on the basis of a native compiler, I doubt it.&lt;br /&gt;&lt;br /&gt;Using the server option is a good thing, regular java uses it by default, I'm not sure about jruby. Because --server is a proxy for -J-server, suggest to me that you may need this option since it has been made easier to use?&lt;br /&gt;&lt;br /&gt;Using the --fast option ensures pre-compilation (amongst other speed-ups) which must be good thing here?&lt;br /&gt;&lt;br /&gt;Allocating increased memory is the only thing the sunflow.sh script does. Running the sunflow.jar directly (java -jar sunflow.jar) requests &gt; 800 mb heap space to run.  &lt;br /&gt;&lt;br /&gt;The thread pooling is used to prevent wasteful ruby green threads being spawned. Both cores on my dual core linux box were kept running flat out according to my conky readout.&lt;br /&gt;&lt;br /&gt;Now the difference between none of these measures, and running with the speed-ups &lt;i&gt;seemed&lt;/i&gt; to be noticeable, so I thought I would measure it?&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Conclusion&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;Now I've done a bit of measurement I'm not so sure perhaps it was the janino compiler change after all?&lt;br /&gt;&lt;br /&gt;The --server command certainly makes no difference for me, default is --server.&lt;br /&gt;&lt;br /&gt;Well it turns out it is all in the imagination when I measured the different compilers with or without any "performance" options performance was much the same...&lt;br /&gt;&lt;br /&gt;However I was very impressed with the new &lt;a href="http://martinpblogformasswritingproject.blogspot.com/2010/10/ray-tracer-in-structuresynth.html"&gt;StructureSynth&lt;/a&gt; built in ray tracing facility, which has apparently been been built with efficiency in mind, the default setting is for 4 processors (2 real, 2 virtual). Apparently povray lags behind in that regard?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-4718678914666168456?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/4718678914666168456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/performance-tune-ups-for-jruby-sunflow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4718678914666168456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4718678914666168456'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/performance-tune-ups-for-jruby-sunflow.html' title='Performance tune-ups (or not) for jruby sunflow raytracing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-7868784207243284368</id><published>2010-10-01T10:58:00.002+01:00</published><updated>2010-10-02T11:09:00.763+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sunflowAPIAPI'/><title type='text'>SunflowAPIAPI test example using jruby</title><content type='html'>See &lt;a href="http://learning-ruby-processing.blogspot.com/2010/09/sunflowapiapi-in-ruby-processing.html"&gt;previous post&lt;/a&gt; for how to setup java libraries. If you are mad like me, and have updated sunflow to use the latest janino compiler you should require the commons-compiler.jar as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# sunflow_test.rb NB: run this script directly with jruby&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;library/sunflow_api/library/sunflow_api.jar&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;library/sunflow/library/sunflow.jar&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;require&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;library/sunflow/library/janino.jar&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;SunflowTest&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Com&lt;/b&gt;&lt;/span&gt;::briansteen::&lt;span style="color: lime;"&gt;&lt;b&gt;SunflowAPIAPI&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Org&lt;/b&gt;&lt;/span&gt;::sunflow::math&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:sunflow&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;&amp;nbsp;width = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/span&gt;, height = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.set_width(width)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.set_height(height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.set_camera_position(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2.5&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.set_camera_target(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.set_thinlens_camera(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;thinLensCamera&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;, width/height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;create_scene&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.draw_plane(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;ground&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.5&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.draw_sphere_flake(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;mySphereFlake&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;render_scene&lt;/b&gt;&lt;/span&gt;&amp;nbsp;filename = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.setPathTracingGIEngine &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# render&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.render &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;filename&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;filename&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# test for dodgy filename/path&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;file = &lt;span style="color: lime;"&gt;&lt;b&gt;File&lt;/b&gt;&lt;/span&gt;.new(filename, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;w&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;file.close&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sunflow.render(filename) &lt;span style="color: cyan;"&gt;&lt;b&gt;# save as png image&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;rescue&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;puts &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Warning &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;filename&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;is not writable&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;test = &lt;span style="color: lime;"&gt;&lt;b&gt;SunflowTest&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;test.create_scene&lt;br /&gt;test.render_scene&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-7868784207243284368?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/7868784207243284368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/sunflowapiapi-test-example-using-jruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7868784207243284368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7868784207243284368'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/10/sunflowapiapi-test-example-using-jruby.html' title='SunflowAPIAPI test example using jruby'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-6506895389742055881</id><published>2010-09-30T21:51:00.008+01:00</published><updated>2010-10-01T20:48:19.429+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sunflowAPIAPI'/><title type='text'>Basic Hair Example SunflowAPIAPI just using jruby</title><content type='html'>It occurred to me that all I was getting from using ruby-processing in my previous post was the ruby processing interface to the libraries. So here is the straightforward jruby version....&lt;br /&gt;Screen output very much as before (smaller) hence not included there. For your convenience I present an embedded gist (click on view raw to copy).&lt;br /&gt;See &lt;a href="http://learning-ruby-processing.blogspot.com/2010/09/sunflowapiapi-in-ruby-processing.html"&gt;previous post&lt;/a&gt; for how to setup java libraries.&lt;br /&gt;Example translated from java version (by Christopher Warnow?) included in the subversion checkout of the sunflowAPIAPI.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/605984.js?file=sunflow_hair.rb"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-6506895389742055881?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/6506895389742055881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/basic-hair-example-sunflowapiapi-just.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6506895389742055881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6506895389742055881'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/basic-hair-example-sunflowapiapi-just.html' title='Basic Hair Example SunflowAPIAPI just using jruby'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-3785269152498896329</id><published>2010-09-30T16:58:00.006+01:00</published><updated>2010-10-01T16:49:53.425+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sunflowAPIAPI'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><title type='text'>Basic Hair Example SunflowAPIAPI in ruby processing</title><content type='html'>See &lt;a href="http://learning-ruby-processing.blogspot.com/2010/09/sunflowapiapi-in-ruby-processing.html"&gt;previous post&lt;/a&gt; for how to setup java libraries.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# basic_hair.rb run with 'rp5 run script.rb'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;BasicHair&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:sunflow_api&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:sunflow&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;com.briansteen&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;org.sunflow.math&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;java.awt&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Com&lt;/b&gt;&lt;/span&gt;::briansteen::&lt;span style="color: lime;"&gt;&lt;b&gt;SunflowAPIAPI&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Org&lt;/b&gt;&lt;/span&gt;::sunflow::math&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= java.awt.Color&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;WIDTH&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;640&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;HEIGHT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;480&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;P_AMOUNT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# create a new API instance&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set width and height&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_width(&lt;span style="color: lime;"&gt;&lt;b&gt;WIDTH&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_height(&lt;span style="color: lime;"&gt;&lt;b&gt;HEIGHT&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set background color&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_background(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set camera&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_camera_position(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_camera_target(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_thinlens_camera(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;thinLensCamera&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;WIDTH&lt;/b&gt;&lt;/span&gt;/&lt;span style="color: lime;"&gt;&lt;b&gt;HEIGHT&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set basic light&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_point_light(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;myPointLight&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_directional_light(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;myDirectionalLight&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/span&gt;.new(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# @sunflow.setSphereLight("mySphereLight", SMath::Point3.new(0, 30, -5), &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# JColor.new(0, 0, 255), 32, 10)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# draw a ground plane&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.draw_plane(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;ground&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;))&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# coordinates array &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_widths = [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.025&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.draw_box(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;boxname&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# create particle coordinates&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;350&lt;/b&gt;&lt;/span&gt;.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;j&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# particle start position&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_x = &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.cos(j*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;)*j*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.0015&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_y = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_z = &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(j*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;)*j*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.0015&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates = &lt;span style="color: lime;"&gt;&lt;b&gt;Array&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: lime;"&gt;&lt;b&gt;P_AMOUNT&lt;/b&gt;&lt;/span&gt;*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;array_index = -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;P_AMOUNT&lt;/b&gt;&lt;/span&gt;.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_x += &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.cos(i * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.15&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ j*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.05&lt;/b&gt;&lt;/span&gt;) * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.13&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_y -= &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(particle_z*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ j*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.05&lt;/b&gt;&lt;/span&gt;)*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.125&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.cos(i*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ particle_y)*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.125&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;particle_z += &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(i)*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.25&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ particle_y*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates[array_index += &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;] = particle_x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates[array_index += &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;] = particle_y&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_coordinates[array_index += &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;] = particle_z&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set ambient occlusion shader&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.setAmbientOcclusionShader(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;myAmbientOcclusionShader&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;j&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;55&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;55&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;55&lt;/b&gt;&lt;/span&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;JColor&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;16&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set glass shader&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# @sunflow.setGlassShader("myGlassShader", JColor.new(1,1,1), 2.5, 3, JColor.new(1,1,1))&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# set shiny-diffuse shader&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# @sunflow.setShinyDiffuseShader("myShinyShader", JColor.new(55,55,55), 0.8)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# draw object&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.drawHair(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;hair&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;j&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;P_AMOUNT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, hair_coordinates.to_java(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:float&lt;/b&gt;&lt;/span&gt;), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair_widths.to_java(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:float&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.setIrradianceCacheGIEngine(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;32&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.4&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;15&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# render&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.render() &lt;span style="color: cyan;"&gt;&lt;b&gt;# display in sunflow window&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# @sunflow.render("BasicHair.png") # save as png image&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: yellow;"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_DUDH0kznFTA/TKS0cQP3ekI/AAAAAAAAC-w/8aX8aNosWKA/s1600/BasicHair.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://2.bp.blogspot.com/_DUDH0kznFTA/TKS0cQP3ekI/AAAAAAAAC-w/8aX8aNosWKA/s400/BasicHair.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-3785269152498896329?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/3785269152498896329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/basic-hair-example-sunflowapiapi-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/3785269152498896329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/3785269152498896329'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/basic-hair-example-sunflowapiapi-in.html' title='Basic Hair Example SunflowAPIAPI in ruby processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_DUDH0kznFTA/TKS0cQP3ekI/AAAAAAAAC-w/8aX8aNosWKA/s72-c/BasicHair.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-9217481713291193595</id><published>2010-09-30T12:17:00.013+01:00</published><updated>2010-10-05T07:55:30.907+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sunflow'/><category scheme='http://www.blogger.com/atom/ns#' term='sunflowAPIAPI'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><title type='text'>SunflowAPIAPI in ruby processing</title><content type='html'>&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# sunflow_test.rb&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;SunflowTest&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:sunflow_api&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:sunflow&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;com.briansteen&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;org.sunflow.math&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Com&lt;/b&gt;&lt;/span&gt;::briansteen::&lt;span style="color: lime;"&gt;&lt;b&gt;SunflowAPIAPI&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Org&lt;/b&gt;&lt;/span&gt;::sunflow::math&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;WIDTH&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;HEIGHT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;500&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;API&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_width(&lt;span style="color: lime;"&gt;&lt;b&gt;WIDTH&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_height(&lt;span style="color: lime;"&gt;&lt;b&gt;HEIGHT&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_camera_position(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2.5&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_camera_target(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.set_thinlens_camera(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;thinLensCamera&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;WIDTH&lt;/b&gt;&lt;/span&gt;/&lt;span style="color: lime;"&gt;&lt;b&gt;HEIGHT&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.draw_plane(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;ground&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Point3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.5&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.draw_sphere_flake(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;mySphereFlake&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;SMath&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Vector3&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;), &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.setPathTracingGIEngine &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@sunflow&lt;/b&gt;&lt;/span&gt;.render &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;SunflowTestRender.png&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;exit&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: lime;"&gt;&lt;b&gt;SunflowTest&lt;/b&gt;&lt;/span&gt;.new &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:title&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Sunflow Test&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #ff6060; font-family: monospace;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This &lt;a href="http://amnonp5.wordpress.com/2010/09/28/sunflow-processing/"&gt;example&lt;/a&gt; was copied from amnon, following his recent &lt;a href="http://forum.processing.org/#Topic/25080000000244063"&gt;posting&lt;/a&gt; on the processing discussion boards. &lt;br /&gt;&lt;br /&gt;Checkout the sunflowapapi source (created by&amp;nbsp; Christopher Warnow?) as follows:-&lt;br /&gt;svn checkout http://sunflowapiapi.googlecode.com/svn/trunk/ sunflowapiapi-read-only&lt;br /&gt;&lt;br /&gt;Get the sunflow libraries here, NB must be version 0.07.3:-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sunflow.sourceforge.net/"&gt;http://sunflow.sourceforge.net&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Or possible here for Windows users:-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.polyquark.com/opensource/"&gt;http://www.polyquark.com/opensource&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The usual library setup required compile and jar the sunflowapiapi code into sunflow_api.jar nest that as follows in a folder library, in a folder sunflow_api in the library folder (in the directory where the sketch you want to run is stored). Do similar for the sunflow.jar put the janino.jar in the same folder.&amp;nbsp; The janino.jar provides a fast java compiler, version is 2.~ is supplied with the sunflow download, however with a few minor modifications sunflow can be updated to use the &lt;a href="http://docs.codehaus.org/display/JANINO/Home"&gt;latest version 2.6.1&lt;/a&gt; (basically include the commons-compiler.jar, and remove a couple of deprecated exception types from the code and &amp;nbsp;update the CompileException to the commons compiler version org.codehaus.commons.compiler.CompileException, do this in an ide unless you are crazy).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_DUDH0kznFTA/TKRxiuiOm8I/AAAAAAAAC-o/Luo4PdsJtcQ/s1600/SunflowTestRender.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/_DUDH0kznFTA/TKRxiuiOm8I/AAAAAAAAC-o/Luo4PdsJtcQ/s400/SunflowTestRender.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-9217481713291193595?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/9217481713291193595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/sunflowapiapi-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/9217481713291193595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/9217481713291193595'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/sunflowapiapi-in-ruby-processing.html' title='SunflowAPIAPI in ruby processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_DUDH0kznFTA/TKRxiuiOm8I/AAAAAAAAC-o/Luo4PdsJtcQ/s72-c/SunflowTestRender.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-7940872060426242415</id><published>2010-09-26T06:41:00.005+01:00</published><updated>2010-09-26T11:35:04.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Staffordshire Knot'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context free DSL'/><title type='text'>A Staffordshire Knot Using Ruby Processing and A Context Free Library</title><content type='html'>&lt;iframe src="http://player.vimeo.com/video/15292220" width="400" height="300" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/15292220"&gt;A Staffordshire Knot, ruby-processing 3D context-free DSL&lt;/a&gt; from &lt;a href="http://vimeo.com/user4783150"&gt;monkstone&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;Using a slight variation of the previous post we get something similar to the Staffordshire Knot.&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;segment &lt;font color="#ff40ff"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/font&gt;&amp;nbsp;=&amp;gt; i, &lt;font color="#ff40ff"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/font&gt;&amp;nbsp;=&amp;gt; &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.sin(i*&lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/font&gt;/&lt;font color="#ff40ff"&gt;&lt;b&gt;180&lt;/b&gt;&lt;/font&gt;)*&lt;font color="#ff40ff"&gt;&lt;b&gt;0.2&lt;/b&gt;&lt;/font&gt;, &lt;font color="#ff40ff"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/font&gt;&amp;nbsp;=&amp;gt; &lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;.sin(i*&lt;font color="#00ff00"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/font&gt;::&lt;font color="#00ff00"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/font&gt;/&lt;font color="#ff40ff"&gt;&lt;b&gt;180&lt;/b&gt;&lt;/font&gt;)*&lt;font color="#ff40ff"&gt;&lt;b&gt;1.5&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Is the main change, although to produce the video, I was saving frames and set the size to 640*480 to match vimeo preferences. Was very jumpy when I saved frames as #####.png ...&lt;br /&gt;&lt;br /&gt;I have since uploaded an improved version, this time using the default save_frame (hence tif format). Mencoder doesn't like this format so I batch converted the tif files to png as so:-&lt;br /&gt;&lt;br /&gt;mogrify -format png -transparent blue *.tif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;See my processing &lt;a href="http://martinpblogformasswritingproject.blogspot.com/2010/09/finally-got-round-to-animating-my-fiery.html"&gt;blog&lt;/a&gt; for the video recording details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-7940872060426242415?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/7940872060426242415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/staffordshire-knot-using-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7940872060426242415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7940872060426242415'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/staffordshire-knot-using-ruby.html' title='A Staffordshire Knot Using Ruby Processing and A Context Free Library'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-1084609563946335970</id><published>2010-09-25T21:40:00.000+01:00</published><updated>2010-09-25T21:40:50.221+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loop'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='infinity'/><category scheme='http://www.blogger.com/atom/ns#' term='3D context free DSL'/><title type='text'>An Infinity Loop? With My 3D Context Free Library</title><content type='html'>&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# infinity.rb &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# An 'infinity loop?' &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:test_free&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;full_screen&lt;br /&gt;&lt;br /&gt;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:wheel&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:col&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_the_spiral&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.define &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:infinity&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;360&lt;/b&gt;&lt;/span&gt;.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;split &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;segment &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; i, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(i*&lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;180&lt;/b&gt;&lt;/span&gt;)*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.cos(i*&lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;180&lt;/b&gt;&lt;/span&gt;)*&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewind&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:segment&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cube &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:segment&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cube &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;render_mode &lt;span style="color: lime;"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@wheel&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;JWheelListener&lt;/b&gt;&lt;/span&gt;.new(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# initialize listener with start_z and maximum values&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.add_mouse_wheel_listener(wheel)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# register the mouse listener&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@xrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@col&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;setup_the_spiral&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;setup_lights col&lt;br /&gt;&amp;nbsp;&amp;nbsp;specular col, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;emissive &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.05&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;shininess &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth_rotation(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.2&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth_color(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.render &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:infinity&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; wheel.zoom, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;350&lt;/b&gt;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.7&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.7&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; xrot, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; yrot, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; zrot&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Generate a gradient value that changes smoothly over time in the range [ 0, 1 ].&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The Math.sin() function is used to map the current time in milliseconds somewhere&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# in the range [ 0, 1 ]. A 'speed' factor is specified by the parameters s1.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;smooth_gradient&lt;/b&gt;&lt;/span&gt;(s1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;mills = millis * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.00003&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;gradient = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(mills * s1) + &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Rotate the current coordinate system.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Uses smooth_gradient() to smoothly animate the rotation.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;smooth_rotation&lt;/b&gt;&lt;/span&gt;(s1, s2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2.0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* smooth_gradient(s1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2.0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* smooth_gradient(s2)&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Generate a 'hue' value which smoothly changes over time.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The speed of change is controlled by the parameter s1.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;smooth_color&lt;/b&gt;&lt;/span&gt;(s1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@col&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= smooth_gradient(s1)&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_lights&lt;/b&gt;&lt;/span&gt;(col)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;directional_light(col, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;point_light(col, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ambient_light(col, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_DUDH0kznFTA/TJ5dWR2ercI/AAAAAAAAC-E/YesQVQBWff8/s1600/frame25.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="188" src="http://1.bp.blogspot.com/_DUDH0kznFTA/TJ5dWR2ercI/AAAAAAAAC-E/YesQVQBWff8/s200/frame25.png" width="200" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_DUDH0kznFTA/TJ5dbDgZhmI/AAAAAAAAC-I/Lfx9usGzhfM/s1600/frame83.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_DUDH0kznFTA/TJ5dbDgZhmI/AAAAAAAAC-I/Lfx9usGzhfM/s200/frame83.png" width="165" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_DUDH0kznFTA/TJ5dfgYRSGI/AAAAAAAAC-M/6s4-zNowBgk/s1600/frame157.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="190" src="http://2.bp.blogspot.com/_DUDH0kznFTA/TJ5dfgYRSGI/AAAAAAAAC-M/6s4-zNowBgk/s200/frame157.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-1084609563946335970?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/1084609563946335970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/infinity-loop-with-my-3d-context-free.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1084609563946335970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1084609563946335970'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/infinity-loop-with-my-3d-context-free.html' title='An Infinity Loop? With My 3D Context Free Library'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_DUDH0kznFTA/TJ5dWR2ercI/AAAAAAAAC-E/YesQVQBWff8/s72-c/frame25.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-6124023685674703182</id><published>2010-09-13T16:35:00.010+01:00</published><updated>2010-10-13T20:24:54.665+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mouse wheel listener'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context free'/><title type='text'>Revised 3D Context Free DSL Sketch, with Mouse Wheel Zoom Utility</title><content type='html'>I demonstrate the new feature of mouse wheel zoom in this sketch. The logic for the smooth of color and rotation I copied from lazydogs classy rotating ball. PS: if you can't see the embedded code below chances are you are not using either Firefox or Google Chrome browser (doesn't always work for me with Opera, which I also find is awkward to use when copying code).&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/571495.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_DUDH0kznFTA/TI5HOWJgiOI/AAAAAAAAC9o/hlXPAsT1LSs/s1600/elephant.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_DUDH0kznFTA/TI5HOWJgiOI/AAAAAAAAC9o/hlXPAsT1LSs/s320/elephant.png" width="310" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://player.vimeo.com/video/15807404" width="400" height="300" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/15807404"&gt;default.rb&lt;/a&gt; from &lt;a href="http://vimeo.com/user4783150"&gt;monkstone&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-6124023685674703182?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/6124023685674703182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/colorful-3d-context-free-dsl-with-mouse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6124023685674703182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6124023685674703182'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/colorful-3d-context-free-dsl-with-mouse.html' title='Revised 3D Context Free DSL Sketch, with Mouse Wheel Zoom Utility'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_DUDH0kznFTA/TI5HOWJgiOI/AAAAAAAAC9o/hlXPAsT1LSs/s72-c/elephant.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-4597425140587027070</id><published>2010-09-12T15:12:00.001+01:00</published><updated>2010-09-12T15:13:51.266+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mouse_wheel_listener'/><category scheme='http://www.blogger.com/atom/ns#' term='zoom'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><title type='text'>A Mouse Wheel Listener in Ruby Processing</title><content type='html'>For my 3D context free application/library, I would like to be able to zoom using the mouse wheel, I had vaguely thought about using peasycam or proscene to provide that, and other functionality. In the first instance I wanted to create it myself. After a bit of research, this the sort of implementation I would do using the java classes/interfaces in ruby:-&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# mouse_listener.rb&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;JWheelListener&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;include&lt;/b&gt;&lt;/span&gt;&amp;nbsp;java.awt.event.MouseWheelListener&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zoom&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;(zoom)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zoom&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= zoom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;mouse_wheel_moved&lt;/b&gt;&lt;/span&gt;(e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zoom&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+= e.get_wheel_rotation * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Mouse&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:wheel&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1000&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1000&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@wheel&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;JWheelListener&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.add_mouse_wheel_listener(&lt;span style="color: cyan;"&gt;&lt;b&gt;@wheel&lt;/b&gt;&lt;/span&gt;)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fill &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;255&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ellipse(width/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, wheel.zoom, wheel.zoom)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: lime;"&gt;&lt;b&gt;Mouse&lt;/b&gt;&lt;/span&gt;.new &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:title&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Mouse Wheel Listener&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_DUDH0kznFTA/TIzftCvI6qI/AAAAAAAAC9Y/-S-ZsUWnj0E/s1600/wheel.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_DUDH0kznFTA/TIzftCvI6qI/AAAAAAAAC9Y/-S-ZsUWnj0E/s320/wheel.png" width="315" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-4597425140587027070?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/4597425140587027070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/mouse-wheel-listener-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4597425140587027070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4597425140587027070'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/mouse-wheel-listener-in-ruby-processing.html' title='A Mouse Wheel Listener in Ruby Processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_DUDH0kznFTA/TIzftCvI6qI/AAAAAAAAC9Y/-S-ZsUWnj0E/s72-c/wheel.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-6071374711416550660</id><published>2010-09-11T08:18:00.006+01:00</published><updated>2010-09-11T11:41:04.406+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='3D'/><category scheme='http://www.blogger.com/atom/ns#' term='screen saver'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context free DSL'/><title type='text'>3D Context Free DSL Screen Saver?</title><content type='html'>Here is an animated version of the default.es from StructureSynth in ruby-processing. Mac or windows users might want to experiment with OPENGL rendering, as this sketch exposes errors in processing P3D, I see odd missing pixels from time to time. If you don't like the holes remove the smooth, personally I prefer the holes to the glitchty non-smooth (&lt;i&gt;it is a known issue with current versions of processing with both P2D and P3D renderers, something to do with tessellation algorithms&lt;/i&gt;). &amp;nbsp;The test_free library is as in &lt;a href="http://learning-ruby-processing.blogspot.com/2010/09/translating-defaultes-to-ruby.html"&gt;previous post&lt;/a&gt;.&lt;br /&gt;Nest the library as follows:-&lt;br /&gt;library/test_free/test_free.rb in the folder containing the sketch&lt;br /&gt;For instructions for installing ruby-processing follow the first link in the blog header.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# full_screen.rb &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# An animation of default.es &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# the StructureSynth default script&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:test_free&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;full_screen&lt;br /&gt;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_the_spiral&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.define &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:default&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;split &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewind&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:R1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sphere &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.99&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.25&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:R2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sphere &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.99&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.25&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;render_mode &lt;span style="color: lime;"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@xrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.01&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;setup_the_spiral&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth_rotation(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.7&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;7.3&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.render &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:default&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;350&lt;/b&gt;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; xrot, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; yrot, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; zrot&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Generate a vector whose components change smoothly over time in the range [ 0, 1 ].&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Each component uses a Math.sin() function to map the current time in milliseconds somewhere&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# in the range [ 0, 1 ].A 'speed' factor is specified for each component.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;smooth_vector&lt;/b&gt;&lt;/span&gt;(s1, s2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;mills = millis * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.00003&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;y = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(mills * s1) + &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;z = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;.sin(mills * s2) + &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;vec = [y, z]&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;##&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Rotate the current coordinate system.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Uses smooth_vector() to smoothly animate the rotation.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;smooth_rotation&lt;/b&gt;&lt;/span&gt;(s1, s2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;r1 = smooth_vector(s1, s2) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= (&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2.0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* r1[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zrot&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= (&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2.0&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* &lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* r1[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;])&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_DUDH0kznFTA/TIstF6vv1FI/AAAAAAAAC9Q/o5hKXzUorhc/s1600/full_screen.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="210" src="http://4.bp.blogspot.com/_DUDH0kznFTA/TIstF6vv1FI/AAAAAAAAC9Q/o5hKXzUorhc/s400/full_screen.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-6071374711416550660?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/6071374711416550660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/3d-context-free-dsl-screen-saver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6071374711416550660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/6071374711416550660'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/3d-context-free-dsl-screen-saver.html' title='3D Context Free DSL Screen Saver?'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_DUDH0kznFTA/TIstF6vv1FI/AAAAAAAAC9Q/o5hKXzUorhc/s72-c/full_screen.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-7649670239371065130</id><published>2010-09-09T16:40:00.011+01:00</published><updated>2010-09-16T10:28:59.897+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context free'/><category scheme='http://www.blogger.com/atom/ns#' term='StructureSynth'/><title type='text'>Translating the default.es to ruby processing DSL</title><content type='html'>It was very constructive to see if I could translate the EisenScript to my ruby processing DSL, I immediately learnt something about the EisenScript (recursion seems to be implicit, something I had not understood before). What I learnt about my library, was I was losing some context by directly altering the attitude (the image expected from the EisenScript appeared  briefly but quickly degraded). I have now re-factored the sketch to only adjust the initial angle, the x rotation seems to affect the amplitude of deformation from the plane of the spirals. The y and z rotation give control of the attitude, and need to be used in combination to fully explore the 3 dimensional shape, which is now somewhat like that produced by StrucureSynth.&amp;nbsp;  &lt;br /&gt;&lt;br /&gt;Here is my revised 3d context free DSL (&lt;i&gt;&lt;b&gt;test_free.rb&lt;/b&gt;&lt;/i&gt;):-&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# A Context-Free library for Ruby-Processing, inspired by&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# contextfreeart.org and StructureSynth&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Built on Jeremy Ashkenas context free DSL script &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;module&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;include&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Proxy&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_accessor&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rules&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:app&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xr&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yr&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zr&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;AVAILABLE_OPTIONS&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:hue&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;HSB_ORDER&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = {&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:hue&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Define a context-free system. Use this method to create a ContextFree&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# object. Call render() on it to make it draw.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.&lt;span style="color: cyan;"&gt;&lt;b&gt;define&lt;/b&gt;&lt;/span&gt;(&amp;amp;block)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cf = &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cf.instance_eval &amp;amp;block&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cf&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Initialize a bare ContextFree object with empty recursion stacks.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;= &lt;span style="color: cyan;"&gt;&lt;b&gt;$app&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@graphics&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &lt;span style="color: cyan;"&gt;&lt;b&gt;$app&lt;/b&gt;&lt;/span&gt;.g&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@finished&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;= {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rewind_stack&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= []&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@matrix_stack&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= []&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@xr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Create an accessor for the current value of every option. We use a values&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# object so that all the state can be saved and restored as a unit.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;AVAILABLE_OPTIONS&lt;/b&gt;&lt;/span&gt;.each &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;option_name&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;define_method option_name &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[option_name]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Here's the first serious method: A Rule has an&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# identifying name, a probability, and is associated with&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# a block of code. These code blocks are saved, and indexed&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# by name in a hash, to be run later, when needed.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The method then dynamically defines a method of the same&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# name here, in order to determine which rule to run.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rule&lt;/b&gt;&lt;/span&gt;(rule_name, prob=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &amp;amp;proc)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name] ||= {&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:procs&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [], &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total = &lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:procs&lt;/b&gt;&lt;/span&gt;] &amp;lt;&amp;lt; [(total...(prob+total)), &lt;span style="color: yellow;"&gt;&lt;b&gt;proc&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;] += prob&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.method_defined? rule_name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.class.class_eval &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;eval&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;-&lt;span style="color: #ff6060;"&gt;&lt;b&gt;METH&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;rule_name&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;(options)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_options(@values, options)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pick = determine_rule(&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;rule_name.inspect&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@finished = true if @values[:size] &amp;lt; @values[:stop_size]&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unless @finished&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get_ready_to_draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pick[1].call(options)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;METH&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Rule choice is random, based on the assigned probabilities.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;determine_rule&lt;/b&gt;&lt;/span&gt;(rule_name)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = &lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;chance = rand * rule[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pick = &lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:procs&lt;/b&gt;&lt;/span&gt;].select {|&lt;span style="color: cyan;"&gt;&lt;b&gt;the_proc&lt;/b&gt;&lt;/span&gt;|&amp;nbsp;the_proc[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;].include?(chance) }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;pick.flatten&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# At each step of the way, any of the options may change, slightly.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Many of them have different strategies for being merged.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;merge_options&lt;/b&gt;&lt;/span&gt;(old_ops, new_ops)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;new_ops&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Do size first&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;] *= new_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;] &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;new_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new_ops.each &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;key&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: cyan;"&gt;&lt;b&gt;value&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] = value * old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] = value * (&lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;/ &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;180.0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:hue&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted = old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;].dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted[&lt;span style="color: lime;"&gt;&lt;b&gt;HSB_ORDER&lt;/b&gt;&lt;/span&gt;[key]] *= value &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;] = adjusted&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:width&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:height&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] *= value &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] = value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Used a key that we don't know about or trying to set&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_unknown_key(key, value, old_ops)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Using an unknown key let's you set arbitrary values,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# to keep track of for your own ends.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;merge_unknown_key&lt;/b&gt;&lt;/span&gt;(key, value, old_ops)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key_s = key.to_s&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key_s.match(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;^&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;set&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key_sym = key_s.sub(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;set_&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;''&lt;/b&gt;&lt;/span&gt;).to_sym&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key_s.match(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;brightness&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;hue&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;saturation&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;alpha&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted = old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;].dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted[&lt;span style="color: lime;"&gt;&lt;b&gt;HSB_ORDER&lt;/b&gt;&lt;/span&gt;[key_sym]] = value &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;] = adjusted&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key_sym] = value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Doing a 'split' saves the context, and proceeds from there,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# allowing you to rewind to where you split from at any moment.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;split&lt;/b&gt;&lt;/span&gt;(options=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;, &amp;amp;block)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;save_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_options(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;, options) &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;options&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;yield&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;restore_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Saving the context means the values plus the coordinate matrix.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;save_context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rewind_stack&lt;/b&gt;&lt;/span&gt;.push &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;.dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@matrix_stack&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt; &lt;span style="color: cyan;"&gt;&lt;b&gt;@graphics&lt;/b&gt;&lt;/span&gt;.get_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Restore the values and the coordinate matrix as the recursion unwinds.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;restore_context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: cyan;"&gt;&lt;b&gt;@rewind_stack&lt;/b&gt;&lt;/span&gt;.pop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@graphics&lt;/b&gt;&lt;/span&gt;.set_matrix &lt;span style="color: cyan;"&gt;&lt;b&gt;@matrix_stack&lt;/b&gt;&lt;/span&gt;.pop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Rewinding goes back one step.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rewind&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@finished&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;restore_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;save_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Render the is method that kicks it all off, initializing the options&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# and calling the first rule.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;render&lt;/b&gt;&lt;/span&gt;(rule_name, starting_values={})&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= {&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:width&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:height&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; width/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.5&lt;/b&gt;&lt;/span&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;.merge!(starting_values)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@finished&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.reset_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.no_stroke&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.color_mode &lt;span style="color: lime;"&gt;&lt;b&gt;HSB&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.translate &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.send(rule_name, {})&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rotate_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@xr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rotate_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rotate_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Before actually drawing the next step, we need to move to the appropriate&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# location.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;get_ready_to_draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.translate(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;] + xr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;] + yr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;] + zr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Compute the rendering parameters for drawing a shape.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;get_shape_values&lt;/b&gt;&lt;/span&gt;(some_options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops = &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;.dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_options(old_ops, some_options) &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;some_options&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.fill *old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;], old_ops&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Sphere, cube are the primitive drawing&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;cube&lt;/b&gt;&lt;/span&gt;(some_options=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size, options = *get_shape_values(some_options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotz = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;roty = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotx = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x rotx &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y roty &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z rotz &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.translate(options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;* size, options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;] * size , options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;* size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.box(size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotz) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# unwind rotations in an oredered way&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* roty) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotx) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;sphere&lt;/b&gt;&lt;/span&gt;(some_options=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size, options = *get_shape_values(some_options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotz = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;roty = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotx = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x rotx &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y roty &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z rotz &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.sphere_detail &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.sphere(size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotz) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# unwind rotations in an oredered way&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* roty) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotx) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My Translation of default.es to ruby processing&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# default.rb &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# virtually a direct translation of default.es &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# the StructureSynth default script&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:test_free&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:control_panel&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:amplitude&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_the_spiral&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.define &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:default&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;split &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewind&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:R1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sphere &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.99&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.25&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:R2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sphere &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;R2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.99&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.25&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;configure_control&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# setup control panel gui&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;control_panel &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;c&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.title = &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Amplitude+Attitude&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:amplitude&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.025&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.015&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.3&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.005&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.3&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6.3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.005&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;size &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;800&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;800&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;configure_control&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth&lt;br /&gt;&amp;nbsp;&amp;nbsp;setup_the_spiral&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.render &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:default&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;40&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;400&lt;/b&gt;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; amplitude, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; yrot, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt; =&amp;gt; zrot&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_DUDH0kznFTA/TIk3mRK-mnI/AAAAAAAAC9I/SP_EbuuS6Jo/s1600/control.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_DUDH0kznFTA/TIk3mRK-mnI/AAAAAAAAC9I/SP_EbuuS6Jo/s320/control.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_DUDH0kznFTA/TIk3jtIS6tI/AAAAAAAAC9A/JQMUjv7N3_k/s1600/default.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_DUDH0kznFTA/TIk3jtIS6tI/AAAAAAAAC9A/JQMUjv7N3_k/s320/default.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_DUDH0kznFTA/TIk3fysdxZI/AAAAAAAAC84/bD4MOOHHbB0/s1600/deafult.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_DUDH0kznFTA/TIk3fysdxZI/AAAAAAAAC84/bD4MOOHHbB0/s320/deafult.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-7649670239371065130?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/7649670239371065130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/translating-defaultes-to-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7649670239371065130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/7649670239371065130'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/translating-defaultes-to-ruby.html' title='Translating the default.es to ruby processing DSL'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_DUDH0kznFTA/TIk3mRK-mnI/AAAAAAAAC9I/SP_EbuuS6Jo/s72-c/control.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-4797069187882643484</id><published>2010-09-09T15:22:00.004+01:00</published><updated>2010-09-09T15:32:47.649+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='3D'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context free'/><title type='text'>Testing the cube primitive in my context free DSL</title><content type='html'>Another context free DSL example, better annotated, control panel and library as previous post (&lt;i&gt;not shown&lt;/i&gt;):-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# cube.rb&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:test_free&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:control_panel&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_the_spiral&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.define &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# define the cf rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cubeform&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;split &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# record the context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cuby &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;72&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* i &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewind&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# restore the context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:beam&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt;.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;split &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# record the context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cube &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.2&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* i&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewind&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# restore the context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cuby&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;beam &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cuby &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.98&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.24&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# recursive call ends when size &amp;lt; 1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# static setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;size &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;800&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;800&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# I can only use P3D (unless full_screen) on linux opengl might work on mac/windows&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;configure_control&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth&lt;br /&gt;&amp;nbsp;&amp;nbsp;setup_the_spiral&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;configure_control&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# setup control panel gui&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;control_panel &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;c&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.title = &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Attitude Control&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# animation loop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.render &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cubeform&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;30&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;300&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.rotate_x xrot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.rotate_y yrot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.rotate_z zrot&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_DUDH0kznFTA/TIjtPBLXr-I/AAAAAAAAC8o/BDyx53F0LMw/s1600/cuby.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_DUDH0kznFTA/TIjtPBLXr-I/AAAAAAAAC8o/BDyx53F0LMw/s320/cuby.png" width="312" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Within the sketch :hue, :saturation and :brightness can be individually set. If you want to use :alpha, initialize :color with a 4 dimension array. Note, the color mode in the ruleset is hsb with range 0 .. 1.0. Increment and decrement is linear cf size where it is multiplicative.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-4797069187882643484?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/4797069187882643484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/testing-cube-primitive-in-my-context.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4797069187882643484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/4797069187882643484'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/testing-cube-primitive-in-my-context.html' title='Testing the cube primitive in my context free DSL'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_DUDH0kznFTA/TIjtPBLXr-I/AAAAAAAAC8o/BDyx53F0LMw/s72-c/cuby.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-5816154260347737468</id><published>2010-09-08T22:39:00.018+01:00</published><updated>2010-09-09T12:05:11.459+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='3D'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='context free'/><title type='text'>Experimental 3D Context Free DSL in ruby-processing, a bit of a monster?</title><content type='html'>This is at fairly experimental stage, I need to decide how to order rotations/translations. At the moment order is fixed by the library script, so it doesn't matter what order they are entered you get the default order!!!&lt;br /&gt;&lt;br /&gt;This library cannot compete with StructureSynth which is a much more refined and complete program. However if you are used to ruby it may be easier to write your rules in ruby, rather than in the EisenScript syntax. The funky extra thing is, because it is based on processing you have the animation possibilities of the 'draw' loop. My monster in some directions could be seen as a beating heart.&lt;br /&gt;&lt;br /&gt;To use the library, create a folder for you work say "&lt;i&gt;work&lt;/i&gt;", create a sub-folder "&lt;i&gt;library&lt;/i&gt;" and sub-sub-folder "&lt;i&gt;test_free&lt;/i&gt;" (or whatever better name you can think of for the library). Put the library "&lt;i&gt;test_free.rb&lt;/i&gt;" in the sub-sub-folder. Write you sketches in the "&lt;i&gt;work&lt;/i&gt;" directory, and run them with "&lt;i&gt;rp5 run my_sketch.rb&lt;/i&gt;". If you want to do it the really neat way use JEdit as your editor and my &lt;a href="http://learning-ruby-processing.blogspot.com/2010/04/live-editing-ruby-processing-from-jedit.html"&gt;macro and commando tools&lt;/a&gt;, then you can run the sketch from the editor. The link to the tools describes live editing, which I haven't tried with this library so I would recommend just using the run mode for now. &lt;br /&gt;&lt;br /&gt;If you are not a ruby meddler just get &lt;a href="http://structuresynth.sourceforge.net/"&gt;StructureSynth&lt;/a&gt;, and learn the EisenScript language. Otherwise you will need to get ruby-processing see link in my blog header to see how. My blog header also has link to the original Jeremy Ashkenas context-free.rb on github.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The test_free.rb library&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# A Context-Free library for Ruby-Processing, inspired by&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# contextfreeart.org and StructureSynth&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Built on Jeremy Ashkenas context free DSL script &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;module&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;include&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;Proxy&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_accessor&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rules&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:app&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xr&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yr&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zr&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;AVAILABLE_OPTIONS&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:hue&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;HSB_ORDER&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = {&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:hue&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Define a context-free system. Use this method to create a ContextFree&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# object. Call render() on it to make it draw.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.&lt;span style="color: cyan;"&gt;&lt;b&gt;define&lt;/b&gt;&lt;/span&gt;(&amp;amp;block)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cf = &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cf.instance_eval &amp;amp;block&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cf&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Initialize a bare ContextFree object with empty recursion stacks.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;initialize&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;= &lt;span style="color: cyan;"&gt;&lt;b&gt;$app&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@graphics&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &lt;span style="color: cyan;"&gt;&lt;b&gt;$app&lt;/b&gt;&lt;/span&gt;.g&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@finished&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;= {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rewind_stack&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= []&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@matrix_stack&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= []&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@xr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Create an accessor for the current value of every option. We use a values&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# object so that all the state can be saved and restored as a unit.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;AVAILABLE_OPTIONS&lt;/b&gt;&lt;/span&gt;.each &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;option_name&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;define_method option_name &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[option_name]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Here's the first serious method: A Rule has an&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# identifying name, a probability, and is associated with&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# a block of code. These code blocks are saved, and indexed&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# by name in a hash, to be run later, when needed.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The method then dynamically defines a method of the same&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# name here, in order to determine which rule to run.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rule&lt;/b&gt;&lt;/span&gt;(rule_name, prob=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &amp;amp;proc)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name] ||= {&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:procs&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [], &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total = &lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:procs&lt;/b&gt;&lt;/span&gt;] &amp;lt;&amp;lt; [(total...(prob+total)), &lt;span style="color: yellow;"&gt;&lt;b&gt;proc&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;] += prob&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.method_defined? rule_name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.class.class_eval &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;eval&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt;-&lt;span style="color: #ff6060;"&gt;&lt;b&gt;METH&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def &lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;rule_name&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;(options)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_options(@values, options)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pick = determine_rule(&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;#{&lt;/b&gt;&lt;/span&gt;rule_name.inspect&lt;span style="color: #ff6060;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@finished = true if @values[:size] &amp;lt; @values[:stop_size]&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unless @finished&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get_ready_to_draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pick[1].call(options)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;METH&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Rule choice is random, based on the assigned probabilities.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;determine_rule&lt;/b&gt;&lt;/span&gt;(rule_name)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule = &lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;chance = rand * rule[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:total&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pick = &lt;span style="color: cyan;"&gt;&lt;b&gt;@rules&lt;/b&gt;&lt;/span&gt;[rule_name][&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:procs&lt;/b&gt;&lt;/span&gt;].select {|&lt;span style="color: cyan;"&gt;&lt;b&gt;the_proc&lt;/b&gt;&lt;/span&gt;|&amp;nbsp;the_proc[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;].include?(chance) }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;pick.flatten&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# At each step of the way, any of the options may change, slightly.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Many of them have different strategies for being merged.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;merge_options&lt;/b&gt;&lt;/span&gt;(old_ops, new_ops)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;new_ops&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Do size first&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;] *= new_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;] &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;new_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new_ops.each &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;key&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: cyan;"&gt;&lt;b&gt;value&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] = value * old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] = value * (&lt;span style="color: lime;"&gt;&lt;b&gt;Math&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;PI&lt;/b&gt;&lt;/span&gt;&amp;nbsp;/ &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;180.0&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:hue&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:saturation&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:alpha&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted = old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;].dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted[&lt;span style="color: lime;"&gt;&lt;b&gt;HSB_ORDER&lt;/b&gt;&lt;/span&gt;[key]] *= value &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;] = adjusted&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:width&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:height&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] *= value &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;when&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key] = value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Used a key that we don't know about or trying to set&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_unknown_key(key, value, old_ops)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Using an unknown key let's you set arbitrary values,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# to keep track of for your own ends.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;merge_unknown_key&lt;/b&gt;&lt;/span&gt;(key, value, old_ops)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key_s = key.to_s&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key_s.match(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;^&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;set&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key_sym = key_s.sub(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;set_&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff6060;"&gt;&lt;b&gt;''&lt;/b&gt;&lt;/span&gt;).to_sym&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;key_s.match(&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;brightness&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;hue&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;saturation&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;alpha&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted = old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;].dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjusted[&lt;span style="color: lime;"&gt;&lt;b&gt;HSB_ORDER&lt;/b&gt;&lt;/span&gt;[key_sym]] = value &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;] = adjusted&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops[key_sym] = value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Doing a 'split' saves the context, and proceeds from there,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# allowing you to rewind to where you split from at any moment.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;split&lt;/b&gt;&lt;/span&gt;(options=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;, &amp;amp;block)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;save_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_options(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;, options) &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;options&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;yield&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;restore_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Saving the context means the values plus the coordinate matrix.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;save_context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@rewind_stack&lt;/b&gt;&lt;/span&gt;.push &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;.dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@matrix_stack&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt;&amp;lt; &lt;span style="color: cyan;"&gt;&lt;b&gt;@graphics&lt;/b&gt;&lt;/span&gt;.get_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Restore the values and the coordinate matrix as the recursion unwinds.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;restore_context&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: cyan;"&gt;&lt;b&gt;@rewind_stack&lt;/b&gt;&lt;/span&gt;.pop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@graphics&lt;/b&gt;&lt;/span&gt;.set_matrix &lt;span style="color: cyan;"&gt;&lt;b&gt;@matrix_stack&lt;/b&gt;&lt;/span&gt;.pop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Rewinding goes back one step.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rewind&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@finished&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;restore_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;save_context&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Render the is method that kicks it all off, initializing the options&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# and calling the first rule.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;render&lt;/b&gt;&lt;/span&gt;(rule_name, starting_values={})&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= {&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:width&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:height&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; width/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.5&lt;/b&gt;&lt;/span&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;.merge!(starting_values)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@finished&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.reset_matrix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rect_mode &lt;span style="color: lime;"&gt;&lt;b&gt;CENTER&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.ellipse_mode &lt;span style="color: lime;"&gt;&lt;b&gt;CENTER&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.no_stroke&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.color_mode &lt;span style="color: lime;"&gt;&lt;b&gt;HSB&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.translate &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;self&lt;/b&gt;&lt;/span&gt;.send(rule_name, {})&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rotate_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@xr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rotate_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@yr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;rotate_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@zr&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= rt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Before actually drawing the next step, we need to move to the appropriate&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# location.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;get_ready_to_draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.translate(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;], &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;] + xr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;] + yr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z(&lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;] + zr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Compute the rendering parameters for drawing a shape.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;get_shape_values&lt;/b&gt;&lt;/span&gt;(some_options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old_ops = &lt;span style="color: cyan;"&gt;&lt;b&gt;@values&lt;/b&gt;&lt;/span&gt;.dup&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;merge_options(old_ops, some_options) &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;some_options&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.fill *old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;nbsp;old_ops[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;], old_ops&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# The shape primitives are sphere and cube&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;cube&lt;/b&gt;&lt;/span&gt;(some_options=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size, options = *get_shape_values(some_options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotz = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;roty = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotx = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x rotx &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y roty &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z rotz &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.translate(options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;* size, options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;] * size , options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;* size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.box(size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotz) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# unwind rotations in an ordered way&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* roty) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotx) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;sphere&lt;/b&gt;&lt;/span&gt;(some_options=&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;nil&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size, options = *get_shape_values(some_options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotz = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rz&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;roty = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rotx = options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:rx&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x rotx &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y roty &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z rotz &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&lt;/span&gt;&lt;span style="font-family: monospace;"&gt; &lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @app&lt;/b&gt;&lt;/span&gt;.translate(options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:x&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;* size, options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;] * size , options[&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:z&lt;/b&gt;&lt;/span&gt;]&amp;nbsp;&amp;nbsp;* size)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.sphere_detail &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.sphere(size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_z(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotz) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotz.nil?&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# unwind rotations in an ordered way&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_y(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* roty) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;roty.nil?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@app&lt;/b&gt;&lt;/span&gt;.rotate_x(-&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* rotx) &lt;span style="color: yellow;"&gt;&lt;b&gt;unless&lt;/b&gt;&lt;/span&gt;&amp;nbsp;rotx.nil?&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My Test Script monster.rb&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;load_libraries &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:test_free&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:control_panel&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_the_spiral&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ContextFree&lt;/b&gt;&lt;/span&gt;.define &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:monster&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt;.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;split &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cone &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:ry&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;72&lt;/b&gt;&lt;/span&gt;&amp;nbsp;* i&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewind&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cone&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: cyan;"&gt;&lt;b&gt;# two equally weighted cone rules creates the beat&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sphere &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cone &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.96&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.24&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rule &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:cone&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sphere &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:brightness&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cone &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.97&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.28&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;size &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;800&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;800&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;P3D&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;configure_control&lt;br /&gt;&amp;nbsp;&amp;nbsp;smooth&lt;br /&gt;&amp;nbsp;&amp;nbsp;setup_the_spiral&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;configure_control&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;control_panel &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;c&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.title = &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Attitude Control&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:xrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:yrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:zrot&lt;/b&gt;&lt;/span&gt;, -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;3.1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1.0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;background &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;lights&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.render &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:monster&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_x&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_y&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:start_z&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; -&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;30&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; height/&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;200&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:stop_size&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:color&lt;/b&gt;&lt;/span&gt;&amp;nbsp;=&amp;gt; [&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.8&lt;/b&gt;&lt;/span&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.rotate_x xrot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.rotate_y yrot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@spiral&lt;/b&gt;&lt;/span&gt;.rotate_z zrot&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_DUDH0kznFTA/TIgCQ7WfKUI/AAAAAAAAC8Y/6NvsfzgBHaQ/s1600/control.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_DUDH0kznFTA/TIgCQ7WfKUI/AAAAAAAAC8Y/6NvsfzgBHaQ/s320/control.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://2.bp.blogspot.com/_DUDH0kznFTA/TIgCU2Vc4CI/AAAAAAAAC8g/xLt3D34_GkQ/s1600/monster.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/_DUDH0kznFTA/TIgCU2Vc4CI/AAAAAAAAC8g/xLt3D34_GkQ/s400/monster.png" width="390" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-5816154260347737468?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/5816154260347737468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/3d-context-free-dsl-in-ruby-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5816154260347737468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/5816154260347737468'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/3d-context-free-dsl-in-ruby-processing.html' title='Experimental 3D Context Free DSL in ruby-processing, a bit of a monster?'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_DUDH0kznFTA/TIgCQ7WfKUI/AAAAAAAAC8Y/6NvsfzgBHaQ/s72-c/control.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-1834185018629131883</id><published>2010-09-04T09:53:00.001+01:00</published><updated>2010-09-04T10:03:15.691+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='control panel'/><category scheme='http://www.blogger.com/atom/ns#' term='Gray-Scott diffusion'/><category scheme='http://www.blogger.com/atom/ns#' term='toxiclibs'/><title type='text'>Using the control  panel and Toxi Processing Libraries in ruby processing</title><content type='html'>Here is a sketch that shows how easy it is to add controls to your sketch in ruby-processing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;p&amp;gt;GrayScottControl uses the seedImage() method to use a bitmap as simulation seed.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# In this demo the image is re-applied every frame and the user can adjust the &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# F coefficient of the reaction diffusion to produce different patterns emerging&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# from the boundary of the bitmapped seed. Unlike some other GS demos provided,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# this one also uses a wrapped simulation space, creating tiled patterns.&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;usage:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;ul&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;li&amp;gt;click + drag mouse to locally disturb the simulation&amp;lt;/li&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;li&amp;gt;Use slider to adjust the F parameter of the simulation&amp;lt;/li&amp;gt; &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;li&amp;gt;press reset! to do what?&amp;lt;/li&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;li&amp;gt;press save_graycsott to do save&amp;lt;/li&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;/ul&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Copyright (c) 2010 Karsten Schmidt (rubified by Martin Prout)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# This demo &amp;amp; library is free software you can redistribute it and/or&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# modify it under the terms of the GNU Lesser General Public&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# License as published by the Free Software Foundation either&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# version 2.1 of the License, or (at your option) any later version.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# http:#creativecommons.org/licenses/LGPL/2.1/&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# This library is distributed in the hope that it will be useful,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# but WITHOUT ANY WARRANTY without even the implied warranty of&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&amp;nbsp;&amp;nbsp;See the GNU&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Lesser General Public License for more details.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# You should have received a copy of the GNU Lesser General Public&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# License along with this library if not, write to the Free Software&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA&amp;nbsp;&amp;nbsp;02110-1301&amp;nbsp;&amp;nbsp;USA&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;GrayScottControl&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;simutils&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxiclibscore&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;colorutils&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;control_panel&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.sim.grayscott&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.math&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.color&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:gs&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:tone_map&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:img&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:set_f&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;256&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;256&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setup_control&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;GrayScott&lt;/b&gt;&lt;/span&gt;.new width, height, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;true&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@img&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= load_image &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;two_prong.png&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# create a duo-tone gradient map with 256 steps&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# NB: use '::' in place of '.' here&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@tone_map&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: lime;"&gt;&lt;b&gt;ToneMap&lt;/b&gt;&lt;/span&gt;.new(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.33&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;NamedColor&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;CRIMSON&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: lime;"&gt;&lt;b&gt;NamedColor&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;WHITE&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;256&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;draw&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;.seed_image(img.pixels, img.width, img.height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;.set_rect(mouse_x, mouse_y, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;) &lt;span style="color: yellow;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;mouse_pressed? &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;load_pixels&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;.times { &lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;.update(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;) }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# read out the V result array&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# and use tone map to render colours&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gs.v.length.times &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;i&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pixels[i]=tone_map.getARGBToneFor(gs.v[i])&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# NB: don't camel case convert here&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;.setF(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.02&lt;/b&gt;&lt;/span&gt;&amp;nbsp;+ set_f * &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.001&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;update_pixels&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup_control&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;control_panel &lt;span style="color: yellow;"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt;&amp;nbsp;|&lt;span style="color: cyan;"&gt;&lt;b&gt;c&lt;/b&gt;&lt;/span&gt;|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.title = &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;Control Panel&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.slider &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:set_f&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;..&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;8&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.button &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:save_graycsott&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c.button &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:reset!&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;save_graycsott&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_loop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;save_frame &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.png&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;loop&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;reset!&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;.reset&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;end&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_DUDH0kznFTA/TIIIrokp_mI/AAAAAAAAC8A/7sgNybcTOxg/s1600/panel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_DUDH0kznFTA/TIIIrokp_mI/AAAAAAAAC8A/7sgNybcTOxg/s320/panel.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_DUDH0kznFTA/TIIIpZuZn2I/AAAAAAAAC74/kt1tvK_tY2c/s1600/toxi.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_DUDH0kznFTA/TIIIpZuZn2I/AAAAAAAAC74/kt1tvK_tY2c/s320/toxi.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: monospace;"&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8424170917240137669-1834185018629131883?l=learning-ruby-processing.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learning-ruby-processing.blogspot.com/feeds/1834185018629131883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/using-control-panel-and-toxi-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1834185018629131883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8424170917240137669/posts/default/1834185018629131883'/><link rel='alternate' type='text/html' href='http://learning-ruby-processing.blogspot.com/2010/09/using-control-panel-and-toxi-processing.html' title='Using the control  panel and Toxi Processing Libraries in ruby processing'/><author><name>monkstone</name><uri>http://www.blogger.com/profile/10339203885788088979</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://1.bp.blogspot.com/_DUDH0kznFTA/TFpmLXujrOI/AAAAAAAAC6Y/Ed9hMb1qPSo/S220/monkstone.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_DUDH0kznFTA/TIIIrokp_mI/AAAAAAAAC8A/7sgNybcTOxg/s72-c/panel.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8424170917240137669.post-350760791715646135</id><published>2010-09-02T20:02:00.003+01:00</published><updated>2010-09-02T20:25:35.080+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby processing'/><category scheme='http://www.blogger.com/atom/ns#' term='Gray-Scott diffusion'/><category scheme='http://www.blogger.com/atom/ns#' term='toxiclibs'/><title type='text'>Tone map example of Gray-Scott diffusion using toxiclibs in ruby processing</title><content type='html'>Another rubified example, showing how to use some of the &lt;a href="http://hg.postspectacular.com/toxiclibs/wiki/Home"&gt;toxiclibs&lt;/a&gt; in ruby-processing. Any observations/questions could be made on the processing alternative implementations forum, which I often watch.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;p&amp;gt;GrayScottToneMap shows how to use the ColorGradient &amp;amp; ToneMap classes of the&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# colorutils package to create a tone map for rendering the results of&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# the Gray-Scott reaction-diffusion.&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Usage:&amp;lt;/strong&amp;gt;&amp;lt;ul&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;li&amp;gt;click + drag mouse to draw dots used as simulation seed&amp;lt;/li&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;li&amp;gt;press any key to reset&amp;lt;/li&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &amp;lt;/ul&amp;gt;&amp;lt;/p&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Copyright (c) 2010 Karsten Schmidt&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# This demo &amp;amp; library is free software you can redistribute it and/or&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# modify it under the terms of the GNU Lesser General Public&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# License as published by the Free Software Foundation either&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# version 2.1 of the License, or (at your option) any later version.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;a href="http://creativecommons.org/licenses/LGPL/2.1/"&gt;http://creativecommons.org/licenses/LGPL/2.1/&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# This library is distributed in the hope that it will be useful,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# but WITHOUT ANY WARRANTY without even the implied warranty of&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&amp;nbsp;&amp;nbsp;See the GNU&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Lesser General Public License for more details.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# You should have received a copy of the GNU Lesser General Public&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# License along with this library if not, write to the Free Software&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA&amp;nbsp;&amp;nbsp;02110-1301&amp;nbsp;&amp;nbsp;USA&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: cyan;"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;GrayScottToneMap&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&amp;lt; &lt;span style="color: lime;"&gt;&lt;b&gt;Processing&lt;/b&gt;&lt;/span&gt;::&lt;span style="color: lime;"&gt;&lt;b&gt;App&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;load_libraries &lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;simutils&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxiclibscore&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;colorutils&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;'&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.sim.grayscott&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.math&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;include_package &lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;toxi.color&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #ff6060;"&gt;&lt;b&gt;"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: lime;"&gt;&lt;b&gt;NUM_ITERATIONS&lt;/b&gt;&lt;/span&gt;&amp;nbsp;= &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: yellow;"&gt;&lt;b&gt;attr_reader&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:gs&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;:tone_map&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #8080ff;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;setup&lt;/b&gt;&lt;/span&gt;() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size(&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;256&lt;/b&gt;&lt;/span&gt;,&lt;span style="color: #ff40ff;"&gt;&lt;b&gt;256&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;= &lt;span style="color: lime;"&gt;&lt;b&gt;GrayScott&lt;/b&gt;&lt;/span&gt;.new width,height, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;@gs&lt;/b&gt;&lt;/span&gt;.set_coefficients &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.021&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.076&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.12&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: #ff40ff;"&gt;&lt;b&gt;0.06&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# create a color gradient for 256 values&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grad = &lt;span style="color: lime;"&gt;&lt;b&gt;ColorGradient&lt;/b&gt;&lt;/span&gt;.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# NamedColors are preset colors, but any TColor can be added&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# see javadocs for list of names:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: cyan;"&gt;&lt;b&gt;# &lt;a href="http://toxiclibs.org/docs/colorutils/toxi/color/NamedColor::html"&gt;http://toxiclibs.org/docs/colorut
