Ico.pde
1 // LED Icosahedron visual prototype, via Adafruit Industries 2 // This DOES NOT communicate with Arduino or LEDs, it is strictly 3 // for testing the geometry. 4 5 static final int nPoints = 12; // # polyhedron vertices 6 PVector pt[] = new PVector[nPoints]; // 3D vertex coordinates 7 8 void setup() { 9 int i; 10 float c, r, h, angle, a; 11 12 size(400, 400, P3D); 13 sphereDetail(6); 14 15 // Calculate a few icoshedron fundamentals (thanks Wikipedia!) 16 c = 2.0 * sin(radians(72.0) / 2.0); // Edge length (chord) 17 r = (c / 4.0) * sqrt(10.0 + 2.0 * sqrt(5.0)); // Radius of circumsphere 18 h = sqrt(c * c - 1.0); // Height of "endcaps" 19 20 // Place vertices using 5-fold symmetry around Y axis. 21 // Processing 3D coord system is a little funky, positive Y being down. 22 pt[0] = new PVector(0.0, -r, 0.0); // Point 0 = top vertex 23 for(angle=0.0, i=1; i<6; i++, angle += 72.0) { 24 a = radians(angle); // Azimuth of "upper" vertex 25 pt[i] = new PVector(cos(a), h-r, sin(a)); // Points 1-5 = upper ring 26 a = radians(angle + 36.0); // Azimuth of "lower" vertex 27 pt[i+5] = new PVector(cos(a), r-h, sin(a)); // Points 6-10 = lower ring 28 } 29 pt[11] = new PVector(0.0, r, 0.0); // Point 11 = Bottom vertex 30 } 31 32 void draw() { 33 int i, j, k; 34 35 background(0); 36 translate(width / 2.0, height / 2.0); 37 rotateX(frameCount * 0.01); 38 rotateY(frameCount * 0.01); 39 rotateZ(frameCount * 0.01); 40 scale(width / 3.0); 41 42 for(i=0; i<5; i++) { 43 j = 1 + (i + 1) % 5; 44 k = 6 + (i + 1) % 5; 45 face(0,i+1,j); // Top endcap faces 46 face(i+1,j,i+6); // Upper mid faces 47 face(j,i+6,k); // Lower mid faces 48 face(i+6,k,11); // Bottom endcap faces 49 } 50 } 51 52 void face(int p1, int p2, int p3) { 53 int x, y; 54 PVector a, b, c, ab, bc, n; 55 56 // Draw polygon face 57 a = pt[p1]; b = pt[p2]; c = pt[p3]; 58 fill(128); 59 stroke(255); 60 beginShape(TRIANGLES); 61 vertex(a.x, a.y, a.z); 62 vertex(b.x, b.y, b.z); 63 vertex(c.x, c.y, c.z); 64 endShape(); 65 66 // Interpolate & draw LED dots 67 ab = PVector.div(PVector.sub(b, a), 7.0); // Edge vectors, scaled 68 bc = PVector.div(PVector.sub(c, b), 7.0); // to 1/2 pixel spacing 69 fill(220); 70 noStroke(); 71 for(y=0; y<3; y++) { 72 for(x=0; x<=y; x++) { 73 n = PVector.add(PVector.add(a, 74 PVector.mult(bc, (x*2+1))), PVector.mult(ab, (y*2+2))); 75 pushMatrix(); 76 translate(n.x, n.y, n.z); 77 scale(0.01); // Processing has trouble with tiny spheres, 78 sphere(5); // so set 'scale' small & draw a big one. 79 popMatrix(); 80 } 81 } 82 }