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

Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

ギリギリで重ならないように回転する円

/**
* unoverlapped spining cirlces
*
* @author aa_debdeb
* @date 2016/08/27
*/

color bg;
color col[];
ArrayList<Spin> spins;

void setup(){
  size(500, 500);
  noStroke();
  colorMode(HSB, 360, 100, 100);
  initialize();
}

void mousePressed(){
  initialize();
}

void initialize(){
  float hue = random(360);
  float sat = random(30, 100);
  float bri = random(50, 100);
  bg = color(hue, sat, bri);
  col = new color[3];
  col[0] = color(hue < 180? hue + 180: hue - 180, sat, bri);
  col[1] = color(hue < 150? hue + 150: hue - 150, sat, bri);
  col[2] = color(hue < 210? hue + 210: hue - 210, sat, bri);

  
  spins = new ArrayList<Spin>();
  for(int i = 0; i < 3000; i++){
    PVector center = new PVector(random(width), random(height));
    float maxRange = 10000;
    boolean isOverlapped = false;
    for(Spin spin: spins){
      float d = PVector.dist(center, spin.center);
      if(d < spin.getSize()){
        isOverlapped = true;
        break;
      }
      if(d - spin.getSize() < maxRange){
        maxRange = d - spin.getSize();
      }
    }
    if(!isOverlapped){
      float minRadious = min(50, maxRange) * 0.2;
      float maxRadious = min(50, maxRange) * 1.0;
      float radious = random(minRadious, maxRadious);
      float range = random(0, maxRadious - radious);
      if(radious > 2){
        spins.add(new Spin(center, range, radious * 2, col[int(random(3))]));
      }
    }
  }
}

void draw(){
  background(bg);
  for(Spin spin: spins){
    spin.display();
    spin.update();
  }
}

class Spin{
  
  PVector center;
  float range;
  float diameter;
  float angle;
  float angleSpeed;
  color c;
  
  Spin(PVector _center, float _range, float _diameter, color _c){
    center = _center;
    range = _range;
    diameter = _diameter;
    angle = random(TWO_PI);
    angleSpeed = random(PI / 64, PI / 16);
    angleSpeed *= random(1) < 0.5 ? -1: 1;
    c = _c;
  }
  
  void display(){
    fill(c);
    float x = center.x + range * cos(angle);
    float y = center.y + range * sin(angle);
    ellipse(x, y, diameter, diameter);
  }
  
  void update(){
    angle += angleSpeed;
    if(angle < 0){
      angle += TWO_PI;
    }
    if(angle >= TWO_PI){
      angle -= TWO_PI;
    }
  }
  
  float getSize(){
    return range + diameter / 2;
  } 
}
f:id:aa_debdeb:20160825131857j:plain