読者です 読者をやめる 読者になる 読者になる

30 min. Processing

毎日30分、Processingで何かを作る

海底探査

3D インタラクション
/**
* seabed exploration
*
* @author aa_debdeb
* @date 2016/07/15
*/

float maxLocRadious = 800;
float minSize = 10;
float maxSize = 100;
float noiseX = random(10000);
float noiseY = random(10000);
float noiseScale = 0.02;
float camSpeed = 10;
float eyeWidth = 50;
ArrayList<Block> blocks;
PVector cam;

void setup(){
  size(500, 500, P3D);
  cam = new PVector(0, 0, 500);
  blocks = new ArrayList<Block>();
  for(int i = 0; i < 200000; i++){
    float locRadious = map(sqrt(random(1)), 0, 1, 0, maxLocRadious);
    float size = random(minSize, map(locRadious, 0, maxLocRadious, maxSize, 0));
    float locRadian = random(TWO_PI);
    PVector loc = new PVector(locRadious * cos(locRadian), locRadious * sin(locRadian), size / 2);
    int stack = int(random(1, 5));
    float radian = random(HALF_PI);
    if(noise(loc.x * noiseScale + noiseX, loc.y * noiseScale + noiseY) < 0.5){
      continue;
    }
    boolean isOverlapped = false;
    for(Block other: blocks){
      float d = PVector.dist(other.loc, loc);
      if(d < sqrt(2) * other.size / 2 + sqrt(2) * size / 2){
        isOverlapped = true;
        break;
      }
    }
    if(!isOverlapped){
      Block block = new Block(loc, radian, size, stack);
      blocks.add(block);
    }
  }
}

void draw(){
  background(30, 51, 51);
  noStroke();
  translate(width / 2,  height / 2, 0);
  lights();  
  float eyeX = map(mouseX, 0, width, -eyeWidth, eyeWidth);
  float eyeY = map(mouseY, 0, height, -eyeWidth, eyeWidth);
  camera(cam.x, cam.y, cam.z, cam.x + eyeX, cam.y + eyeY, 0, 0, 1, 0); 
  for(Block block: blocks){
    block.display();
  }
  cam.x += map(mouseX, 0, width, -camSpeed, camSpeed);
  if(cam.x < -maxLocRadious){cam.x = -maxLocRadious;}
  if(cam.x > maxLocRadious){cam.x = maxLocRadious;}
  cam.y += map(mouseY, 0, height, -camSpeed, camSpeed);
  if(cam.y < -maxLocRadious){cam.y = -maxLocRadious;}
  if(cam.y > maxLocRadious){cam.y = maxLocRadious;}
}

class Block{
  
  PVector loc;
  float radian, size;
  int stack;
  color c;
  
  Block(PVector _loc, float _radian, float _size, int _stack){
    loc = _loc;
    radian = _radian;
    size = _size;
    stack = _stack;
    colorMode(HSB, 360, 100, 100);
    color _c = color(random(180, 220), random(70, 100), random(20, 40));
    colorMode(RGB, 255, 255, 255);
    c = color(red(_c), green(_c), blue(_c));
  }
  
  void display(){
    fill(c);
    for(int i = 0; i < stack; i++){
      pushMatrix();
      translate(loc.x, loc.y, loc.z + i * size);
      rotateZ(radian);
      box(size);
      popMatrix();
    }
  }
  
}