• The Serpinski Gasket
    • They use this example to develop the ideas of the chapter.
    • They give one of several algorithms for developing this shape
    • Given T= {(x1, y1, 0), (x2, y2, 0), (x3, y3, 0)
      
      1. Pick an initial point p = (x,y,0) inside of the triangle
      2. count = 0
      3. While count < LIMIT
      4. Select one of the three vertices at random, v.
      5. Find point q halfway between p and v.
      6. Display a pixel at q
      7. q = p
      8. count++
  • They provide three code snipets to distinguish between immediate mode, reatined mode, and a "GPU" mode
    • In immediate mode
    • function serpinski() {
          initialize_the_system();
          p = find_initial_point();
          for(i=0;i<LIMIT;i++) {
              q = generate_a_point(p);
      	display_the_point(q);
      	p = q;
          }
      }
      
    • Note, the points are not stored.
      • The program is responsible for generating and displaying the points.
      • And, given the random process, the image will shift every time.
    • Retained mode
    • function serpinski() {
          initialize_the_system();
          p = find_initial_point();
          for(i=0;i<LIMIT;i++) {
              q = generate_a_point(p);
      	store_the_point(q);
      	p = q;
          }
          display_all_points();
      }
      
    • In this mode, the points are stored in an array.
    • display_all_points probably loops through and calls display_the_point on each point.
      • The CPU is still mostly responsible for the display of th points
      • But the picture will not shift.
      • And the work is GREATLY reduced.
    • The GPU mode would be more like
    • function serpinski() {
          initialize_the_system();
          p = find_initial_point();
          for(i=0;i<LIMIT;i++) {
              q = generate_a_point(p);
      	store_the_point(q);
      	p = q;
          }
          TransferPontsToGPU();
          DisplayOnGPU();
      
  • Let me brag a bit.
    • I copied canvas object to draw this.
    • Initialization
      • var p1 = [this.width/2.0, 20];
        var p2 = [20, this.height-20];
        var p3 = [this.width-20, this.height-20];
        this.tri = [p1, p2, p3]
        
      • Store three points of a triangle into a two dimensional array
      • This is perhaps a step backwards for a structured programming point of view (field names vs indexes)
      • But I want to be able to select a random vertex, hence a index computation, not a wierd switch lookup.
    • Linear Interpolation (LERP)
      • Given two values, find a value part way between the two.
      • Interp: function(a,b,s) {
             return a*s + b*(1-s);
        },
        
      • Defined for s in [0,1]
      • If s=0, the function returns a
      • If s=1, the function returns b
      • Anything in between returns a mixture of the two.
    • So picking a point in the middle of the line
      •     HalfPoint: function(p1,p2) {
                var x = this.Interp(p1[0],p2[0],.5);
                var y = this.Interp(p1[1],p2[1],.5);
                return [x,y];
            },
        
    • Or even a random point on a line
      •     RandPoint: function(p1, p2) {
                var s = Math.random();
                var x = this.Interp(p1[0],p2[0],s);
                var y = this.Interp(p1[1],p2[1],s);
                return [x,y];
            },
        
    • So creating the points becomes :
      • In intermediate mode.
      •     Redisplay: function() {
                this.Clear();
        
                var p, q, v;
        
                this.ctx.fillStyle = this.color;
        
                var t1 = this.RandPoint(this.tri[0], this.tri[1]);
                p = this.RandPoint(t1, this.tri[2]);
                for (var i=0; i<this.count; i++) {
                    var c = Math.floor(Math.random()*3);
                    v = this.tri[c]
                    q = this.HalfPoint(p,v);
                    this.ctx.fillRect(q[0],q[1],2,2);
                    p = q;
                }
                return;
            }
        
        
      • In retained mode:
      •         var p, q, v;
                var t1 = this.RandPoint(this.tri[0], this.tri[1]);
                p = this.RandPoint(t1, this.tri[2]);
                this.list= [];
                for (var i=0; i<this.count; i++) {
                    var c = Math.floor(Math.random()*3);
                    v = this.tri[c]
                    q = this.HalfPoint(p,v);
                    this.list.push(q);
                    p = q;
                }
                return;
            },
        
  • The code needs some cleanup but it works.
  • Immediate Mode
  • Retaied Mode