/** * 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 + ")"); } }