• fullscreen
  • GlassNode.pde
  • math_functions.pde
  • other_functions.pde
  • sketch_feb21a_Gherkin08.pde
  • class GlassNode 
    {
      int num;
      float diam;
      float nx, ny, nz;
      float angle = 0;
      float angle1 = 0;
      PVector[] nodes;
    
      // number of nodes, diameter, and which floor it is
      GlassNode (int number, float diameter, float f, float ratio, boolean isTruss) 
      {
        num = number;
        diam = diameter;
        ny = - f * floorHeight * ratio ;
        angle = TWO_PI / num;   
        if (isTruss) {
          if (f % 2 == 0) angle1 = -rotAngle;  // for the truss structure
        }  
        else {
          if (f % 2 != 0)  angle1 = rotAngle * ratio; //for the glaze fabrication
        }
        nodes = new PVector[num+2];
        for (int i=0; i<nodes.length; i++) {
          nx = diam * cos(angle * i + angle1 ) /2;
          nz = diam * sin(angle * i + angle1) /2;
          nodes[i] = new PVector(nx, ny, nz);
        }
      }
    
      void display()
      { 
        stroke(255, 255, 0, 200);
        strokeWeight(1.5);
        noFill();
        for (int i=0; i<nodes.length; i++) {
          pushMatrix();
          translate(nodes[i].x, nodes[i].y, nodes[i].z);
          box(5, 5, 5);
          popMatrix();
        }
      }
    }
    
    
    
    
    // the function to calculate the diameter of each floor
    void floor_diameter() 
    {
      arcD = floorHeight * relation; 
      floorDiam = new float[23];
      for (int i=0; i<9; i++) {
        floorDiam[8-i] = (sqrt(sq(arcD/2.0) - sq(i*floorHeight)) - arcD/2.1) * 2;  
        floorDiam[8+i] = floorDiam[8-i];
      }  
      for (int i=13; i<floorDiam.length; i++) {
        floorDiam[i] = roof_diameter(arcD, floorDiam[12], floorHeight*4, floorHeight*10.5, floorHeight*(i-12));
      }
      for (int i=1; i<floorDiam.length; i=i+2) {
        floorDiam[i] = secondary_diameter(floorDiam[i-1], floorDiam[i+1], rotAngle);
      }
    }
    
    
    // the funciont to calculate the new set of diameters on the roof part
    // d1=arcD, d2=D16, h1=floorHeight*8, h2=floorHeight*6, h3=floorHeight*(i+1)
    float roof_diameter(float d1, float d2, float h1, float h2, float h3)
    {
      float A = asin(h1/(d1/2)); 
      float B = atan(h2/(d2/2));
      float p = sqrt(sq(h2) + sq(d2/2)); // xuan chang
      float r3 = (p/2) / sin(PI/2 - A - B);
    
      float X = asin(sin(A) + h3/r3);
      float Q = (A + X) / 2;
      float diff = h3 * tan(Q);
      float d3 = d2 - diff*2;
      return d3;
    }
    
    // the function to calculate the secondary diameter between two main diameters
    // for fabricating of glaze in practice
    float secondary_diameter(float da, float dc, float rot)
    {
      float db = (da + dc) / 2;
      db = db / cos(rot);
      return db;
    }
    
    
    
    
    
    
    color col_glass = color(0, 120, 240, 210); 
    color col_truss = color(220, 20, 180, 200); 
    float stroke_truss = 1.5;
    
    // the function is to draw the cladding of the glass surface
    void glass_Cladding() 
    {
      float [] glassDiam = new float[storey+1];
      float glassHeight = floorHeight * 22.0 / storey;
      int f = 8*storey/22;
      for (int i=0; i<f+1; i++) {
        glassDiam[f-i] = (sqrt(sq(arcD/2.0) - sq(i*glassHeight)) - arcD/2.1) * 2;  
        glassDiam[f+i] = glassDiam[f-i];
      }
      int t = 12*storey/22;
      for (int i=t+1; i<glassDiam.length; i++) {
        glassDiam[i] = roof_diameter(arcD, glassDiam[t], glassHeight*4*storey/22, glassHeight*10.5*storey/22, glassHeight*(i-t));
      }
    
      for (int i=1; i<glassDiam.length; i=i+2) {
        glassDiam[i] = secondary_diameter(glassDiam[i-1], glassDiam[i+1], rotAngle*22.0/storey);
      }
    
      strokeWeight(0.8);
      stroke(90, 20, 90, 200);
      noFill();
      fill(col_glass);
      glasses = new GlassNode[3];
      int nod = nodeNum*storey/22;
    
      for (int i=0; i<storey-2; i=i+2) {
        glasses[0] = new GlassNode(nod, glassDiam[i], i, 22.0/storey, false);
        glasses[1] = new GlassNode(nod, glassDiam[i+1], i+1, 22.0/storey, false);
        glasses[2] = new GlassNode(nod, glassDiam[i+2], i+2, 22.0/storey, false);
    
        for (int j=1; j<=nod; j++) {
          beginShape(QUADS);
          vertex(glasses[0].nodes[j].x, glasses[0].nodes[j].y, glasses[0].nodes[j].z);
          vertex(glasses[1].nodes[j].x, glasses[1].nodes[j].y, glasses[1].nodes[j].z);
          vertex(glasses[2].nodes[j].x, glasses[2].nodes[j].y, glasses[2].nodes[j].z);
          vertex(glasses[1].nodes[j+1].x, glasses[1].nodes[j+1].y, glasses[1].nodes[j+1].z);
          endShape();
          beginShape(TRIANGLES);
          vertex(glasses[0].nodes[j].x, glasses[0].nodes[j].y, glasses[0].nodes[j].z);
          vertex(glasses[0].nodes[j+1].x, glasses[0].nodes[j+1].y, glasses[0].nodes[j+1].z);    
          vertex(glasses[1].nodes[j+1].x, glasses[1].nodes[j+1].y, glasses[1].nodes[j+1].z);
          vertex(glasses[2].nodes[j].x, glasses[2].nodes[j].y, glasses[2].nodes[j].z);
          vertex(glasses[2].nodes[j+1].x, glasses[2].nodes[j+1].y, glasses[2].nodes[j+1].z);    
          vertex(glasses[1].nodes[j+1].x, glasses[1].nodes[j+1].y, glasses[1].nodes[j+1].z);
          endShape();
        }
      }
    }
    
    // the function is to draw the truss structure of the building
    void truss_Structure()
    {
      trusses = new GlassNode[3];
      for (int i=0; i<20; i=i+2) {
        trusses[0] = new GlassNode(nodeNum, floorDiam[i], i, 1.0, true);
        trusses[1] = new GlassNode(nodeNum, floorDiam[i+1], i+1, 1.0, true);
        trusses[2] = new GlassNode(nodeNum, floorDiam[i+2], i+2, 1.0, true);
        if (showNodes) {
          trusses[0].display();
          trusses[1].display();
          trusses[2].display();
        }
        strokeWeight(stroke_truss);
        stroke(col_truss); 
        noFill();
        for (int j=1; j<=nodeNum; j++) {
          beginShape(QUADS);
          vertex(trusses[0].nodes[j].x, trusses[0].nodes[j].y, trusses[0].nodes[j].z);
          vertex(trusses[1].nodes[j].x, trusses[1].nodes[j].y, trusses[1].nodes[j].z);
          vertex(trusses[2].nodes[j].x, trusses[2].nodes[j].y, trusses[2].nodes[j].z);
          vertex(trusses[1].nodes[j+1].x, trusses[1].nodes[j+1].y, trusses[1].nodes[j+1].z);
          endShape();
          beginShape(TRIANGLES);
          vertex(trusses[0].nodes[j].x, trusses[0].nodes[j].y, trusses[0].nodes[j].z);
          vertex(trusses[0].nodes[j+1].x, trusses[0].nodes[j+1].y, trusses[0].nodes[j+1].z);    
          vertex(trusses[1].nodes[j+1].x, trusses[1].nodes[j+1].y, trusses[1].nodes[j+1].z);
          vertex(trusses[2].nodes[j].x, trusses[2].nodes[j].y, trusses[2].nodes[j].z);
          vertex(trusses[2].nodes[j+1].x, trusses[2].nodes[j+1].y, trusses[2].nodes[j+1].z);    
          vertex(trusses[1].nodes[j+1].x, trusses[1].nodes[j+1].y, trusses[1].nodes[j+1].z);
          endShape();
        }
      }
    }
    
    
    // the function is to draw top of the truss
    void truss_Top()
    {
      GlassNode [] top = new GlassNode[3];
      for (int i=0; i<3; i++) {
        top[i] = new GlassNode(nodeNum, floorDiam[i+20], i+20, 1.0, true);
        if (showNodes)  top[i].display();
      }
      strokeWeight(stroke_truss);
      stroke(col_truss); 
      noFill(); 
      for (int i=1; i<top.length; i++) {
        if (i % 2 != 0) {
          for( int j=0; j<nodeNum; j++) {
            line(top[i].nodes[j].x, top[i].nodes[j].y, top[i].nodes[j].z, top[i-1].nodes[j].x, top[i-1].nodes[j].y, top[i-1].nodes[j].z);
            if (j > 0) line(top[i].nodes[j].x, top[i].nodes[j].y, top[i].nodes[j].z, top[i-1].nodes[j-1].x, top[i-1].nodes[j-1].y, top[i-1].nodes[j-1].z);
            if (j == 0) line(top[i].nodes[j].x, top[i].nodes[j].y, top[i].nodes[j].z, top[i-1].nodes[nodeNum-1].x, top[i-1].nodes[nodeNum-1].y, top[i-1].nodes[nodeNum-1].z);       
          }
        }
        else {
          for( int j=0; j<nodeNum; j++) {     
            line(top[i].nodes[j].x, top[i].nodes[j].y, top[i].nodes[j].z, top[i-1].nodes[j].x, top[i-1].nodes[j].y, top[i-1].nodes[j].z);
            if (j < nodeNum) line(top[i].nodes[j].x, top[i].nodes[j].y, top[i].nodes[j].z, top[i-1].nodes[j+1].x, top[i-1].nodes[j+1].y, top[i-1].nodes[j+1].z);
            if (j == nodeNum-1) line(top[i].nodes[j].x, top[i].nodes[j].y, top[i].nodes[j].z, top[i-1].nodes[0].x, top[i-1].nodes[0].y, top[i-1].nodes[0].z);       
          }
        }
      }
    }
    
    float k = 4.0; // scale key
    float floorHeight = 8.2 * k; // the floor height is 8.2m for actual two floors
    float relation = 145.0; // the relation could be justed in term of real relation
    float arcD; 
    
    int storey = 22; // 22 as default, controlled by UP and DOWN KEYS
    int nodeNum = 18; // 18 as  default, controlled by LEFT and RIGHT KEYS
    float rotAngle = -PI/nodeNum; // rotate or not rotate, controlled by SHIFT KEY
    float [] floorDiam; 
    GlassNode [] trusses;
    GlassNode [] glasses;
    boolean showTruss = true;
    boolean showGlaze = true;
    boolean showNodes = true;
    boolean mouseControl = false;
    
    
    ////////////////////////////////////////////////////////////////////////////
    void setup()
    {
      size(600, 800, P3D);
      lights();
      // calculate the diameter of each floor
      floor_diameter();
      for (int i=0; i<floorDiam.length; i++) {
        println(i*2 + " F, diameter: " + floorDiam[i]/k); 
      }
      println("total height: " + floorHeight*22.0/k);
    }
    
    
    //////////////////////////////////////////////////////////////////////////////////////
    void draw()
    {
      background(30);
      smooth();
      stroke(200, 50);
      noFill();
    
      if (mouseControl) {
        noSmooth();
        rotateX(PI * (height/2-mouseY)/height);
        rotateY(-PI * (width/2-mouseX)/width);
      }
      rotateX(-PI/9);
      translate(width/2, height/2+100, 0);
      if (mouseControl) rotateY(frameCount*0.01);
      else              rotateY(frameCount*0.05);
      translate(0, 8*floorHeight, 0); // basement coordinate
      box(300, 20, 300);
    
      floor_diameter();
      // draw the glaze
      if (showGlaze) {
        glass_Cladding();
      }
      // draw the truss and nodes of the truss
      if (showTruss) {
        // draw the top
        pushMatrix();
        translate(0, -22*floorHeight*0.99, 0);
        fill(col_truss);
        noStroke();
        sphere(15); //floorDiam[22]/2 * 1.5
        popMatrix(); 
        truss_Top();
        truss_Structure();   
      }
    }
    
    
    //////////////////////////////////////////////////////////////
    void mousePressed() 
    { 
      mouseControl = !mouseControl;
    }
    
    void keyPressed()
    {
      if (key == CODED) {
        if (keyCode == UP) {
          if (storey < 88) storey = storey * 2;
        }
        else if (keyCode == DOWN) {
          if (storey > 22) storey = storey / 2;
        }
        if (keyCode == LEFT) { 
          if (nodeNum > 3) nodeNum--;
        }
        else if (keyCode == RIGHT) {
          if (nodeNum < 36) nodeNum++;  
        }
        if (keyCode == CONTROL) {
          relation = 145.0;
          storey = 88;
          nodeNum = 18;
        }
        rotAngle = -PI/nodeNum;
        if (keyCode == SHIFT) {
          rotAngle = 0;
        }
      }
      if (key == 't'|| key == 'T') {
        showTruss = !showTruss;
      }
      if (key == 'g'|| key == 'G') {
        showGlaze = !showGlaze;
      }
      if (key == 'n'|| key == 'N') {
        showNodes = !showNodes;
      }
      if (key == 'z'|| key == 'Z') {
        relation -= 14.5;
      }
      else if (key == 'x'|| key == 'X') {
        relation += 14.5;
      }
      println("rotate: "+ degrees(rotAngle) + ", node number: " + nodeNum + ", glaze detail: " + storey);
      //  println(floors[5].nodes[3]);
      //  println(floors[6].nodes[3]);
    }  
    
    
    
    
    
    
    
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    sheng cheng

    The Gherkin

    Add to Faves Me Likey@! 2
    You must login/register to add this sketch to your favorites.

    This is an example of Parametric Modeling. Use key boards to change the parameters.

    You need to login/register to comment.