/* * Model for a circle rolling inside a larger circle, * akin to classic Spirograph drawings. * * Pressing the space bar clears the screen. * * Pressing 'c' key picks random pen color. * * Author: Michael Goldwasser */ int MAX = 100000; // arbitrary, and maybe not big enough float innerRadius; // for inner circle float penRadius; // dist of pen from circle center color penColor = color(255,0,0); float tIncr = 3.0; float t; // units of travel for point on inner circle boundary float[] penX = new float[MAX]; // points of traced polyline float[] penY = new float[MAX]; color[] penC = new color[MAX]; int numPoints; void setup() { size(600,600); innerRadius = 0.295 * width; penRadius = 0.9 * innerRadius; reset(); } void reset() { t = 0; numPoints = 0; loop(); } void keyPressed() { if (key == ' ') { numPoints = 0; } else if (key == 'c') { penColor = color(random(255),random(255),random(255)); } } void draw() { // update model of rolling circle. // We assume initial condition is with inner circle // below center and pen downward. float outerRotations = t/(PI*width); // circumference is P*width float outerTheta = TWO_PI * outerRotations; float innerRotations = -t/(TWO_PI*innerRadius); float innerTheta = TWO_PI * innerRotations; float innerGap = 0.5*width - innerRadius; // first calculate (cx,cy) for center of inner circle float cx = 0.5*width + innerGap*cos(outerTheta); float cy = 0.5*width + innerGap*sin(outerTheta); // next calculate pen location, relative to inner center penX[numPoints] = cx + penRadius*cos(innerTheta); penY[numPoints] = cy + penRadius*sin(innerTheta); penC[numPoints] = penColor; numPoints++; t += tIncr; if (numPoints == MAX) { noLoop(); // stop } // now its time to render the current state background(255); // draw outer circle stroke(0); strokeWeight(1); ellipse(0.5*width, 0.5*width, width, width); // draw the inner circle and pen point fill(200,200,255); ellipse(cx, cy, 2*innerRadius, 2*innerRadius); stroke(penColor); strokeWeight(8); point(penX[numPoints-1], penY[numPoints-1]); // draw the traced pen path strokeWeight(1); noFill(); beginShape(); stroke(penC[0]); for (int j=0; j < numPoints; j++) { if (j > 0 && penC[j] != penC[j-1]) { endShape(); stroke(penC[j]); beginShape(); } vertex(penX[j], penY[j]); } endShape(); }