Crickets Chirping

mon qui si, mon qui d’où

Archive for the ‘Processing’ Category

js.Processing with Rhino

with 4 comments

Processing.js: Processing in JavaScript

A few months ago JavaScript Ninja John Resig unleashed processing.js. Like many others I was shocked and amazed. I love to tinker with Processing, and I also do a fair amount of JavaScript work, so I was keenly interested.

There are some limitations to using the browser for the type of work people want to do with Processing though. Processing.js is even slower than Processing applets, and it’s not even a full implementation.

However, I am intrigued by the use of JavaScript to do Processing-like stuff.

js.Processing: JavaScript in Processing

The Processing language inherits some unfortunate (and personally annoying) features of Java since that’s what it compiles down to.

I actually prefer JavaScript to the Processing language because it’s loosely typed and has some other nifty features.

I’d like to be able to use all of Processing’s capabilities (not the crippled applet variety), AND program with JavaScript instead of Processing’s language.

cake.have().eat();

So today I created a .pde that loads Rhino, creates a JavaScript execution context, stuffs itself into that context, loads an external javascript file and runs it.

And js.Processing is born.

I added some functions to proxy the built-in Processing callbacks so you can write “draw(){}” and “mouseDragged(){}” in javascript and they do what you’d expect.

Here’s the main shell Processing sketch that runs the Javascript (listing below):


/**
 * Experiment to drive Processing with JavaScript.
 * Uses Rhino: https://developer.mozilla.org/en/Rhino_Overview
 * This does not currently work in an applet due to some Rhino issues
 * with class loading and optimization.
 *
 * This class itself isn't where you put the javascript.  .js files
 * should go in your processing project's code/ folder.  Load your .js
 * script explicitly in setup() below.  This example is hard-coded to
 * laod "guilloches.js", an example I ported from regular Processing
 * but you can set it to whatever file name you want.
 *
 * This class just forwards calls from Processing into your javascript code.
 *
 * To access Processing methods in javascript, prefix them with "p5." -
 * I'm looking at how to make those functions global, if that's possible.
 *
 * author: Sean McCullough banksean@gmail.com
 */
import org.mozilla.javascript.*;

Context cx;
Scriptable scope;
Function jsInit;
Function jsDraw;
Function jsMouseDragged;
Function jsMousePressed;
Function jsMouseReleased;
Function jsKeyPressed;
Function jsKeyReleased;

void setup() {
  cx = Context.enter();   

  // TODO: make this work so it can run in an applet.  Because optimization levels 0 and higher do classLoader voodoo,
  // the browser seems to object.  Setting it to -1, however, makes JavaAdapter no workie and that makes this exercise
  // even more useless.
  // cx.setOptimizationLevel(-1);

  scope = cx.initStandardObjects();
  size(400, 400);

  // String[] globalNames = {"log"};
  // TODO: make this work so global functions don't need to be prefixed with p5.whatever.
  // scope.defineFunctionProperties(globalNames, Class.forName("jstest.JSProcessing"), ScriptableObject.DONTENUM);

  Object wrappedThis = Context.javaToJS(this, scope);

  // p5 is the global "Processing" object available to your scripts.  Prefix any processing api calls with "p5." or they
  // won't work.
  ScriptableObject.putProperty(scope, "p5", wrappedThis);

  String srcStrings[] = loadStrings("guilloches.js");
  String src = "";
  for (int i=0; i<srcStrings.length; i++) {
    src += srcStrings[i] + "\n";
  }

  cx.evaluateString(scope, src, "<cmd>", 1, null);

  jsInit = getFunction("init");
  jsDraw = getFunction("draw");
  jsMouseDragged = getFunction("mouseDragged");
  jsMousePressed = getFunction("mousePressed");
  jsMouseReleased = getFunction("mouseReleased");

  jsKeyPressed = getFunction("keyPressed");
  jsKeyReleased = getFunction("keyReleased");

  jsInit.call(cx, scope, scope, null);
}

Function getFunction(String name) {
  Object o = scope.get(name, scope);
  if (o instanceof Function) { return (Function) o; }
  return null;
}

void draw() {
  callIfNotNull(jsDraw);
}

