processingを使用して多くの正方形を画像内に描画したいです
これまで画像内に多くの円を描写するプログラミングを使用してきました。
小(17px)、中(821px),大(22~48px)の三種類の円をそれぞれの種類ごとに個数を指定し、重ならないようにしながら描画していました。円の位置はそれぞれランダムに配置していました。
今回は円ではなく正方形を描画したかったのですが、方法が分からず質問させてもらいました。
基本的な条件などは円を描画している時と同じにしたいです。
条件としては
・正方形の個数を指定できる
・小、中、大の3種類(それぞれの大きさはある範囲内でランダム)を描画
・場所はランダムに配置される
・正方形同士は重ならない
・色は枠も内部も共に黒で指定する
・一度に多くの画像を作成
該当のソースコード
円を描写している際のコードを添付します。
大の円1個
中の円25個
小の円1個を描画した画像を400枚作った際のコードになります。
processing
1 2ArrayList<PVector> circles; // 円のデータ 3 4void setup() { 5 size(600, 600); 6 smooth(); 7 8 frameRate(20); // 1秒当たり描画数 9 10} 11 12void draw() { 13 background(255); 14 circles = new ArrayList<PVector>(); // 15 16 //データ 17 addCircle(); 18 19 20 // 円を全部描画 21 for ( 22 23 int i = 0; i < circles.size(); i++) { 24 PVector p = circles.get(i); 25 noStroke(); 26 fill(0); 27 ellipse(p.x, p.y, p.z, p.z); 28 } 29 30 31 // 画像の保存 32 save("E:/hozon/" + frameCount + ".png"); 33 34 if (frameCount == 400) { // n枚作ったら止める 35 noLoop(); // 止める 36 37 //launch("start " + sketchPath()); // Windows専用 エクスプローラでフォルダを開く 38 //exit(); // 終了 39 } 40} 41 42void addCircle() { 43 int[] sizes = { 44 int(random(22,49)), 45 int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), 46 int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), 47 int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), 48 int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), 49 int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), int(random(8,22)), 50 int(random(1,8)), 51}; 52 53 while (circles.size() < sizes.length) { // 円のデータの個数が、必要サイズ候補数より少ない間ループ 54 // サイズを取得(配列は0始まりなので、circles.size()が0の時は0番目、circles.size()が1の時は1番目... 55 int diameter = sizes[circles.size()]; 56 57 // 3次元のベクトルのうちxyを2次元座標、zを円の直径として利用している 58 PVector c = new PVector(random(30,570), random(30,570), diameter); 59 boolean overlapping = false; 60 61 for (PVector p : circles) { 62 // zは直径なので理屈的には割る2 くっついて見えるのがまずい場合は、少し足すなりなんなり 63 if (dist(c.x, c.y, p.x, p.y) < (c.z + p.z) / 2) { 64 overlapping = true; 65 break; 66 } 67 } 68 69 if (!overlapping) { 70 circles.add(c); 71 } 72 } 73}
ご存じの方がおられたらお力添えお願いいたします。
正方形なら辺の長さが同じですから、円の場合と同様の手法(xyを座標・zを辺の長さとして利用)が使えます。
であれば問題は重なり判定のコードだけです。
if (dist(c.x, c.y, p.x, p.y) < (c.z + p.z) / 2)
この条件を変えるだけですが、どの程度調べたのでしょうか?
以前の質問のコードそのままで、丸投げと取られます。
注)正確には当然ellipseをrectに変更と、rectMode(CENTER)の追加も必要ですが^^;
> ellipseをrectに変更
ねぇ、みんなsquare()とかcircle()って使わないの?
w
恥ずかしながら当時は知らなかったのです^^;
引数の数が変わるため、変に混乱させないようにrectと書きました。
今手元に準備中のコードではsquareを使用しています^^
確かに丸投げと捉えられるような質問であったと反省しています。
切れたり、重なってしまったりという不具合があったのですがrectMode(CENTER)を入れると解決しました。
ありがとうございます。
> rectMode(CENTER)を入れると解決しました。
自力で解決されましたか。おめでとうございます^^
であれば、自己回答で閉じていただいて結構です。
解決コードも載せれば、もしかしたら誰かの役に立つかもしれません。
> 解決コードも載せれば、もしかしたら誰かの役に立つかもしれません。
あるいは間違っている場合、誰かから突っ込みが入ります^^;
rectModeを変えても円の当たり判定のままでは重なりますよ。
回答3件
あなたの回答
tips
プレビュー