NonCircularPacking.pde
class NonCircularPacking {
PGraphics pg;
PGraphics tmpPg;
ArrayList<AbstractItem> items;
AbstractItem maskItem;
int margin;
NonCircularPacking() {
this(null);
}
NonCircularPacking(AbstractItem maskItem) {
this(maskItem, 0);
}
NonCircularPacking(AbstractItem maskItem, int margin) {
this.margin = margin;
this.maskItem = maskItem;
pg = createGraphics(width, height);
pg.beginDraw();
pg.background(0, 0);
if (maskItem != null) {
maskItem.draw(pg, 0);
}
pg.endDraw();
// マスクが設定されているときは透明度をひっくり返しておく
if (maskItem != null) {
pg.loadPixels();
for (int k = 0; k < pg.pixels.length; k++) {
color pixel = pg.pixels[k];
pg.pixels[k] = color(red(pixel), green(pixel), blue(pixel), 255 - alpha(pixel));
}
pg.updatePixels();
}
tmpPg = createGraphics(pg.width, pg.height);
tmpPg.beginDraw();
tmpPg.background(0, 0);
tmpPg.endDraw();
items = new ArrayList();
}
boolean isOverlapped(AbstractItem item) {
tmpPg.beginDraw();
tmpPg.background(0, 0);
item.draw(tmpPg, 0);
tmpPg.endDraw();
boolean overlapped = false;
pg.loadPixels();
tmpPg.loadPixels();
for (int k = 0; k < pg.pixels.length; k++) {
float a1 = alpha(pg.pixels[k]);
float a2 = alpha(tmpPg.pixels[k]);
if (a2 > 0 && a1 > 0) {
overlapped = true;
break;
}
}
return overlapped;
}
void addItem(AbstractItem item) {
tmpPg.beginDraw();
tmpPg.background(0, 0);
item.draw(tmpPg, 0);
for (int k = 0; k < margin; k++) {
tmpPg.filter(DILATE);
}
tmpPg.endDraw();
pg.beginDraw();
pg.image(tmpPg, 0, 0);
pg.endDraw();
items.add(item);
}
void draw(PGraphics g, int t) {
for (AbstractItem item : items) {
item.draw(g, t);
}
}
}
PackingItems.pde
abstract class AbstractItem {
abstract void draw(PGraphics pg, int t);
}
class ImageItem extends AbstractItem {
PVector pos;
float rot;
float sc;
PImage img;
ImageItem(PImage img, PVector pos) {
this(img, pos, 0.0, 1.0);
}
ImageItem(PImage img, PVector pos, float rot, float sc) {
this.img = img;
this.pos = pos;
this.rot = rot;
this.sc = sc;
}
void draw(PGraphics pg, int t) {
pg.imageMode(CENTER);
pg.pushMatrix();
pg.translate(pos.x, pos.y);
pg.rotate(rot);
pg.scale(sc);
pg.image(img, pos.x, pos.y);
pg.popMatrix();
}
}
class ShapeItem extends AbstractItem {
PVector pos;
float rot;
float sc;
color c;
PShape sh;
ShapeItem(PShape sh, PVector pos) {
this(sh, pos, 0.0, 1.0);
}
ShapeItem(PShape sh, PVector pos, float rot, float sc) {
this(sh, pos, rot, sc, color(75));
}
ShapeItem(PShape sh, PVector pos, float rot, float sc, color c) {
this.sh = sh;
this.pos = pos;
this.rot = rot;
this.sc = sc;
this.c = c;
}
void draw(PGraphics pg, int t) {
pg.shapeMode(CENTER);
pg.pushMatrix();
pg.translate(pos.x, pos.y);
pg.rotate(rot);
pg.scale(sc);
pg.fill(c);
pg.noStroke();
pg.shape(sh);
pg.popMatrix();
}
}
sketch_210607a.pde
NonCircularPacking ncp;
PShape[] shapes;
void setup() {
size(800, 800);
String[] fileList = new String[] {
"cat.svg",
"horse.svg",
"monkey.svg",
"ツチノコアイコン1.svg",
"ネズミアイコン.svg",
"ネッシーアイコン2.svg",
"フラミンゴアイコン2.svg",
"ラクダアイコン2.svg",
"恐竜アイコン2.svg"
};
shapes = new PShape[fileList.length];
for (int k = 0; k < fileList.length; k++) {
shapes[k] = loadShape(fileList[k]);
shapes[k].disableStyle();
}
ncp = new NonCircularPacking(null, 16);
generateItems(ncp);
println("done");
}
void draw() {
background(220);
ncp.draw(g, frameCount);
}
void generateItems(NonCircularPacking ncp) {
for (int k = 0; k < 100; k++) {
PVector pos = new PVector(random(0, width), random(0, height));
float rot = random(0, TWO_PI);
color c = color(random(0, 128));
int idx = (int)random(0, shapes.length);
for (int l = 0; l < 10; l++) {
float sc = 0.5 * (1.0 - (float)l / 10);
ShapeItem item = new ShapeItem(shapes[idx], pos, rot, sc, c);
if (!ncp.isOverlapped(item)) {
ncp.addItem(item);
break;
}
}
}
}
void mousePressed() {
if (mouseButton == LEFT) {
boolean isput = false;
PVector pos = new PVector(mouseX, mouseY);
float rot = random(0, TWO_PI);
color c = color(random(0, 128));
int idx = (int)random(0, shapes.length);
for (int l = 0; l < 10; l++) {
float sc = 0.5 * (1.0 - (float)l / 10);
ShapeItem item = new ShapeItem(shapes[idx], pos, rot, sc, c);
if (!ncp.isOverlapped(item)) {
ncp.addItem(item);
isput = true;
break;
}
}
if (isput) {
println("ok");
}
} else if (mouseButton == RIGHT) {
save("example.png");
}
}