Letter boundary offset

Hi all.

Newbie here. Sorry if this has been asked before but I was looking to do something like the image below. Any clues as to where to start? I have googled a lot with no luck as of yet.

Basically what I’m looking for is to get the boundaries of any text (or shape) and offset the lines outwards.
General advice on how to achieve curve offset is also appreciated.


1 Like

I’d start by trying get a set of points that I could later expand outwards. This would be relatively simple in p5.js because of the textToPoints() function. But as far as I know there’s no equivalent function in processing. If you’d still like to use processing I would suggest trying to convert your font into svgs. Then you could load in the letters as PShapes.

Once you get points or a PShape you could create the ripple effect by moving the points outwards from one another and drawing each result. I can’t think of an easy way to get the direction that you should make the points expand so you might have to try out a couple ideas. I might try drawing the shape or text to a PGraphics or p5.Graphics element and checking the color of neighboring pixels and trying to set the direction that way.

Hopefully that makes sense and gives you an idea of where you could start.

As a side not if you’d like the lines to be kinda sketchy like in your image you might checkout p5.scribble or the equivalent for Processing library handy (which hasn’t been updated for Processing 3).


thanks @figraham. very helpful indeed.

1 Like

Other than rolling your own, for Processing libraries for text manipulation check out, Geomerative, NextText (quite old), and Fontastic. I seem to recall that both Geomerative and NextText have facilities for font to point conversion.

Beyond text specifically, I would suggest implementing your tree rings as an ArrayList of points, with a simple rule – they are drawn towards the center of the screen until they collide with something, then they stop.

That gives you your basic shrink wrap effect – start your ring as a big circle or square, then walk the points in towards the center until they stop. This will cause clipping around the corners of shapes if you have low point counts, but you could add more points (or add a line collision algorithm, and inject extra points in the line) to refine that part.

class Shrinky {
  boolean stopped;
  float x;
  float y;
  ArrayList<PVector> points;
  void collide(){
  void move(float targetX; float targetY){
1 Like

Use Processing Geometry Suite to do this easily.

Offset Style = Bevel

Offset Style = Round

Offset Style = Miter

Animated Code Example

import micycle.pgs.*;

PShape letter;

void setup() {
  size(1000, 1000, FX2D);
  colorMode(HSB, 1, 1, 1, 1);
  letter = createFont(PFont.list()[(int) random(PFont.list().length)], 200, true).getShape('F');
  letter = PGS_Transformation.translateTo(letter, width / 2, height / 2);

void draw() {

  PShape offsetCurves = PGS_Contour.offsetCurvesOutward(letter, PGS_Contour.OffsetStyle.ROUND, 15 + sin(frameCount*0.02f)*8, 25);

  float hue = 0;
  final float inc = 1f / offsetCurves.getChildCount();
  for (PShape offsetCurve : offsetCurves.getChildren()) {
    offsetCurve.setStroke(color((hue+frameCount*0.01f) % 1, 0.8f, 1, 1));
    hue += inc;



Applying PGS_Morphology.fieldWarp() to offset curves.