A plugin for Processing

Processing is a very popular and simple development tool for writing java-like code, targeted towards artists. Processing is dedicated to developing small, extremely lightweight and simple interactive applets and this orientation affects most of its design and implementation decisions. It presents a slightly cut down version of the Java language — casts, imports, and class preambles are removed — in a cut down runtime environment. Push "play" and your files are manipulated back into Java, sent to Jikes and the resulting class-file run. Push "stop" and the applet disappears. Change your code, push "play" and so on.

Field has very little to say on the subject of making small Applets. And while we respect the pedagogical ambitions of Processing, we're frustrated at the imbalance between the energy in the community and the conservatism of the development environment. What Processing does have is a wide-ranging community of users who are, uniquely, sharing ideas and code in a vibrant way — that's a truly wonderful thing.

This page is pretty developer-oriented. For a more straightforward tutorial: SimpleProcessingTutorial.

A PApplet / Field bridge

Can Field talk Processing? A pleasant afternoon yielded the ProcessingPlugin which seems to prove that we can replace Processing's text editor with the Field environment.

While one could, via the magic of Jython, define a perfectly valid PApplet subclass in Python and then load and run it using any technique that loads and runs Applets, this would really miss the point — or rather, simply duplicate what Processing already achieves in a different language. The trick is to understand that Processing, having packaged up its now-Java code, essentially wants to run all of its users's code during the PApplet.draw() at which point PApplet has conspired to have the necessary valid drawing context active. Any python code that is executed by the Field programmer needs to be executed "inside" that method.

If you want to skip to the punchline (and miss the Field-internal-developer level documentation below) it's this: anything that you can write in Processing in Java (then compile, then run, the stop, then edit etc) you can write with Field's text editor (without any compilation, stopping &c); any visual element can tagged such that its execution plays nicely with PApplet — these visual elements are just like any other, they can be executed by other elements, they can appear in time-lines, they can have GUI elements in them etc... Multiple code fragments can be cooperating simultaneously, or stopping and starting on demand. The PApplet is never torn down and restarted.

This transforms Processing in a way that is simultaneously gentle and radical. Gentle, because if we take, say, the BezierEllipse example that ships with Processing we can write it in Python/Field, line for line:

smooth()
background(145);

controlPtCol = 0x222222ff
anchorPtCol = 0xbbbbbbff
strokeColor = 0xf02030ff

width=500
height=500

#draw ellipse with anchor/control points
def drawEllipse():
    strokeWeight(1.125);
    stroke(strokeColor);
    noFill();
    #create ellipse
    for i in range(0, pts):
        bezier(px[i], py[i], cx[i], cy[i], cx2[i], cy2[i], px[(i+1)%len(px)], py[(i+1)%len(px)])
    strokeWeight(1.75);
    stroke(0);
    rectMode(applet.CENTER);

    # control handles and tangent lines
    for i in range(0, pts):
        line(px[i], py[i], cx[i], cy[i])
    for i in range(0, pts):
        fill(controlPtCol)
    noStroke();

    #control handles
    ellipse(cx[i], cy[i], 4, 4);
    ellipse(cx2[i], cy2[i], 4, 4);
    fill(anchorPtCol);
    stroke(0);

    #anchor points
    rect(px[i], py[i], 5, 5);
    
def setEllipse(points, radius, controlRadius):
    global pts
    pts= points;
    angle = 360.0/points;
    controlAngle1 = angle/3.0;
    controlAngle2 = controlAngle1*2.0;
    global px, py, cx, cy, cx2,cy2
    
    r = range(0, 360, 360/points)
    px = [width/2+cos(radians(angle))*radius for angle in r]
    py = [height/2+sin(radians(angle))*radius for angle in r]
    cx = [width/2+cos(radians(angle+controlAngle1))*
controlRadius/cos(radians(controlAngle1)) for angle in r]
    cy = [height/2+sin(radians(angle+controlAngle1))*
controlRadius/sin(radians(controlAngle1)) for angle in r]
    cx2 = [width/2+cos(radians(angle+controlAngle2))*
controlRadius/cos(radians(controlAngle1)) for angle in r]
    cy2 = [height/2+sin(radians(angle+controlAngle2))*
controlRadius/sin(radians(controlAngle1)) for angle in r]


def ongoing():
    background(145)
    setEllipse(int(random(3, 12)), random(-100, 150), random(-100, 150));
    drawEllipse();

_r = ongoing

Radical because we can cause this to start running by option-clicking on this element in the canvas. But unlike Processing we can alter the colors of the elements while it is running: either by typing (and hitting command-return), or with an embedded slider, or with some more code (a script, a time-slider, anything). Unlike Processing we can then add another set of drawing commands, in a completely different visual element, with a different lifecycle, that draw to the same canvas (they only have to agree on which one of them is going to call background(...)). If this has piqued your interest, take a look at the SimpleProcessingTutorial.