# Using fisica and geomerative to add physics to typography

**URL:** <https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225>\
**Category:** Libraries\
**Created:** [May 23, 2020, 11:48pm UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225 "2020-05-23T23:48:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![hiphophooray](https://avatars.discourse-cdn.com/v4/letter/h/45deac/32.png) [@hiphophooray](https://discourse.processing.org/u/hiphophooray)\
**Post date:** [May 23, 2020, 11:48pm UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/1 "2020-05-23T23:48:15Z")

</div>

Hi guys.

I have this idea for a project but I can’t really figured it out and the documentation for both of these libraries (fisica and geomerative) that I want to use are not that good. Does anyone know how can this be in the easiest way possible?

Thanks! 🙂

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 24, 2020, 5:04am UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/2 "2020-05-24T05:04:52Z")

</div>

> [@hiphophooray](#):
>
> Does anyone know how can this be in the easiest way possible?

It depends.

What kind of physics to what kind of typography?

---

<div class="post-metadata">

**Author:** ![hiphophooray](https://avatars.discourse-cdn.com/v4/letter/h/45deac/32.png) [@hiphophooray](https://discourse.processing.org/u/hiphophooray)\
**Post date:** [May 24, 2020, 7:47am UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/3 "2020-05-24T07:47:55Z")

</div>

Some very simple collision. I want to have a static text in the bottom of my canvas and lets say I have in every x frames a new FCircle (that is not static) at the top of my canvas. When it comes down I want this circle to collide with the text. Don’t know if I made it clear.

Thanks for quick answer Jeremy! 🙂

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 24, 2020, 5:37pm UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/4 "2020-05-24T17:37:28Z")

</div>

There are several ways of doing this. The collision detection itself you can do without a physics engine – you just need a vertex list for the letter forms. Do you need additional physics, or just a bouncing ball that reacts to letter shapes?

If you don’t need additional physics, then you can create the effect you want by combining these two things:

1. This geomerative example: Tutorial\_07\_HelloWorld\_getPoints.pde

2. polygon-circle collision detection. [http://jeffreythompson.org/collision-detection/poly-circle.php](http://jeffreythompson.org/collision-detection/poly-circle.php)

Your list of letter points is the polygon. Run it through the polygon-circle collision algorithm to check whether the circle is colliding. Then bounce the ball (or whatever action you choose).

Here is a simple demo with a mouse.

```auto
/**
 * LetterCollisions
 * 2020-05-24 Jeremy Douglass - Processing 3.5.4
 * https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/2
 * 
 * Move the mouse over letters to test collision detection.
 *
 * Combines:
 * 1. This geomerative example: Tutorial_07_HelloWorld_getPoints.pde
 * 2. polygon-circle collision detection. http://jeffreythompson.org/collision-detection/poly-circle.php
 */

import geomerative.*;

// Declare the objects we are going to use, so that they are accesible from setup() and from draw()
RFont f;
RShape grp;
RPoint[] points;

void setup() {
  // Initilaize the sketch
  size(600, 400);
  frameRate(24);

  // Choice of colors
  background(255);
  fill(255, 102, 0);
  stroke(0);

  // VERY IMPORTANT: Allways initialize the library in the setup
  RG.init(this);

  // Load the font file we want to use (the file must be in the data folder in the sketch floder), with the size 60 and the alignment CENTER
  grp = RG.getText("Hello world!", "FreeSans.ttf", 90, CENTER);

  // Enable smoothing
  smooth();
}

void draw() {
  // Clean frame
  background(255);

  // Set the origin to draw in the middle of the sketch
  int xoff = width/2;
  int yoff = 3*height/5;
  translate(xoff, yoff);

  // express mouse in new coordinates
  int mx = mouseX-xoff;
  int my = mouseY-yoff;
  boolean hit = false;
  
  // Draw the group of shapes
  noFill();
  stroke(0, 0, 200, 150);
  RG.setPolygonizer(RG.ADAPTATIVE);
  grp.draw();

  // Get the points on the curve's shape
  //RG.setPolygonizer(RG.UNIFORMSTEP);
  //RG.setPolygonizerStep(map(float(mouseY), 0.0, float(height), 0.0, 1.0));

  RG.setPolygonizer(RG.UNIFORMLENGTH);
  RG.setPolygonizerLength(8); // set gap in px between points around letter
  
  // Loop over individual letters in group
  // and process their points separately
  for (int c=0; c<grp.children.length; c++) {
    points = grp.children[c].getPoints();
    // If there are any points
    if (points != null) {
      // draw the letter outline
      fill(0, 200, 0, 32);
      stroke(0, 200, 0);
      beginShape();
      for (int i=0; i<points.length; i++) {
        vertex(points[i].x, points[i].y);
      }
      endShape();

      // draw box on each vertex
      stroke(0, 128, 0);
      for (int i=0; i<points.length; i++) {
        rect(points[i].x-1, points[i].y-1, 3, 3);
      }
      
      // check for mouse collision with this letter
      // record a hit if mouse is touching this letter
      // and use it for drawing later
      if(polyCircle(points, mx, my, 10)) hit=true;
    }
  }
  // draw the mouse is hit(red) or not(blue)
  if(hit) fill(255,0,0,64);
  else fill(0,0,255,64);
  ellipse(mx, my, 20, 20);
}

// PolyCircle collision functions adapted from:
// http://jeffreythompson.org/collision-detection/poly-circle.php
// 1. replace "PVector" with "RPPoint"
// 2. remove "closest point" circle display

// POLYGON/CIRCLE
boolean polyCircle(RPoint[] vertices, float cx, float cy, float r) {

  // go through each of the vertices, plus
  // the next vertex in the list
  int next = 0;
  for (int current=0; current<vertices.length; current++) {

    // get next vertex in list
    // if we've hit the end, wrap around to 0
    next = current+1;
    if (next == vertices.length) next = 0;

    // get the RPoints at our current position
    // this makes our if statement a little cleaner
    RPoint vc = vertices[current]; // c for "current"
    RPoint vn = vertices[next]; // n for "next"

    // check for collision between the circle and
    // a line formed between the two vertices
    boolean collision = lineCircle(vc.x,vc.y, vn.x,vn.y, cx,cy,r);
    if (collision) return true;
  }

  // the above algorithm only checks if the circle
  // is touching the edges of the polygon – in most
  // cases this is enough, but you can un-comment the
  // following code to also test if the center of the
  // circle is inside the polygon

  // boolean centerInside = polygonPoint(vertices, cx,cy);
  // if (centerInside) return true;

  // otherwise, after all that, return false
  return false;
}

// LINE/CIRCLE
boolean lineCircle(float x1, float y1, float x2, float y2, float cx, float cy, float r) {

  // is either end INSIDE the circle?
  // if so, return true immediately
  boolean inside1 = pointCircle(x1,y1, cx,cy,r);
  boolean inside2 = pointCircle(x2,y2, cx,cy,r);
  if (inside1 || inside2) return true;

  // get length of the line
  float distX = x1 - x2;
  float distY = y1 - y2;
  float len = sqrt( (distX*distX) + (distY*distY) );

  // get dot product of the line and circle
  float dot = ( ((cx-x1)*(x2-x1)) + ((cy-y1)*(y2-y1)) ) / pow(len,2);

  // find the closest point on the line
  float closestX = x1 + (dot * (x2-x1));
  float closestY = y1 + (dot * (y2-y1));

  // is this point actually on the line segment?
  // if so keep going, but if not, return false
  boolean onSegment = linePoint(x1,y1,x2,y2, closestX,closestY);
  if (!onSegment) return false;

  // optionally, draw a circle at the closest point
  // on the line
  //////fill(255,0,0);
  //////noStroke();
  //////ellipse(closestX, closestY, 20, 20);
  
  // get distance to closest point
  distX = closestX - cx;
  distY = closestY - cy;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // is the circle on the line?
  if (distance <= r) {
    return true;
  }
  return false;
}

// LINE/POINT
boolean linePoint(float x1, float y1, float x2, float y2, float px, float py) {

  // get distance from the point to the two ends of the line
  float d1 = dist(px,py, x1,y1);
  float d2 = dist(px,py, x2,y2);

  // get the length of the line
  float lineLen = dist(x1,y1, x2,y2);

  // since floats are so minutely accurate, add
  // a little buffer zone that will give collision
  float buffer = 0.1; // higher # = less accurate

  // if the two distances are equal to the line's
  // length, the point is on the line!
  // note we use the buffer here to give a range, rather
  // than one #
  if (d1+d2 >= lineLen-buffer && d1+d2 <= lineLen+buffer) {
    return true;
  }
  return false;
}

// POINT/CIRCLE
boolean pointCircle(float px, float py, float cx, float cy, float r) {
  
  // get distance between the point and circle's center
  // using the Pythagorean Theorem
  float distX = px - cx;
  float distY = py - cy;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // if the distance is less than the circle's 
  // radius the point is inside!
  if (distance <= r) {
    return true;
  }
  return false;
}

// POLYGON/POINT
// only needed if you're going to check if the circle
// is INSIDE the polygon
boolean polygonPoint(RPoint[] vertices, float px, float py) {
  boolean collision = false;

  // go through each of the vertices, plus the next
  // vertex in the list
  int next = 0;
  for (int current=0; current<vertices.length; current++) {

    // get next vertex in list
    // if we've hit the end, wrap around to 0
    next = current+1;
    if (next == vertices.length) next = 0;

    // get the RPoints at our current position
    // this makes our if statement a little cleaner
    RPoint vc = vertices[current]; // c for "current"
    RPoint vn = vertices[next]; // n for "next"

    // compare position, flip 'collision' variable
    // back and forth
    if (((vc.y > py && vn.y < py) || (vc.y < py && vn.y > py)) &&
         (px < (vn.x-vc.x)*(py-vc.y) / (vn.y-vc.y)+vc.x)) {
            collision = !collision;
    }
  }
  return collision;
}

```

 ![LetterCollisions--screenshot](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/ab680929b6cb5b28cb8c84957de045ff416e936b.png)

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 24, 2020, 5:39pm UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/5 "2020-05-24T17:39:20Z")

</div>

You may also be interested in reading the past posts of @lolonulu, who has done a lot of work with the geomerative library and text vertex data.

---

<div class="post-metadata">

**Author:** ![hiphophooray](https://avatars.discourse-cdn.com/v4/letter/h/45deac/32.png) [@hiphophooray](https://discourse.processing.org/u/hiphophooray)\
**Post date:** [May 24, 2020, 9:11pm UTC](https://discourse.processing.org/t/using-fisica-and-geomerative-to-add-physics-to-typography/21225/6 "2020-05-24T21:11:36Z")

</div>

Thank you @jeremydouglass and @lolonulu, you guys are amazing.
