/* * Rendering of a great seal as a circle, with individual letters * of a given string rendered around a circle center. * * Sketch by Michael Goldwasser */ void setup() { size(600, 600); background(255); // move origin to center of canvas translate(0.5*width, 0.5*height); // let's start by drawing the annulus float outerRadius = 0.45 * width; float innerRadius = 0.3 * width; float annulusHeight = outerRadius - innerRadius; float textPct = 0.6; // percentage of annulus float textHeight = textPct*annulusHeight; float textPadding = 0.5*(annulusHeight - textHeight); fill(0, 26, 162); ellipse(0, 0, 2*outerRadius, 2*outerRadius); fill(237, 233, 217); ellipse(0, 0, 2*innerRadius, 2*innerRadius); // now let's render text on the annulus PFont custom = createFont("LucidaGrande-Bold", textHeight); // I don't like the default font textFont(custom); textSize(textHeight); fill(134, 132, 113); // horizontally centered around 1.5*PI, facing inward // intentionally double space between words for better separation // (as textWidth(" ") seems too small) textArc("UNIVERSITAS SANCTI LUDOVICI", innerRadius + 1.25*textPadding, 0.8*PI, 2.2*PI, false); // horizontally centered around 0.5*PI, facing outward textArc("1818", outerRadius - 1.25*textPadding, 0.4*PI, 0.6*PI, true); } void draw() { } /* * Render the message with baseline along a circular arc around the origin. * if faceOutward is true, bottom of letters will be farther from center. * * This version lays out characters proportional to their widths, for more * consistent interletter spacing. */ void textArc(String msg, float radius, float startAngle, float stopAngle, boolean faceOutward) { textAlign(CENTER, BASELINE); int numChars = msg.length(); // first calculate total width of each character float total = 0.0; for (int j=0; j < numChars; j++) { total += textWidth(msg.charAt(j)); } // now go through all characters again and set angle based on proportions float subtotal = 0.0; for (int j=0; j < numChars; j++) { float w = textWidth(msg.charAt(j)); float percent = (0.5*w + subtotal)/total; // include half of character for placement subtotal += w; float theta; if (faceOutward) { theta = stopAngle - percent * (stopAngle - startAngle); } else { theta = startAngle + percent * (stopAngle - startAngle); } // time to render msg.charAt(j) pushMatrix(); translate(radius*cos(theta), radius*sin(theta)); rotate(theta + HALF_PI); // so character at top is normally aligned if (faceOutward) { rotate(PI); } text(msg.charAt(j), 0, 0); popMatrix(); } }