日常の進捗

主に自分のための,行為とその習慣化の記録

Mod: Coding Challenge #50: Animated Circle Packing

f:id:takawo:20171018083903p:plain

Processing.jsだと継承したクラスがスーパークラスのプロパティを呼び出す時,this付けないとエラーが出るようだ.

コード(PGraphis版)

ArrayList<Circle> circles;
ArrayList<PVector> points;

PGraphics pg;

void setup() {
  size(960, 540);
  colorMode(HSB, 360, 100, 100);

  circles = new ArrayList<Circle>();
  points = new ArrayList<PVector>();

  pg = createGraphics(width, height);
  pg.beginDraw();
  pg.colorMode(HSB, 360, 100, 100);
  pg.background(0, 0, 0);
  pg.fill(0, 0, 100);
  pg.textAlign(CENTER, CENTER);
  pg.textSize(200);
  pg.text("CIRCLE", width/2, height/2);
  //pg.ellipse(width/2, height/2, 300, 300);
  pg.endDraw();

  pg.loadPixels();
  for (int y = 0; y < pg.height; y++) {
    for (int x = 0; x < pg.width; x++) {
      int index = x + y * pg.width;
      color c = pg.pixels[index];
      float b = brightness(c);
      if (b > 1) {
        points.add(new PVector(x, y));
      }
    }
  }
}

void  draw() {
  background(220, 20, 20);

  int total = 2;
  int count = 0;
  int attempts = 0;

  while (count < total) {
    Circle c = createCircle();
    if ( c != null) {
      circles.add(c);
      count++;
    }
    attempts++;
    if (attempts > 1000) {
      noLoop();
      break;
    }
  }
  for (Circle c : circles) {
    if (c.isAlive) {
      if (c.isEdge()) {
        c.isAlive = false;
      } else {
        for (Circle other : circles) {
          if (!c.equals(other)) {
            float d = dist(c.x, c.y, other.x, other.y);
            if (d  < c.r + other.r) {
              c.isAlive = false;
              break;
            }
          }
        }
      }
    }
    c.draw();
    c.grow();
  }
}

Circle createCircle() {
  int n = (int)random(points.size());

  float x = points.get(n).x;
  float y = points.get(n).y;

  for (Circle c : circles) {
    float d = dist(x, y, c.x, c.y);
    if (d < c.r) {
      return null;
    }
  }
  return new Circle(x, y);
}


class Circle extends PVector {
  float r;
  boolean isAlive = true;

  Circle(float _x, float _y) {
    super(_x, _y);
    r = 1;
  }

  Circle(float _x, float _y, float _r) {
    super(_x, _y);
    r = _r;
  }

  void grow() {
    if (isAlive) {
      r += 0.1;
    }
  }

  boolean isEdge() {
    return ( this.x + r > width || this.x - r < 0 || this.y + r > height || this.y - r < 0 );
  }

  void draw() {
    stroke(0, 0, 100);
    strokeWeight(0.5);
    noFill();
    ellipse(this.x, this.y, r*2, r*2);
  }
}

コード(PImage版)

ArrayList<Circle> circles;
ArrayList<PVector> points;

PImage img;

void setup() {
  size(960, 540);
  colorMode(HSB, 360, 100, 100);
  init();
}

void init() {
  circles = new ArrayList<Circle>();
  points = new ArrayList<PVector>();

  String str = "http://lorempixel.com/" + width +"/"+ height + "/";
  img = loadImage(str, "jpg");


  img.loadPixels();
  for (int y = 0; y < img.height; y += 1) {
    for (int x = 0; x < img.width; x += 1) {
      int index = x + y * img.width;
      color c = img.pixels[index];
      float b = brightness(c);
      if (b > 0.1) {
        points.add(new PVector(x, y));
      }
    }
  }
}

void  draw() {
  background(0, 0, 50);

  int total = 100;
  int count = 0;
  int attempts = 0;

  while (count < total) {
    Circle c = createCircle();
    if ( c != null) {
      circles.add(c);
      count++;
    }
    attempts++;
    if (attempts > 1000) {
      saveFrame("#######.png");
      init();
      break;
    }
  }
  for (Circle c : circles) {
    if (c.isAlive) {
      if (c.isEdge()) {
        c.isAlive = false;
      } else {
        for (Circle other : circles) {
          if (!c.equals(other)) {
            float d = dist(c.x, c.y, other.x, other.y);
            if (d  < c.r + other.r) {
              c.isAlive = false;
              break;
            }
          }
        }
      }
    }
    c.draw();
    c.grow();
  }
  image(img, width-img.width/7-20, height-img.height/7-20, img.width/7, img.height/7);
}

Circle createCircle() {
  int n = (int)random(points.size());

  float x = points.get(n).x;
  float y = points.get(n).y;

  for (Circle c : circles) {
    float d = dist(x, y, c.x, c.y);
    if (d < c.r) {
      return null;
    }
  }
  return new Circle(x, y);
}


class Circle extends PVector {
  float r;
  color c;
  boolean isAlive = true;

  Circle(float _x, float _y) {
    super(_x, _y);
    r = 1;
    c = img.get((int)x, (int)y);
  }

  Circle(float _x, float _y, float _r) {
    super(_x, _y);
    r = _r;
    c = img.get((int)x, (int)y);
  }

  void grow() {
    if (isAlive) {
      r += 0.3;
    }
  }

  boolean isEdge() {
    return ( this.x + r > width || this.x - r < 0 || this.y + r > height || this.y - r < 0 );
  }

  void draw() {
    noStroke();
    fill(c);
    ellipse(this.x, this.y, r*2, r*2);
  }
}

void mousePressed() {
  init();
}

リファレンス