Text on a circle
From Processing
| Versions: | 1.0+ |
| Contributors: | mflux |
| Started: | 2009-09-25 |
So you want to display text on an arc. Easy! The following gives you some control over how to display text on a circular path with easy-to-modify code. (Note: The kerning is probably not 100% spot on so you may have to adjust this if you want it looking perfect.)
Pseudocode
- First we gather information for the shape of the circle. So we need stuff like x and y, radius, etc.
- Next we find the circumference of a circle which is 2 * PI * Diameter.
- Dividing the text width of the word we want to render with the circumference (think of the text hugging a circle) you get an actual “percentage” of how much space the text takes up on the circle.
- For each letter in the text, find the angle on the circle where it's supposed to land.
- As we're incrementing each letter, also accumulate the text width for each letter so that we know how to space out the next letter
- Now that we have the angle and radius, we can find the X/Y position of the letter using sin/cos
- Since we have the angle, we can simply rotate each letter by the angle plus 90 degrees so it “arcs” properly.
- The final thing to watch out for is to actually rotate from the center of the text, not from the corner.
Source Code
/** arctext taken from http://wiki.processing.org/index.php/Text_on_a_circle @author mflux */ // the good stuff void arcText(String text, float x, float y, float radius, float startAngle, float arcScale, int direction){ if(g.textFont==null) return; if(text==null) return; if(text.length()<=0) return; textFont(g.textFont); float totalWidth = textWidth(text); float circumference = PI * radius * 2; pushMatrix(); translate(x,y); float widthAccumulate = 0; for(int i=0; i<text.length(); i++){ char c = text.charAt(i); float percent = widthAccumulate / circumference; float angle = radians( startAngle + percent * 360 * arcScale) * (direction>=0? 1 : -1); widthAccumulate += textWidth(c); float px = cos(angle) * radius; float py = sin(angle) * radius; pushMatrix(); translate(px,py); // this rotates from the -center- of the letter translate(textWidth(c)/2,0); rotate( angle + radians(90)); translate(-textWidth(c)/2,0); text(c, 0, 0); popMatrix(); } popMatrix(); } // the example PFont font; void setup(){ size(500,500); font = createFont("Verdana-Bold",48); smooth(); } void draw(){ background(255); fill(0); // you have to set a font first! textFont(font); float radius = mouseX; float offset = -mouseY/2; arcText("ArcText", width/2, height/2, radius, offset, 1, 1); }