import processing.pdf.*;
boolean bRecordingPDF = false;
float inch = 72;
float diamArtInner = inch * 1.50;
float diamArtOuter = inch * 4.80;
float diamCutInner = inch * 1.41;
float diamCutOuter = inch * 4.875;
float holeDy = inch * 0.23;
float holeDx = inch * 0.20;
float holeD = inch * 0.1;
final int nFrames = 10;
int myFrameCount = 0;
int exportFrameCount = 0;
boolean bAnimate = true;
boolean bExportFrameImages = false;
//-------------------------------------------------------
void setup() {
size(792, 612); // 11x8.5" at 72DPI
frameRate(15);
smooth();
}
//-------------------------------------------------------
void draw() {
background(240);
if (bRecordingPDF) {
beginRecord(PDF, "praxinoscope-output.pdf");
}
// Do all the drawing.
pushMatrix();
translate(width/2, height/2);
drawCutLines();
drawGuides();
drawAllFrames();
popMatrix();
if (bExportFrameImages) {
// If activated, export .PNG frames
if (exportFrameCount < nFrames) { String filename = "frame_" + nf((exportFrameCount%nFrames), 3) + ".png"; saveFrame("frames/" + filename); println("Saved: " + filename); exportFrameCount++; if (exportFrameCount >= nFrames) {
bExportFrameImages = false;
exportFrameCount = 0;
}
}
}
if (bRecordingPDF) {
endRecord();
bRecordingPDF = false;
}
}
//-------------------------------------------------------
void keyPressed() {
switch (key) {
case ' ':
// Press spacebar to pause/unpause the animation.
bAnimate = !bAnimate;
break;
case 'p':
case 'P':
// Press 'p' to export a PDF for the Praxinoscope.
bRecordingPDF = true;
break;
case 'f':
case 'F':
// Press 'f' to export .png Frames (to make an animated .GIF)
myFrameCount = 0;
exportFrameCount = 0;
bExportFrameImages = true;
bAnimate = true;
break;
}
}
//-------------------------------------------------------
void drawCutLines() {
fill(0);
textAlign(CENTER, BOTTOM);
text("Praxinoscope Template", 0, 0-diamCutOuter/2-6);
stroke(0);
strokeWeight(1.0);
noFill();
if (!bRecordingPDF) {
fill(255);
}
ellipse(0, 0, diamCutOuter, diamCutOuter);
noFill();
if (!bRecordingPDF) {
fill(240);
}
ellipse(0, 0, diamCutInner, diamCutInner);
noFill();
ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD);
line (diamCutInner/2, 0, diamCutOuter/2, 0);
}
//-------------------------------------------------------
void drawGuides() {
// This function draws the guidelines.
// Don't draw these when we're exporting the PDF.
if (!bRecordingPDF) {
noFill();
stroke(128);
strokeWeight(0.2);
ellipse(0, 0, diamArtInner, diamArtInner);
ellipse(0, 0, diamArtOuter, diamArtOuter);
for (int i=0; i<nFrames; i++) {
float angle = map(i, 0, nFrames, 0, TWO_PI);
float pxi = diamArtInner/2 * cos(angle);
float pyi = diamArtInner/2 * sin(angle);
float pxo = diamArtOuter/2 * cos(angle);
float pyo = diamArtOuter/2 * sin(angle);
stroke(128);
strokeWeight(0.2);
line (pxi, pyi, pxo, pyo);
}
// Draw the red wedge outline, highlighting the main view.
int redWedge = 7; // assuming nFrames = 10
for (int i=redWedge; i<=(redWedge+1); i++) {
float angle = map(i, 0, nFrames, 0, TWO_PI);
float pxi = diamArtInner/2 * cos(angle);
float pyi = diamArtInner/2 * sin(angle);
float pxo = diamArtOuter/2 * cos(angle);
float pyo = diamArtOuter/2 * sin(angle);
stroke(255, 0, 0);
strokeWeight(2.0);
line (pxi, pyi, pxo, pyo);
}
noFill();
stroke(255, 0, 0);
strokeWeight(2.0);
float startAngle = redWedge*TWO_PI/nFrames;
float endAngle = (redWedge+1)*TWO_PI/nFrames;
arc(0, 0, diamArtInner, diamArtInner, startAngle, endAngle);
arc(0, 0, diamArtOuter, diamArtOuter, startAngle, endAngle);
for (int i=0; i<nFrames; i++) {
float angle = map(i, 0, nFrames, 0, TWO_PI);
pushMatrix();
rotate(angle);
float originY = ((diamArtOuter + diamArtInner)/2)/2;
translate(0, 0-originY);
noFill();
stroke(128);
strokeWeight(0.2);
line (-inch/2, 0, inch/2, 0);
line (0, -inch/2, 0, inch/2);
popMatrix();
}
}
}
//-------------------------------------------------------
void drawAllFrames() {
for (int i=0; i<nFrames; i++) {
float angle = map(i, 0, nFrames, 0, TWO_PI);
float originY = ((diamArtOuter + diamArtInner)/2)/2;
pushMatrix();
rotate(angle);
translate(0, 0-originY);
scale(0.8, 0.8); // feel free to ditch this
int whichFrame = i;
if (bAnimate) {
whichFrame = (i+myFrameCount)%nFrames;
}
drawArtFrame (whichFrame);
// drawArtFrameAlternate (whichFrame);
popMatrix();
}
myFrameCount++;
}
//-------------------------------------------------------
void drawArtFrame (int whichFrame) {
// Draw the artwork for a generic frame of the Praxinoscope,
// given the framenumber (whichFrame) out of nFrames.
// NOTE #1: The "origin" for the frame is in the center of the wedge.
// NOTE #2: Remember that everything will appear upside-down!
// Draw the frame number
fill(0);
noStroke();
// Draw a pulsating ellipse
noFill();
stroke(0);
strokeWeight(1);
float t = map(whichFrame, 0, nFrames, 0, 1);
float diam = map(cos(t*TWO_PI), -1, 1, 25, 50);
ellipse(0, 0, diam, diam);
//rotating circle
float radius = diam/2;
float rotatingArmAngle = (whichFrame*.1) * TWO_PI;
float px = 0 + radius*cos(rotatingArmAngle);
float py = 0 + radius*sin(rotatingArmAngle);
fill (0);
stroke(51);
ellipse(px, py, 8, 8);
//rotating circle
float rotatingArmAngle2 = (whichFrame*.1) * TWO_PI;
float px2 = 15 + radius*cos(rotatingArmAngle2);
float py2 = 15 + radius*sin(rotatingArmAngle2);
fill (0);
stroke(51);
ellipse(-px2, -py2, 8, 8);
float px3 = -12 + radius*cos(rotatingArmAngle2);
float py3 = -20 + radius*sin(rotatingArmAngle2);
fill (0);
stroke(51);
ellipse(-px3, -py3, 8, 8);
//rect figure
float amplitude=100;
float f=.1;
float xR=160;
float yR=(160)+amplitude*sin(f*whichFrame);
rect(xR,yR,10,10);
}
//-------------------------------------------------------
void drawArtFrameAlternate(int whichFrame) {
// An alternate drawing test.
// Draw a falling object.
// Draw a little splat on the frame when it hits the ground.
if (whichFrame == (nFrames-1)) {
stroke(0, 0, 0);
strokeWeight(0.5);
int nL = 10;
for (int i=0; i<nL; i++) {
float a = HALF_PI + map(i, 0, nL-1, 0, TWO_PI);
float cx = 12 * cos(a);
float cy = 10 * sin(a);
float dx = 16 * cos(a);
float dy = 13 * sin(a);
line (cx, 45+cy, dx, 45+dy);
}
}
// Draw a little box frame
fill(255);
stroke(0, 0, 0);
strokeWeight(1);
rect(-5, -50, 10, 100);
// Make the puck accelerate downward
float t = map(whichFrame, 0, nFrames-1, 0, 1);
float t2 = pow(t, 2.0);
float rh = 8 + whichFrame * 0.5; // wee stretch
float ry = map(t2, 0, 1, 0, 100-rh) - 50;
noStroke();
fill(0, 0, 0);
rect(-5, ry, 10, rh);
} |