• fullscreen
  • Friends.pde
  • LinkedList.pde
  • /* Landscape generator
      Version 1.0, programmed by Xiaohan Zhang
      
      Re-use code plox
      
      left/right: turn landscape
      up/down: rotate view up/down
      +/-: zoom in/out (it's actually the equal sign instead of the plus sign)
      
      Originally, this was going to be a study of how related objects interact with each other in the face of chance, a semi-simulation of 
      people in real life - some people would overcome hardship and rise to the top, while others will bring their friends down, etc. Instead,
      this became a landscape generator.
      
    */
    
    final static float MAXRATE = 4;
    final static float yMax = 128;
    
    final static int xMax = 100,
                     zMax = 100;
    
    final static float zin = 1.05, zout = 1/zin;
    float yMult;
    float BLOCK_DIST;
    int HALF_TOTAL_DIST;
    
    Unit[][] units = new Unit[xMax][zMax];
    
    void setup() {
      size(900, 450, P3D);
      BLOCK_DIST = (float)width / xMax;
      yMult = height/yMax/2;
      HALF_TOTAL_DIST = width/2;
    //  background(0);
      noStroke();
      for(int x = 0; x < xMax; x++) {
        for(int z = 0; z < zMax; z++) {
    //      println(x+", "+z);
          units[x][z] = new Unit(x, z, yMax, random(-MAXRATE, MAXRATE));
        }
      }
      for(int x = 0; x < xMax; x++) {
        for(int z = 0; z < zMax; z++) {
          units[x][z].findFriends();
        }
      }
    //  sphereDetail(6);
      camera(0, -height, (height/2.0) / tan(PI*60.0 / 360.0), 0, -height/2, 0, 0, 1, 0);
    }
    
    final float turnSpeed = radians(3);
    float ty = 0;
    float tx = 0;
    float zoom = 1;
    
    void draw() {
      background(255);
      for(int x = 0; x < xMax; x++) {
        for(int z = 0; z < zMax; z++) {
          units[x][z].run();
        }
      }
      if(keyPressed) {    
      if(keyCode == LEFT) {
        ty += turnSpeed;
      }
      else if(keyCode == RIGHT) {
        ty -= turnSpeed;
      }
      if(keyCode == UP) {
        tx = max(tx-turnSpeed, -PI/4);
      }
      else if(keyCode == DOWN) {
        tx = min(tx+turnSpeed, PI/4);
      }
      if(key == '-') {
    //    beginCamera();
        zoom *= zout;
    //    endCamera();
      }
      else if(key == '=') {
    //    beginCamera();
        zoom *= zin;
    //    endCamera();
      }
      }
      scale(zoom);
      rotateX(tx);
      rotateY(ty);
     
      translate(-HALF_TOTAL_DIST, 0, -HALF_TOTAL_DIST);
    //  beginShape(QUAD_STRIP);
      for(int x = 0; x < xMax; x++) {
        for(int z = 0; z < zMax; z++) {
          units[x][z].update();
        }
      }
      for(int x = 1; x < xMax; x++) {
        for(int z = 1; z < zMax; z++) {
          drawFor(unitAt(x-1, z-1), unitAt(x-1, z), unitAt(x, z), unitAt(x, z-1));
        }
      }
    //  endShape();
      println(frameRate);
    }
    
    Unit unitAt(int x, int z) {
      if(x < 0 | x > xMax-1 | z < 0 | z > zMax-1) return null;
      return units[x][z];
    }
    
    int colorFor(float x) {
      float r = (x-yMax/2)/yMax*255*yMax/(yMax-yMax/2);
      float g = x/yMax*255*.9*yMax/(.9*yMax-.35*yMax);
      float b = abs(yMax/2-x)/yMax/2*255;
      return color(r, g, b);
    }
    
    void drawFor(Unit u1, Unit u2, Unit u3, Unit u4) {
    //  float rate = (u1.rate+u2.rate+u3.rate+u4.rate)/4;
    //  fill(colorFor((u1.rate+u2.rate+u3.rate+u4.rate)/4*16));
      fill(colorFor((u1.y+u2.y+u3.y+u4.y)/4));
      beginShape(QUADS);
      u1.vertexHere();
      u2.vertexHere();
      u3.vertexHere();
      u4.vertexHere();
      endShape();
    }
    
    class Unit {
      final int x, z;
      float y, nextY;
      float rate;
      boolean alive = true;
      LinkedList friends;
      
      Unit(int x, int z, float y, float rate) {
        this.x = x;
        this.z = z;
        this.y = y;
        this.rate = rate;
        friends = new LinkedList();
      }
      
      void findFriends() {
        for(int x = -1; x < 2; x++) {
          for(int z = -1; z < 2; z++) {
            Unit f = unitAt(this.x+x, this.z+z);
            if(f != null && f != this)
              if(friends.indexOf(f) == -1)
                friends.add(f);
          }
        }
      }
      
      void run() {
        add(rate);
        Link l = friends.first();
        Unit f;
        float dif = 0;
        int k = 0;
        while(l != null) {
          f = (Unit)l.data;
          dif += f.get()-get();
          k++;
          l = l.next;
        }
        add(dif/k);
    //    rate += random(-.1, .1);
    //    if(random(1) < .01) {
    //      add(random(-5, 5));
    //    }
      }
      
      float get() {
        return y;
      }
      
      void set(float p) {
        nextY = constrain(p, 0, yMax);
      }
      
      void add(float p) {
        set(nextY+p);
      }
      
      void update() {
        if(alive) {
          y = nextY;
    //      if(rate > 0) fill(color(128+128/MAXRATE*rate, 0, 0));
    //      pushMatrix();
    //      translate(x*BLOCK_DIST, -y*yMult, z*BLOCK_DIST);
    //      sphere(4);
    //      popMatrix();
    //      vertex(x*BLOCK_DIST, -y*yMult, z*BLOCK_DIST);
        }
        else {
          
        }
      }
      
      void vertexHere() {
        vertex(x*BLOCK_DIST, -y*yMult, z*BLOCK_DIST);
      }
    }
    
    /* Linked List
      Version 1.0, programmed by Jill Jackson
      
      Take my LinkedList class if you want. I'm pretty sure it's not the fastest or the best there is out there, but it works for me
    */
    
    public class Link {
    
        public Link next;
        public Object data;
    
        public Link(Link next, Object data) {
            this.next = next;
            this.data = data;
        }
    
        public Link(Object data) {
            this(null, data);
        }
    }
    
    
    public class LinkedList {
    
        final Link head = new Link(null);
        Link last = head;
        
        public LinkedList() {
        }
    
        public LinkedList(Link l) {
            add(l);
        }
    
        public LinkedList(Object o) {
            this(new Link(o));
        }
    //
    //    public LinkedList(E[] array) {
    //        for (E o : array) {
    //            add(o);
    //        }
    //    }
    
        public Link first() {
            return head.next;
        }
    
        public void add(Link l) {
            last.next = l;
            last = l;
        }
    
        public void add(Object a) {
            add(new Link(a));
        }
        
        public void insert(Link l, int index) {
            Link linkAt = linkAt(index-1), next = linkAt.next;
            linkAt.next = l;
            l.next = next;
            if(next == null) last = l;
        }
        
        public void insert(Object o, int index) {
            insert(new Link(o), index);
        }
    
        public Link linkAt(int index) {
            Link current = head;
            for (int a = -1; a < index; a++) {
                if (current == null) {
                    break;
                } else {
                    current = current.next;
                }
            }
            return current;
        }
    
        public void remove(int index) {
            Link prev = linkAt(index - 1);
            if((prev.next = prev.next.next) == null)
                last = prev.next;
        }
    
        public int remove(Link l) {
            Link current = head;
            for (int a = -1; current != null; a++, current = current.next) {
                if (current.next == l) {
                    if((current.next = l.next) == null) last = current;
                    return a;
                }
            }
            return -1;
        }
    
        public int remove(Object o) {
            Link current = head;
            for (int a = -1; current != null; a++, current = current.next) {
                if (current.next.data == o) {
                    if((current.next = current.next.next) == null) last = current;
                    return a;
                }
            }
            return -1;
        }
    
        public int indexOf(Link l) {
            Link current = head;
            for (int a = -1; current != null; a++, current = current.next) {
                if (current == l) {
                    return a;
                }
            }
            return -1;
        }
    
        public int indexOf(Object e) {
            Link current = head;
            for (int a = -1; current != null; a++, current = current.next) {
                if (current.data == e) {
                    return a;
                }
            }
            return -1;
        }
    
        public String toString() {
            Link l = first();
            String s = super.toString();
            for (int a = 0; l != null; a++) {
                s += "\n[" + a + "]" + l.data;
                l = l.next;
            }
            return s;
        }
    
        public Object[] toArray() {
            Object[] list = new Object[length()];
            Link current = first();
            for (int b = 0; b < list.length; b++) {
                list[b] = current.data;
                current = current.next;
            }
            return list;
        }
    
        public int length() {
            Link current = first();
            int a = 0;
            for(; current != null; a++, current = current.next) {}
            return a;
        }
    }
    

    code

    tweaks (0)

    about this sketch

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

    license

    advertisement

    Xiaohan Zhang

    3D Landscape Generator

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

    Creates a random landscape with mountains and valleys each time.
    <br>
    left/right: turn landscape<br>
    up/down: rotate view up/down<br>
    +/-: zoom in/out (it's actually the equal sign instead of the plus sign)

    Jashaszun
    8 Sep 2009
    You should probably make the landscape in the center of the screen so that the bottom isn't always cut off by the edge of the screen.
    You need to login/register to comment.