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  }