void mouseDragged() {
  callIfNotNull(jsMouseDragged);
}

void mousePressed() {
  callIfNotNull(jsMousePressed);
}

void mouseReleased() {
  callIfNotNull(jsMouseReleased);
}

void keyPressed() {
  callIfNotNull(jsKeyPressed);
}

void keyReleased() {
  callIfNotNull(jsKeyReleased);
}

void callIfNotNull(Function f) {
  if (f != null) {
    f.call(cx, scope, scope, null);
  }
}

public void log(String str) {
  System.out.println(str);
}

//////////////////// Begin overloaded global functions //////////////////////

public void stroke(String cr) {
  stroke((Integer)colors.get(cr));
}

public void fill(String s) {
  fill((Integer)colors.get(s));
}

HashMap colors = new HashMap();

/**
 * Rhino/Javascript don't support long types.  In processing, a color object is
 * represented by a long, so we have a problem.  This method proxies color() to
 * return a JS-safe reference to a processing color value.
 * See:
 * http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/FunctionObject.html
 * Also, it's called getColor() instead of color() because processing won't let
 * me override that method name.  Probably has something to do with it being a
 * reserved word as well as a method/class.  Should probably just replace this
 * with a hex string of the color values.
 */
public String getColor(int r, int g, int b, int a) {
  color c = color(r,g,b,a);
  colors.put("" + c, c);
  return "" + c;
}

Here’s what my Guilloches sketch looks like, re-implemented in js.Processing:


function init() {
  p5.smooth();
  p5.background(255);
  // NOTE: have to use getColor() instead of color()
  // because JavaScript is retarded about Longs, which color() returns.
  var c = p5.getColor(0, 0, 0, 64);
  p5.stroke(c);
  p5.frameRate(10);
  p5.strokeWeight(0.5);
  p5.strokeCap(p5.SQUARE);
}

var lastSet = false;
var lastX = 0;
var lastY = 0;

var dTheta = 0.0004 * p5.PI;
var theta = 0.0;

var R = 50.0;
var r = -0.25;
var p = 25.0;
var m = 1;
var n = 6.00;
var Q = 0; 

function mousePressed() {
  drawStuff();
}

function mouseDragged() {
  drawStuff();
}

function draw() {
  if (!lastSet) drawStuff();
}

function drawStuff() {
  var mx = 2.0*(p5.width/2.0-p5.mouseX)/p5.width;
  var my = 2.0*(p5.height/2.0-p5.mouseY)/p5.height;

  if (lastSet)
    Q = (50*Math.sqrt(mx*mx + my*my));

  var Rr = R + r;
  var rp = r + p;

  p5.background(255);

  var mTheta = m*theta;
  var mThetaRrr = m*theta*Rr/r;
  var nTheta = n*theta;
  var x;
  var y;
  var plotX;
  var plotY;

  for (var i=0; i<15000; i++) {
  theta += dTheta;

  mTheta = m*theta;
  mThetaRrr = m*theta*Rr/r;
  nTheta = n*theta;

  x = (Rr)*Math.cos(mTheta) +
	(rp)*Math.cos(mThetaRrr) +
	Q*Math.cos(nTheta);
  y = (Rr)*Math.sin(mTheta) +
	(rp)*Math.sin(mThetaRrr) +
	Q*Math.sin(nTheta);

  plotX = (p5.width/2 + (x/125)*p5.width/2);
  plotY = (p5.height/2 + (y/125)*p5.height/2);
  if (!lastSet) {
    lastSet = true;
    lastX = plotX;
    lastY = plotY;
  }

  p5.line(lastX, lastY, plotX, plotY);
  lastX = plotX;
  lastY = plotY;
  }
}

I’m not really taking advantage of JavaScript language features much here (besides not having to worry about variable types) but it proves the concept.

I haven’t done any formal performance tests, but this seems to run slower than the original.

Download the js.Processing Project .zip Here

The JavaScript source code is in the data/ folder (since it’s loaded as an external resource).

Of course I imagine there’s an easier way to go about this, especially if one were to actually modify the Processing source code itself to accommodate JavaScript/Rhino.

Written by banksean

December 7th, 2008 at 9:23 pm

Posted in Code,General,Processing

Slit-Scan Slinky Bass with Processing

