/**
* Pentamorph
* Fredrik Bridell 2007-05-23
*
*
This is a sort of moving logo that I made at the request of Ingvar Sjöberg. * It's a pentagon with an inscribed shape that moves from a point in the center * to an inscribed pentagram, upside-down compeared to the outer one. * About halfway through the inner shape becomes a pentagram. * *
This code is really ugly, but it works. * *
Click to focus, then use keyboard:
* SPACE - pause
* e - toggle easing
* t - toggle trails
*
*/
Point A, B, C, D, E, F; // corners of the outer pentagon, clockwise from top (A-E) and center (F)
Point AB, BC, CD, DE, EA; // middle of sides of outer pentagon
Point a, b, c, d, e; // the moving points, clockwise from the outer points
float t=0.0; // parameter that controls the inner shape, goes from 0 to 1!
float dt=0.01; // the "velocity of t"
int outer; // length from center to A
// settings
// easing adjusts the speed of the motion depending on where it is
boolean easing=false;
// trails enables trails
boolean trails=false;
boolean pause=false; // set to true to pause
// set up the screen and calculate all the corner points and mid points
void setup(){
size(300, 300);
smooth();
int outer=int(min(width, height)*0.4);
F = new Point(width/2, height/2);
float c1 = cos (2.0*PI/5.0);
float c2 = cos (PI/5.0);
float s1 = sin (2.0*PI/5.0);
float s2 = sin(4.0*PI/5.0);
float C1 = outer*c1;
float C2 = outer*c2;
float S1 = outer*s1;
float S2 = outer*s2;
A = new Point(F.x, F.y-outer);
B = new Point(F.x+S1, F.y-C1);
C = new Point(F.x+S2, F.y+C2);
D = new Point(F.x-S2, F.y+C2);
E = new Point(F.x-S1, F.y-C1);
AB = new Point(A, B); // a point halfway between A and B
BC = new Point(B, C);
CD = new Point(C, D);
DE = new Point(D, E);
EA = new Point(E, A);
a = new Point(F);
b = new Point(F);
c = new Point(F);
d = new Point(F);
e = new Point(F);
}
// draws a frame
void draw(){
if (!pause){
if(trails){
fill(255, 255, 255, 32);
noStroke();
rect(0, 0, width, height);
}
else {
background(255); // clear
}
stroke(0);
strokeWeight(3);
// outer:
line(A, B);
line(B, C);
line(C, D);
line(D, E);
line(E, A);
if (easing){
t=t+dt*(0.5+2.0*abs(t)); // with easing
}
else {
t=t+dt; // no easing
}
if (t>1){
dt=-dt;
}
if(t<-0){
dt=-dt;
}
a.x = int(t*F.x + (1.0-t)*AB.x);
a.y = int(t*F.y + (1.0-t)*AB.y);
b.x = int(t*F.x + (1.0-t)*BC.x);
b.y = int(t*F.y + (1.0-t)*BC.y);
c.x = int(t*F.x + (1.0-t)*CD.x);
c.y = int(t*F.y + (1.0-t)*CD.y);
d.x = int(t*F.x + (1.0-t)*DE.x);
d.y = int(t*F.y + (1.0-t)*DE.y);
e.x = int(t*F.x + (1.0-t)*EA.x);
e.y = int(t*F.y + (1.0-t)*EA.y);
line(A, a);
line(B, b);
line(C, c);
line(D, d);
line(E, e);
line(A, e);
line(E, d);
line(D, c);
line(C, b);
line(B, a);
line(a, b);
line(b, c);
line(c, d);
line(d, e);
line(e, a);
}
}
// convenience method to draw a line between two Points
void line(Point a, Point b){
line(a.x, a.y, b.x, b.y);
}
// handle keyboard to change settings (click first!)
void keyPressed(){
switch(key){
case ' ': // space=pause
pause=!pause;
break;
case 't': // toggle trails
trails=!trails;
break;
case 'e': // toggle easing
easing=!easing;
break;
}
}
class Point {
int x, y;
// constructor
Point(){
this(0,0);
}
/* constructor */
Point(int x, int y){
this.x=x;
this.y=y;
}
// constructor from floats
Point(float x, float y){
this((int) x, (int) y);
}
// constructor from two points, creates a new one in the middle
Point(Point P, Point Q){
this((P.x+Q.x)/2.0, (P.y+Q.y)/2.0);
}
// constructor, creates a copy of another point
Point(Point P){
this(P.x, P.y);
}
String toString(){
return ("Point (" + x + ", " + y + ")");
}
}