Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

Embed Size (px)

Citation preview

  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    1/11

    orking with Toxiclibs [Processing, Tutorial]

    uld you like to create what you see in those videos? Well, read on! Because in this article I will show you how you can d

    t using Processing and Toxiclibs. As Processings biggest open source collection of libraries, Toxiclibs can assist you in

    geometry, physics, math and color. With so much code candy for the taking, the libs can still be a bit daunting for ma

    ple, especially Processing beginners. Thats why in addition to great functionality and documentation clear and in

    mples on how to use the library are so important. Fortunately the collection of code examples bundled with the libs is

    adily. I hope my examples can add to that and be helpful to those learning how to use this wonderful collection of code

    hared and continuously developed by Karsten Schmidt.

    http://postspectacular.com/http://toxiclibs.org/
  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    2/11

    already shared the two code examples from the first video on myblog. As the video shows these concern creating, pic

    gging polygon shapes (example 1) and the destruction of voronoi tesselated circles (example 2). The full source cod

    re detailed explanation of those two examples can be found HERE. In this follow-up I will share the source code for th

    nd new examples you see in the second video. This time Im venturing a little deeper into the physics capabilities of To

    re specifically theVerletSpring2Dclass (example 3) and we will explore a whole new area of the libs, namely the colo

    ample 4). All of the examples are commented as much as possible. So by running them and looking through the code

    uld be able to understand whats going on. The rest of this blog post can be considered additional background informa

    ging from general description to specific pointers. Note (06/05/2011): Karsten came up with some useful suggestions

    ther improve the code, which of course I was happy to apply. This explains why the visuals when running the code may

    r so slightly from what you see in the movie.

    ample 3: The Infinite Rope

    ats better than a rope? Exactly. An INFINITE rope! This example demonstrates both the creation and efficient remov

    ticles, springs and behaviors. The three pillars of the physics system. Specifically it uses theVerletSpring2Dclass, whi

    http://toxiclibs.org/docs/verletphysics/toxi/physics2d/VerletSpring2D.htmlhttp://www.creativeapplications.net/wp-content/uploads/2011/05/Toxiclibs-Spring2D-v2-by-Amnon-Owed.jpghttp://toxiclibs.org/docs/verletphysics/toxi/physics2d/VerletSpring2D.htmlhttp://amnonp5.wordpress.com/2011/04/23/working-with-toxiclibs/http://amnonp5.wordpress.com/http://www.creativeapplications.net/wp-content/uploads/2011/05/Toxiclibs-BreakCircle-by-Amnon-Owed.jpg
  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    3/11

    nect twoVerletParticlesin space. For simplicity its kept 2D, but everything with regard to physics in Toxiclibs also ha

    ivalent. Let me describe the way it works and some of the specific choices and solutions. When the mouse is dragged a

    ticle is created and connected to the last one, effectively making a digital rope. Release the mouse to start a new rope.

    avior is added to each particle to make it look a little more realistic. For aesthetic reasons, the color of every segment

    ermined by the direction of each spring.

    e most important part of the sketch however, is the code that removes off-screen objects. This is absolutely imperative

    ngs running smoothly. Let me elaborate on two specific aspects with regard to the removeOffscreen() function. First, it

    ning backwards through the for loop! This is because we are removing things from the list. Meaning the list is getting

    le you are going through it. Therefore you need to go backwards to prevent problems and to make sure you cover ever

    list. Second, notice that I remove behavior(i+1) for particle(i). The reason is that the first behavior on the list is the gr

    ed in setup(). Therefore the behavior of particle 1 can be found in position 2 of the behavior list and so on.

    Toxiclibs Code Example: The Infinite Rope

    by Amnon Owed (05/05/2011)

    minor refactorings by Karsten Schmidt (06/05/2011)

    port processing.opengl.*;

    port toxi.physics2d.behaviors.*;

    port toxi.physics2d.*;

    port toxi.geom.*;

    port toxi.color.*;

    rletPhysics2D physics;

    rletParticle2D prev;

    t continuous,current; // variables to create a new continuous line on each mouse drag

    id setup() {

    size(1280,720,OPENGL);

    physics = new VerletPhysics2D();

    // add gravity in positive Y direction

    physics.addBehavior(new GravityBehavior(new Vec2D(0,0.1)));

    // set the stroke weight of the line

    strokeWeight(2);

    id draw() {

    background(255);

    // update all the physics stuff (particles, springs, gravity)

    physics.update();

    // draw a line segment for each spring and change the color of it based on the x positi

    for(VerletSpring2D s : physics.springs) {

    http://toxiclibs.org/docs/verletphysics/toxi/physics2d/VerletParticle2D.html
  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    4/11

    // map the direction of each spring to a hue

    float currHue=map(s.b.sub(s.a).heading(),-PI,PI,0,1);

    // define a color in HSV and convert into ARGB format (32bit packed integer)

    stroke(TColor.newHSV(currHue,1,1).toARGB());

    line(s.a.x,s.a.y,s.b.x,s.b.y);

    }

    // remove stuff that is off the screen to keep things running smoothly ;-)

    removeOffscreen();

    id removeOffscreen() {

    // remove off-screen springs

    for (Iterator i=physics.springs.iterator(); i.hasNext();) {

    VerletSpring2D s=i.next();

    if (s.a.y > height+100 || s.b.y > height+100) {

    i.remove();

    }

    }

    // remove off-screen particles & behaviors

    for (int i=physics.particles.size()-1; i>=0; i--) {

    VerletParticle2D p = physics.particles.get(i);

    if (p.y > height+200) {

    physics.removeParticle(p);

    ParticleBehavior2D b = physics.behaviors.get(i+1);

    physics.removeBehavior(b);

    }

    }

    id mouseDragged() {

    // create a locked (unmovable) particle at the mouse position

    VerletParticle2D p = new VerletParticle2D(mouseX,mouseY);

    p.lock();

    // if there is at least one particle and this is the current continuous line

    if (physics.particles.size() > 0 && continuous == current) {

    // get the previous particle (aka the last in the list)

    VerletParticle2D prev = physics.particles.get(physics.particles.size()-1);

    // create a spring between the previous and the current particle of length 10 and str

    VerletSpring2D s = new VerletSpring2D(p,prev,10,1);

    // add the spring to the physics system

    physics.addSpring(s);

    } else {

  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    5/11

    current = continuous;

    }

    // unlock previous particle

    if (prev!=null) {

    prev.unlock();

    }

    // add the particle to the physics system

    hysics.addParticle(p);

    // create a forcefield around this particle with radius 20 and force -1.5 (aka push)ParticleBehavior2D b = new AttractionBehavior(p,20,-1.5);

    // add the behavior to the physics system (will be applied to all particles)

    hysics.addBehavior(b);

    // make current particle the previous one...

    prev=p;

    id mouseReleased() {

    if (prev!=null) {

    prev.unlock();

    }

    ontinuous++;

    ample 4: NamedColors

    thetically somewhat similar, but technically completely different, this example is meant to demonstrate how to use TC

    eral and NamedColorsin particular. If Vec2D/Vec3D is the heart of the geometry lib, then you could say TColor is the

    color lib. Its the basis for much greater possibilities such as color ranges, themes and gradients. But to grasp this part

    xiclibs, I think its best to start with a basic example. For this I chose the NamedColors since they are less abstract than

    rking with numbers alone. In the color portion of Toxiclibs there is a list of 143 NamedColors that you can use. They ha

    http://toxiclibs.org/docs/colorutils/toxi/color/NamedColor.htmlhttp://toxiclibs.org/docs/colorutils/toxi/color/TColor.htmlhttp://www.creativeapplications.net/wp-content/uploads/2011/05/Toxiclibs-NamedColors-by-Amnon-Owed.jpg
  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    6/11

    mes like azure, darkturquoise, lavender, orange and last but not least peachpuff. When working with TColors its impor

    member that you need to convert them into something that can be used in a Processing fill() or stroke() function. In thi

    mple you can see that every time the color is actually used, its converted into a packed ARGB int using the toARGB() f

    et me walk through the sketch real quick. In setup() all the names are loaded into an ArrayList of strings for the purpo

    ting them alphabetically. Running the sketch presents you with the full color palette. Ive applied some

    omLensInterpolationto bring out the selected color (mouseX) and made it move up and down with the user (mouseY)

    some checks to make sure both the name and its background are kept within the boundaries of the screen. The right m

    ton changes the background color, while the left mouse button creates a colorWorm at the mouse position. Press any k

    gle the palette on/off, the mouse functionality will keep working. The colorWorm is basically a list of up to 25 points, a

    ection and a certain color. It starts at the mouse position and then moves randomly, adding new points along the way.

    directional change is limited to 30 degrees, it will generally keep going into a certain direction instead of wriggling aro

    me spot. To make it a little smoother all the points are loaded into a Spline2Dwhich is then subdivided. From the vertic

    me out, the line is drawn.

    Toxiclibs Code Example: NamedColors

    by Amnon Owed (05/05/2011)

    minor refactorings by Karsten Schmidt (06/05/2011)

    port processing.opengl.*;

    port toxi.geom.*;

    port toxi.color.*;

    port toxi.math.*;

    rayList names = new ArrayList ();

    rayList worms = new ArrayList ();

    omLensInterpolation zoomLens = new ZoomLensInterpolation();

    olean showColorPalette = true;

    t selectedColorID;

    screen center

    c2D center;

    background color (readonly colors can't be modified)adonlyTColor bg;

    id setup() {

    size(1280, 720, OPENGL);

    center = new Vec2D(width/2, height/2);

    // create a list of all the Toxiclibs NamedColors

    names = NamedColor.getNames();

    // sort it alphabetically

    Collections.sort(names);

    http://toxiclibs.org/docs/core/toxi/geom/Spline2D.htmlhttp://toxiclibs.org/docs/core/toxi/math/ZoomLensInterpolation.html
  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    7/11

    textFont(createFont("SansSerif", 28));

    // set zoom lens to a dilating characteristic

    // setting the first parameter to a negative value will create a bundling effect

    zoomLens.setLensStrength(0.45, 1);

    // set the background color to deepskyblue

    bg = NamedColor.getForName("deepskyblue");

    id draw() {// convert the bg color into ARGB color format (32bit packed integer)

    background(bg.toARGB());

    // run through all the worms (backwards cause we are also removing some from the list)

    for (Iterator i=worms.iterator(); i.hasNext();) {

    ColorWorm w = i.next();

    // if the worm's last point is 'off the screen' remove the worm

    // distanceToSquared() is faster than distanceTo() since it avoids

    // the square root calculation and we don't need precise values here...

    if (w.points.get(0).distanceToSquared(center) > 640000) {

    i.remove();

    }

    else {

    // otherwise update and display the worm

    w.update();

    w.display();

    }

    }

    // set the zoom location based on the normalized mouseX (0.0 .. 1.0 interval)

    float normX=(float)mouseX / width;

    // interpolate focal point to new mouse position (15% step per frame)

    zoomLens.setLensPos(normX, 0.15);

    // determine the selected color based on mouseX

    // by finding which color area contains mouseX

    float focalX=zoomLens.interpolate(0, width, normX);

    for (int i=0, num=names.size()-1; i= x && focalX < x2) {

    selectedColorID=i;

    break;

    }

    }

  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    8/11

    // toggle the color palette

    if (showColorPalette) {

    drawColorPalette();

    }

    if (mousePressed) {

    // Create worms with the LEFT mouse button

    if (mouseButton == LEFT) {Vec2D mouse = new Vec2D(mouseX, mouseY);

    ReadonlyTColor c = NamedColor.getForName(names.get(selectedColorID));

    worms.add(new ColorWorm(mouse, c));

    // Change the background color with the RIGHT or MIDDLE mouse button

    }

    else {

    bg = NamedColor.getForName(names.get(selectedColorID));

    }

    }

    Press ANY key to toggle the color palette

    id keyPressed() {

    showColorPalette = !showColorPalette;

    ass ColorWorm {

    List points = new ArrayList ();

    Vec2D direction;

    TColor c;

    ColorWorm(Vec2D origin, ReadonlyTColor c) {

    // at the origin point (mouseX,mouseY)

    points.add(origin);

    // create a copy of the readonly color for later manipulation

    this.c = c.copy();

    // create a random direction

    direction = Vec2D.randomVector();

    }

    void update() {

    // every second frame (not too fast, not too slow)

    if (frameCount % 2 == 0) {

    // create a new point given the last point's coordinates

    Vec2D p = points.get(points.size()-1).copy();

  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    9/11

    // rotate the direction randomly somewhere between -30 and 30 degrees

    direction.rotate(radians(random(-30, 30)));

    // create a movement vector in that direction with a random magnitude between 15 an

    Vec2D move = direction.getNormalizedTo(random(15, 30));

    // move the point in that direction and with that distance

    p.addSelf(move);

    // add the new point to the list

    points.add(p);

    }

    // truncate at 25 points (remove the oldest point)

    while (points.size () > 25) {

    points.remove(0);

    }

    }

    void display() {

    // need at least 3 points to construct a spline

    if (points.size()>2) {

    // create Spline2D from the points

    Spline2D s = new Spline2D(points);

    // subdivide it by 8 into a list of vertices

    List vertices = s.computeVertices(8);

    noFill();

    strokeWeight(2);

    // draw a line through all the vertices

    beginShape();

    for (int i=0,num=vertices.size()-1; i

  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    10/11

    for (int i=0,num=names.size()-1; i

  • 7/22/2019 Working With #Toxiclibs - #Processing Tutorial by Amnon Owed

    11/11