Skip to content

Instantly share code, notes, and snippets.

Created March 1, 2017 16:54
Show Gist options
  • Save anonymous/e085d5d38d91290bd03c04cec16d833c to your computer and use it in GitHub Desktop.
Save anonymous/e085d5d38d91290bd03c04cec16d833c to your computer and use it in GitHub Desktop.
Random polygon packing
import processing.core.*;
import java.awt.*;
import java.util.ArrayList;
public class Main extends PApplet{
String[] palette = {"#6C8D84","#CA9D59","#AD624B","#8A5354","#3D3E53","#6C8D84","#CA9D59","#AD624B"};
ArrayList<Polygon> pol = new ArrayList<>();
public void settings(){
size(490,490);
}
public void setup() {
background(255);
strokeWeight(1);
// frameRate(10);
}
public void draw() {
background(255);
int total = 3;
int count = 0;
int attempts = 0;
while (count < total) {
Polygon newP = newPol();
if (newP != null) {
pol.add(newP);
count++;
}
attempts++;
if (attempts > 10000) {
noLoop();
println("Finished");
break;
}
}
for (Polygon r : pol) {
if (r.outFrame(r.shape))
r.growing = false;
else {
for (Polygon other : pol) {
if (r != other) {
if (other.polyPoly(r.shape,other.shape)) {
r.growing = false;
break;
}
}
}
}
r.show();
r.grow();
}
// if ( frameCount % 1 == 0 ) { saveFrame("output/image-####.gif"); }
}
Polygon newPol() {
float x = random(20,width-20);
float y = random(20,height-20);
float sz = random(3,10);
String color = palette[(int) random(palette.length)];
Polygon poly = new Polygon(this,x,y,sz, pickColor(color));
boolean valid = true;
for (Polygon r : pol) {
if (r.polyPoly(r.shape,poly.shape)){
valid = false;
break;
}
}
if (valid)
return poly;
else
return null;
}
public int pickColor(String clr) {
return Color.decode(clr).getRGB();
}
public static void main(String[] args) {
PApplet.main("Main", args);
}
}
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PVector;
public class Polygon {
PVector[] shape = new PVector[20];
PApplet parent;
float x;
float y;
float sz;
int color;
boolean growing = true;
Polygon(PApplet p, float x_, float y_, float sz_, int color_) {
parent = p;
x = x_;
y = y_;
sz = sz_;
color = color_;
setShape(x,y,sz, true);
}
public void setShape(float x, float y, float sz, boolean grCheck) {
float angle = parent.TWO_PI / shape.length;
for (int i = 0; i < shape.length; i++) {
float a = angle * i;
if (grCheck) {
float px = x + parent.cos(a) * sz * parent.random(1, 2);
float py = y + parent.sin(a) * sz * parent.random(1, 2);
shape[i] = new PVector(px, py);
} else {
float px = shape[i].x + parent.cos(a) * sz / 10;
float py = shape[i].y + parent.sin(a) * sz / 10;
shape[i] = new PVector(px, py);
}
}
}
public void show() {
parent.fill(color, 250);
parent.beginShape();
for (PVector v : shape) {
parent.vertex(v.x, v.y);
}
parent.endShape(PConstants.CLOSE);
}
public void grow() {
if (growing) {
sz += 1;
setShape(x, y, sz, false);
}
}
// out of window detection
public boolean outFrame(PVector[] p1) {
int offset = 2;
return polyLine(p1, offset, offset, offset, parent.height-offset) || polyLine(p1, offset, offset, parent.width-offset, offset) || polyLine(p1, offset, parent.height-offset, parent.width-offset, parent.height-offset) || polyLine(p1, parent.width-offset, offset, parent.width-offset, parent.height-offset);
}
// Collision detection
public boolean polyPoly(PVector[] p1, PVector[] p2) {
int next = 0;
for (int current = 0; current < p1.length; current++) {
next = current + 1;
if (next == p1.length) next = 0;
PVector vc = p1[current];
PVector vn = p1[next];
boolean collision = polyLine(p2, vc.x, vc.y, vn.x, vn.y);
if (collision) return true;
collision = polyPoint(p1, p2[0].x, p2[0].y);
if (collision) return true;
}
return false;
}
public boolean polyLine(PVector[] verticles, float x1, float y1, float x2, float y2) {
int next = 0;
for (int current = 0; current < verticles.length; current++) {
next = current + 1;
if (next == verticles.length) next = 0;
float x3 = verticles[current].x;
float y3 = verticles[current].y;
float x4 = verticles[next].x;
float y4 = verticles[next].y;
boolean hit = lineLine(x1, y1, x2, y2, x3, y3, x4, y4);
if (hit) {
return true;
}
}
return false;
}
public boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
// calculate the direction of the lines
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1.2 && uB >= 0 && uB <= 1.2) {
return true;
}
return false;
}
public boolean polyPoint(PVector[] verticles, float px, float py) {
boolean collision = false;
int next = 0;
for (int current = 0; current < verticles.length; current++) {
next = current + 1;
if (next == verticles.length) next = 0;
PVector vc = verticles[current];
PVector vn = verticles[next];
if (((vc.y > py && vn.y < py) || (vc.y < py && vn.y > py)) && (px < (vn.x - vc.x) * (py - vc.y) / (vn.y - vc.y) + vc.x)) {
collision = !collision;
}
}
return collision;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment