### Working with Toxiclibs

Hey everyone! Working on some projects, more soon! Right now I’d like to share two Toxiclibs code examples I made to learn this excellent library by Karsten Schmidt. Both were made in response to questions posted in the Processing forum. The first example deals with picking and dragging shapes, the second with making shapes explode. As it turns out, Toxiclibs has many useful functions to realise these things quickly, clearly and efficiently. The first example makes use of the basic functionalities. The second example uses more adventurous options such as physics-based particles and Voronoi tessellation. Creating these examples also allowed me to brush up on my vector skills since Toxiclibs has an advanced Vec2D class with many additional options for vector math manipulations. So I definitely learned a few things from making these examples and I hope they’re useful for others as well.

Example 1: Creating, Picking & Dragging Shapes
This is a pretty basic example but it contains a few interesting facets. With the Toxiclibs library, specifically the containsPoint function, it’s very easy to check if a certain point is within a shape. This is useful for many different things, but picking is definitely one of them. This function exists for all the Shape2D shapes, so it can be used quite broadly. In this example you can create, pick and drag Polygon2D shapes. When creating a shape, the left mouse button only adds a point, while the right mouse button finalizes the shape once there are more than two points. So if you only want to make triangles, just keep using the right mouse button. With regard to keys: space clears everything, d deletes the shape under the mouse and x deletes the last point. There are a lot of little tricks and solutions to make everything work as intended, check the full commented code to find out. You can copy-paste and run it in Processing’s pde directly.

```import toxi.geom.*;
import toxi.processing.*;

ArrayList <Polygon2D> polygons = new ArrayList <Polygon2D> ();
ArrayList <Vec2D> points = new ArrayList <Vec2D> ();
int draggedPolygon = -1;
ToxiclibsSupport gfx;
boolean onPolygon;
Vec2D mouse;

void setup() {
size(1280,720);
gfx = new ToxiclibsSupport(this);
noStroke();
smooth();
}

void draw() {
background(255);
mouse = new Vec2D(mouseX,mouseY);

// (re)set onPolygon to false
onPolygon = false;

// draw all the polygons
for (Polygon2D p : polygons) {
if (p.containsPoint(mouse)) {
// if the mouse is over a polygon...
// set onPolygon to true and color it red
onPolygon = true;
fill(255,0,0);
} else {
fill(0);
}
gfx.polygon2D(p);
}

// draw all the points
fill(0);
for (Vec2D p : points) {
ellipse(p.x,p.y,5,5);
}
}

void mousePressed() {
// if the mouse is NOT on a polygon
if (!onPolygon) {
// add a point at mouseX,mouseY
// if the right mouse button is pressed
// and there are more than 2 points
if (mouseButton == RIGHT && points.size() > 2) {
// create a polygon from the points
// clear the points
points.clear();
}
}
}

void mouseDragged() {
// if no polygon is selected
if (draggedPolygon == -1) {
// check if the mouse is on a polygon
for (int i=0; i<polygons.size(); i++) {
if (polygons.get(i).containsPoint(mouse)) {
// if so, set this to be the selected polygon
draggedPolygon = i;
}
}
// if a polygon is selected
} else {
// set change amount to the movement of the mouse
Vec2D change = new Vec2D(mouseX-pmouseX,mouseY-pmouseY);
// get the selected polygon
Polygon2D p = polygons.get(draggedPolygon);
// add the change to all of it's individual points
for (Vec2D v : p.vertices) {
}
}
}

void mouseReleased() {
// on mouse release reset to 'no polygon selected'
draggedPolygon = -1;
}

void keyPressed() {
// clear all points and polygons
if (key == ' ' && !mousePressed) {
points.clear();
polygons.clear();
}
// delete the polygon under the mouse
if (key == 'd' && !mousePressed) {
for (int i=polygons.size()-1; i>=0; i--) {
if (polygons.get(i).containsPoint(mouse)) {
polygons.remove(i);
}
}
}
// remove the last point (if points > 0)
if (key == 'x') {
if (points.size() > 0) {
points.remove(points.size()-1);
}
}
}
```

Example 2: Exploding Circles (Voronoi style)
The next example is in many ways more advanced. First, it deals with physics and verletParticles to create a lot of different-sized circles all within a system of counteracting forces, where the force of each particle is in line with the radius of that circle. Most of this is handled internally by the Toxiclibs library. So that’s step one. The next step is the creative destruction of a circle. Once the breaking commences, the “circle” is divided in many segments using Voronoi tessellation. Currently the only polygon clipping available in the Toxiclibs library, is rectangular. Therefore I’ve used some vector tricks to clip points outside the radius of the circle. The different fragments are loaded into an arrayList of Polygon2D shapes that move away from their initial position. To make things visually more interesting, the fragments move away at different speeds and more importantly their direction depends on the relative angle to the point-of-impact. In addition, the point-of-impact influences the Voronoi tessellation. Close to the impact there are multiple, smaller fragments, while further away the fragments get bigger. All in all this creates a fairly realistic and interesting destruction.

A few things keep the sketch running at a decent framerate. First of all, only breaking shapes are made out of Voronoi fragments. Secondly, the transparency of the breaking shape starts decreasing after a few frames. Once it is completely invisible, it’s removed entirely. This makes the code fairly efficient, although it is always possible to further optimize of course. For convenience, I’ve placed everything in one class. The showcase sketch starts with a single shape in the center of the screen. Click somewehere on the circle to make it explode. As stated before, the point-of-impact determines the tessellation and the direction of the moving fragments. For every shape that is removed, two shapes return! So things will get crowdy real soon. Therefore I’ve maximized the amount of circles on the screen. Below is the full commented code for both the main program and the BreakCircle class. Copy-paste them both in Processing’s pde and you will be able to run this example.