with one comment

Written by banksean

December 5th, 2008 at 2:33 am

Posted in Processing

Guilloches

with 2 comments

I was inspired by this post on Guilloches to generate them in Processing (It’s been that kind of weekend. At least my unit tests are passing now :)

Click here to try out the applet

Or check out these stills:

This basically look like spirographs for now, but I’m sure there are ways to make them more interesting. Maybe have the extended cycloid follow some other curve besides a circle.

Written by banksean

November 24th, 2008 at 1:00 am

Posted in Code,General,Processing

A 16,777,216 Color Picture

with one comment

I was bored waiting for some unit tests to run and I ran across allRGB: images made from all the colors in the 24-bit RGB space, none missing and none repeated. Each color is used by exactly one pixel.

I love challenges/constraints like this. Here’s my 4096×4096 pixel image:

These are scaled down. The full size image doesn’t compress very well, and if you want to see it up close you can just use the Processing source code at the end of this post.

Algorithm rough outline: first fill up the 4096×4096 pixel array with all the distinct integers in that range, in increasing order. Then scan all the pixels in order, swapping each with a neighbor located nearby adjusted by some sinusoidal terms. The swap operation preserves the 1-1 mapping of pixels to colors. Then count the colors to make sure you didn’t miss one, or have any duplicates. I came up with a way to do this check, but I thought it was pretty brain dead. Turns out it’s the recommended way to do it over on Stack Overflow.

Source (wouldn’t dare embed this as an applet):

int HEIGHT=800;
int WIDTH=800;

PImage img;
boolean saved = false;

void setup() {
  size(WIDTH, HEIGHT);
}

void draw() {
  if (img == null) {
    img = createImage(4096, 4096, RGB);
    for(int i=0; i < img.pixels.length; i++) {
      img.pixels[i] = i;
    }
  }

  for(int x=0; x < img.width; x++) {
    for(int y=0; y < img.height; y++) {
      double i = Math.sqrt(Math.pow(img.width/2 - (x % img.width/2), 2) +
        Math.pow(img.height/2 - (y % img.height/2), 2));
      int x2 = x + (int)(Math.sin(i*0.001*PI) * i);
      int y2 = y + (int)(Math.cos(i*0.001*PI) * i);
      swapPixels(x, y, x2, y2);
    }
  }

  image(img, 0, 0, WIDTH, HEIGHT);
  if (!saved) {
    img.save("rgb.png");
    saved = true;
    checkColorsUsed();
  }
}

void swapPixels(int x1, int y1, int x2, int y2) {
  x1 = x1 % img.width;
  if (x1 < 0) { x1 = img.width + x1; }
  x2 = x2 % img.width;
  if (x2 < 0) { x2 = img.width + x2; }
  y1 = y1 % img.height;
  if (y1 < 0) { y1 = img.height + y1; }
  y2 = y2 % img.height;
  if (y2 < 0) { y2 = img.height + y2; }

  swapPixels(x1 + y1*img.width, x2 + y2*img.width);
}

void swapPixels(int i, int j) {
    int a = img.pixels[i];
    int b = img.pixels[j];
    img.pixels[j] = a;
    img.pixels[i] = b;
}

void checkColorsUsed() {
  System.out.println("scanning colors");

  boolean colorsUsed[] = new boolean[img.pixels.length];
  for (int i = 0; i < img.pixels.length; i++) {
    if (colorsUsed[img.pixels[i]]) {
      System.out.println("duplicate: " + img.pixels[i]);
    }
   colorsUsed[img.pixels[i]] = true;
  }

  System.out.println("counting colors");

  for (int i=0; i < colorsUsed.length; i++) {
    if(!colorsUsed[i]) {
      System.out.println("unused: " + i);
    }
  }

  System.out.println("color check complete");
}



If you want to run it from Processing, you’ll probably have to increase the maximum available memory to some very large number (it’s in the Preferences window).

I love writing sloppy crap in processing because the code really doesn’t matter :)

I would have posted this image to allRGB, but they want you to sign up for an account on some other site first. Shrug.

Written by banksean

November 23rd, 2008 at 2:35 am

Posted in Processing

Japan, Right Now: Multiple Interactive Stacked Charts

