Placing text along a path using Geomerative and Processing

/, Programming, Projects, Uncategorized/Placing text along a path using Geomerative and Processing

Placing text along a path using Geomerative and Processing

Introduction

In the last post here we explored placing points along an a wave path we had created all using the built in functionality of the Geomerative library. This was ultimately to allow text to be placed along the path, which is what today’s post will cover.

If you have not read the previous posts, you will require a great library for processing named “Geomerative”  (Website) by Ricard Marxer.  I have struggled to find many similar sketches online other than those included in the examples, so i figured I would share my progress with the community which has always given me so much! This post whilst keeping a log for my own future use, I hope may serve as a reference for others out there with the same aims as me.

First – Get some characters in place

So first up, lets just get some text on the points we established in the last post. This looks like:

Geromerative Text to Path No Rotation

The code to make this:

<br />
import geomerative.*;<br />
RShape wave;<br />
RFont font;</p>
<p>float plusminus =0.0;<br />
float scale = 3;<br />
String message = &quot;hello bendy world &amp;amp;gt;&amp;amp;gt;&amp;amp;gt;&quot;;<br />
int index = 0;</p>
<p>//Somwhere to store our curve points<br />
RPoint[] points;</p>
<p>void setup()<br />
{<br />
 // From the examples we must always initialise the library using this command<br />
 RG.init(this);</p>
<p> //Usual Processing Jazz<br />
 size(800 ,450);<br />
 background(255);<br />
 frameRate(25);</p>
<p> font = new RFont(&quot;Impact Label Reversed.ttf&quot;, 72, RIGHT);<br />
}</p>
<p>void draw(){<br />
 //Blank Background each frame<br />
 background(255);</p>
<p> //Create a new RShape each frame<br />
 RShape wave = new RShape();</p>
<p> //At the moment the wave object is empty, so lets add a curve:<br />
 wave.addMoveTo(0*scale, 100*scale);<br />
 wave.addBezierTo(0*scale, 100*scale, 50*scale, 25*scale, 100*scale, 100*scale);<br />
 wave.addBezierTo(100*scale, 100*scale, 150*scale, 175*scale, 200*scale, 100*scale); </p>
<p> //Lets draw away from the edges<br />
 translate(100,-80);</p>
<p> //Draw our wave<br />
 noFill();<br />
 stroke(0);<br />
 strokeWeight(60);<br />
 strokeCap(PROJECT);<br />
 wave.draw();<br />
 strokeCap(ROUND);</p>
<p> //Collect some points along the curve<br />
 RG.setPolygonizer(RG.UNIFORMLENGTH);<br />
 RG.setPolygonizerLength(35);<br />
 points = wave.getPoints(); </p>
<p> index=0; //Letter index within the string message</p>
<p> //Loop through and place a letter at each point<br />
 for(int i=0; i&amp;amp;lt;points.length-1; i++){<br />
 //Add a dot for the point<br />
 stroke(0, 90, 255); //Blue<br />
 strokeWeight(5);<br />
 point(points[i].x, points[i].y);</p>
<p> fill(255);<br />
 noStroke();</p>
<p> //Draw the current letter<br />
 pushMatrix();<br />
 translate(points[i].x, points[i].y);<br />
 //This is for centering up the font on the line<br />
 translate(5, 20);<br />
 font.draw(message.charAt(index));</p>
<p> popMatrix();</p>
<p> index++;<br />
 }<br />
}<br />
}<br />

Now, this is a good first step, but we want our lettering to follow the curves, so next we must calculate the angle of each section of curve to correctly rotate our characters.

We can do this with a simple function calculating the angle between two points. Mine simply looks something like this:

<br />
//Simple function to calculate the angle between two points<br />
float getAngle(RPoint p1, RPoint p2){<br />
 float deltax = p1.x - p2.x;<br />
 float deltay= p1.y - p2.y;</p>
<p> return atan(deltay/deltax);<br />
}<br />

Now we can rotate the canvas where we were translating with a quick call to this new function:

<br />
...<br />
 pushMatrix();<br />
 translate(points[i].x,points[i].y);<br />
 rotate(getAngle(points[i], points[i+1]));<br />
 translate(5, 20);<br />
 font.draw(message.charAt(index));<br />
 popMatrix();<br />
...<br />

Resulting in: Geromerative Text to Path - Basic Rotation

Most definitely a step in the right direction, but we still see this is not perfect, because the text character is being placed on the first point, where as the angle is being calculated between the points. The best solution would be to place the characters in the center of the two points. We can do this with some simple calculation, or better still use the built in features of the Geomerative library! So after some exploring in the Geomerative Documentation I came across the getCenter() function, perfect!

<br />
 stroke(255, 90, 0); //Orange<br />
 strokeWeight(10);<br />
 RPoint center = new RCommand(points[i], points[i+1]).getCenter();<br />
 point(center.x,center.y);<br />

Turning off the text, we are not getting:

Calculated Center Points Marked in Orange

Calculated Center Points Marked in Orange

Now we place the characters in these new center points (center.x, center.y) and use the already calculated rotation resulting in:

Geromerative Text to Path

Complete code PDE can be found here:

https://github.com/louisc/processing-standalone-sketches/blob/master/Geomerative_Text_Along_Path/Geomerative_Text_Along_Path.pde 

In Repo:

https://github.com/louisc/processing-standalone-sketches

By |2016-11-05T11:17:47+00:00June 28th, 2016|Kinetic Storyteller, Programming, Projects, Uncategorized|1 Comment

About the Author:

A PhD in Electronic Engineering. A love for photography (www.islou.co.uk). An interest in tinkering, electronics and design. (www.louisc.co.uk).

One Comment

  1. Martin Prout July 20, 2016 at 7:04 pm - Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.