Main Program

```import toxi.geom.*;
import toxi.geom.mesh2d.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;
import toxi.util.datatypes.*;
import toxi.processing.*;

ArrayList <BreakCircle> circles = new ArrayList <BreakCircle> ();
VerletPhysics2D physics;
ToxiclibsSupport gfx;
Vec2D origin, mouse;

int maxCircles = 90; // maximum amount of circles on the screen
int numPoints = 50;  // number of voronoi points / segments
int minSpeed = 2;    // minimum speed of a voronoi segment
int maxSpeed = 14;   // maximum speed of a voronoi segment

void setup() {
size(1280,720);
smooth();
noStroke();
gfx = new ToxiclibsSupport(this);
physics = new VerletPhysics2D();
physics.setDrag(0.05f);
physics.setWorldBounds(new Rect(0,0,width,height));
radius = new BiasedFloatRange(30, 100, 30, 0.6f);
origin = new Vec2D(width/2,height/2);
reset();
}

void draw() {
background(255,0,0);
physics.update();

mouse = new Vec2D(mouseX,mouseY);
for (BreakCircle bc : circles) {
bc.run();
}
}

for (int i=circles.size()-1; i>=0; i--) {
// if a circle is invisible, remove it...
if (circles.get(i).transparency < 0) {
circles.remove(i);
// and add two new circles (if there are less than maxCircles)
if (circles.size() < maxCircles) {
}
}
}
}

void keyPressed() {
if (key == ' ') { reset(); }
}

void reset() {
// remove all physics elements
for (BreakCircle bc : circles) {
physics.removeParticle(bc.vp);
physics.removeBehavior(bc.abh);
}
// remove all circles
circles.clear();
}
```

BreakCircle class

```class BreakCircle {
ArrayList <Polygon2D> polygons = new ArrayList <Polygon2D> ();
Voronoi voronoi;
FloatRange xpos, ypos;
PolygonClipper2D clip;
float[] moveSpeeds;
Vec2D pos, impact;
int transparency;
int start;
VerletParticle2D vp;
AttractionBehavior abh;
boolean broken;

this.pos = pos;
vp = new VerletParticle2D(pos);
}

void run() {
// for regular (not broken) circles
if (!broken) {
moveVerlet();
displayVerlet();
checkBreak();
// if the circle is broken
} else {
moveBreak();
displayBreak();
}
}

// set position based on the particle in the physics system
void moveVerlet() {
pos = vp;
}

// display circle
void displayVerlet() {
fill(255);
}

// if the mouse is pressed on a circle, it will be broken
void checkBreak() {
// remove particle + behavior in the physics system
physics.removeParticle(vp);
physics.removeBehavior(abh);
// point of impact is set to mouseX,mouseY
impact = mouse;
initiateBreak();
}
}

void initiateBreak() {
broken = true;
transparency = 255;
start = frameCount;
// create a voronoi shape
voronoi = new Voronoi();
// set biased float ranges based on circle position, radius and point of impact
// set clipping based on circle position and radius
}

// add random points (biased towards point of impact) to the voronoi
for (int i=0; i<numPoints; i++) {
}
// generate polygons from voronoi segments
for (Polygon2D poly : voronoi.getRegions()) {
// clip them based on the rectangular clipping
poly = clip.clipPolygon(poly);
for (Vec2D v : poly.vertices) {
// if a point is outside the circle
// scale it's distance from the center to the radius
clipPoint(v);
}
}
}
}

// generate random speeds for all polygons
moveSpeeds = new float[polygons.size()];
for (int i=0; i<moveSpeeds.length; i++) {
moveSpeeds[i] = random(minSpeed,maxSpeed);
}
}

// move polygons away from the point of impact at their respective speeds
void moveBreak() {
for (int i=0; i<polygons.size(); i++) {
Polygon2D poly = polygons.get(i);
Vec2D centroid = poly.getCentroid();
Vec2D targetDir = centroid.sub(impact).normalize();
targetDir.scaleSelf(moveSpeeds[i]);
for (Vec2D v : poly.vertices) {
}
}
}

// draw the polygons
void displayBreak() {
// after 12 frames, start decreasing the transparency
if (frameCount-start > 12) { transparency -= 7; }
fill(255,transparency);
for (Polygon2D poly : polygons) {
gfx.polygon2D(poly);
}
}

void clipPoint(Vec2D v) {
v.subSelf(pos);
v.normalize();
}
}
```
7 Responses to “Working with Toxiclibs”
1. toxi says:

That’s my Easter present! 🙂 Can’t thank you enough for doing this, Amnon! 10^3 thanks! Both are very good & clear examples and it’d be amazing if I could bundle them (fully credited) with the libs starting with the next release…

• Amnon says:

Absolutely, that would be great. Can’t wait for the next release. Hopefully I can make some more cool stuff with it in the future, be it code examples, interesting visuals or both. Thank YOU for all the hard work on the libs! 🙂

2. felix says:

The Voronoi explosions are great!

• Amnon says:

Thanks Felix! In the next release of Toxiclibs it should be even easier, cause there will be custom polyon clipping. I’ll probably do some more destruction then. 😉

3. peripecio says:

Hiperguay!

• Amnon says:

I looked up that word to find out that it means ‘supercool’ in Spanish… so thanks! 😉