with one comment

Japan, Right Now is an interesting data visualization of Japanese census data written in Processing.

I’m a fan of the stacked charts technique and I really like what Soma has done to project the data set in multiple sections interactively.

I think the navigation up and down the hierarchy could be improved (by, say, underlining the clickable titles in the upper left of each stacked chart, and including breadcrumbs) but overall I really like this piece.

Some examples of single stacked charts are the famous Baby Name Voyager and NYT Movie Revenues. While these are also interactive, Soma’s visualization is a little more ambitious because it links multiple stacked charts together.

Thanks for the link, Adam!

Written by banksean

October 17th, 2008 at 12:52 pm

Posted in General,Processing

SVG to OSC

with 2 comments

Bill Orcutt created a neat-o visual audio experiment called “SVG to OSC” based on my circle-packing Processing experiment.

I love this about the Processing community: you try something out on a lark, share it with the web and other people riff on it. Or if you find something cool that’s close to something else you’d like to try, it’s easy to riff off of other people’s code. This example isn’t written in Processing, actually but it’s still pretty neat.


SVG to OSC from Bill Orcutt on Vimeo.

Check out his other work, built using his Lilly environment rather than Processing but it’s based on JavaScript so I’ll have to try it out.

Written by banksean

February 2nd, 2008 at 2:03 pm

Posted in General,Processing

Processing Sketch: Circle Packing

with 6 comments

This evening I implemented a circle packing algorithm in processing.


circlepack.jpg
Click here to run the applet.

I have some more ambitious ideas in mind for this, but what I really need is a hierarchical circle packing implementation like the one described here. I started down that road but I kept getting stumped by the math. That’s frustrating because it’s basic geometry and trig. The alternative algorithm I chose for this applet is much simpler and performs reasonably well for interactive use.

Written by banksean

June 18th, 2007 at 12:00 am

Posted in Code,General,Processing

Force Directed Graph Layout With Processing, Take 2

with 6 comments

Once upon a time I wrote a force-directed graph layout application using processing. I rolled it all myself, so that meant the physics calculations were a) sloppy and b) slow. In the time since then, a wonderful physics library has come to my attention so it’s time for some updates. (As if I wanted to write my own Runge-Kutta integrator. pshaw right. I failed calculus in high school, but I made a 4 on the AP exam. I don’t do homework. :)

graphtoy.gif

The demonstration app is a toy with a few simple rules:

  • Expand: Click on the red nodes to expand a randomly generated subtree.
  • Connect: Click on a blue node to connect it to whichever node you currently have selected.
  • Fade: The nodes age with time. They eventually fade and disappear, so you have to keep expanding and connecting in order to keep the graph alive. Clicking on a node resets its clock.

I liken the activity to playing with bubble-wrap that keeps regenerating itself the more you pop it.

I’ve got some ideas for a game based on this, but by all means let me know if you have suggestions.

Written by banksean

February 26th, 2007 at 9:39 am

Posted in General,Processing

Biblical Citations via Google

with 7 comments

I wonder which Bible verses are cited most often on the web. What are the most popular pieces of Holy Wisdom, according to Google?

I seek to answer this question with some code I’ve written.

Here’s a chart of Google results for every verse in Genesis:


bible1.png

I’m writing an interactive browser for this dataset in Proce55ing (that chart is a screenshot actually), so stay tuned if you want to see the finished product.

There are some interesting problems with displaying a chart like this on a normal computer screen. For one thing, you’d need a screen 31,000 pixels wide in order to display it at a one-pixel per verse resolution. That’s one hell of a sparkline.

I’ll probably borrow a few ideas from some of the Human Genome Project data browsers and visualizations out there on the net.

What I’m aiming for at this point is a way to seek out the most often cited verses, and see them in context of who quotes them and why.

It’s obvious that some verses are more popular than others, but why? From a textual analysis of the most popular verses, I’d also like to build a Markov process to generate new verses that might also be appealing.

God damnit. Somebody already did it. I’m starting to get sick of this postmodern creative dilemma shit.

[Edit: Fucking shit. I hate my life. Just one original idea. That's all I fucking want.]

Written by banksean

December 15th, 2006 at 3:58 pm