processingが楽しいので、コツコツ継続して勉強していきたい。
今回はCanvasを要素で埋め尽くすような表現を学習する。
例えば、こういうやつ
今回は基礎なので、大きさと位置がランダムなサークルを生成する。
ポイントは「要素同士は重なり合わない」こと。
まず全体のコードはイカ
ArrayList<Circle> circles = new ArrayList<Circle>();
// 生成するサークルの直径
int minDiam = 2;
int maxDiam = 200;
Circle c = new Circle(new PVector(0, 0), 20);
void setup() {
size(640, 640);
circles.add(c);
background(255);
}
void draw() {
c.draw();
PVector newLoc = new PVector(random(width), random(height));
int newDiam = (int) random(minDiam, maxDiam);
while(detectAnyCollision(circles, newLoc, newDiam)) {
newLoc = new PVector(random(width), random(height));
newDiam = (int) random(minDiam, maxDiam);
}
c = new Circle(newLoc, newDiam);
circles.add(c);
}
static boolean detectAnyCollision(ArrayList<Circle> circles, PVector newLoc, int newDiam) {
for (Circle c : circles) {
if (c.detectCollision(newLoc, newDiam)) {
return true;
}
}
return false;
}
class Circle {
PVector loc; // 位置(location)
int diam; // 直径(diammeter)
Circle(PVector loc, int diam) {
this.loc = loc;
this.diam = diam;
}
void draw() {
fill(0);
ellipse(loc.x, loc.y, diam, diam);
}
//衝突判定
boolean detectCollision(PVector newLoc, int newDiam) {
return dist(loc.x, loc.y, newLoc.x, newLoc.y) < ((diam + newDiam) / 2);
}
}
ポイントはここ
//衝突判定
boolean detectCollision(PVector newLoc, int newDiam) {
return dist(loc.x, loc.y, newLoc.x, newLoc.y) < ((diam + newDiam) / 2);
}
すでにキャンバス上に存在する円(A)と、新たに生成しようとする円(B)のそれぞれの中心点の距離をdist()
で測り、その長さが、円(A)の半径と円(B)の半径を足したものより短いかどうかで衝突判定を行う。
絵に描いた(ヘタクソ...)
あとは、イカの部分で衝突判定を繰り返し行い、描画スペースがなくなるまでサークルを生成し続ける。
while(detectAnyCollision(circles, newLoc, newDiam)) {
newLoc = new PVector(random(width), random(height));
newDiam = (int) random(minDiam, maxDiam);
}
Runすると、こんな感じ
おわり