A semi-auto random block profile pic generator perhaps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// algo | |
int minBlockWidth = 2; | |
int minBlockHeight = 2; | |
int maxBlockWidth = 5; | |
int maxBlockHeight = 5; | |
class Block | |
{ | |
color c; | |
int ix; | |
int iy; | |
int iw; | |
int ih; | |
Block(int _x, int _y, int _w, int _h) | |
{ | |
ix = _x; | |
iy = _y; | |
iw = _w; | |
ih = _h; | |
} | |
} | |
enum CutType | |
{ | |
NoCut, | |
Horizontal, | |
Vertical | |
} | |
class CutDecision | |
{ | |
CutType type; | |
int offset; | |
CutDecision(CutType _type, int _offset) | |
{ | |
this.type = _type; | |
this.offset = _offset; | |
} | |
} | |
ArrayList<Block> blocks; | |
void cutOrMakeBlock(Block b) | |
{ | |
CutDecision cut = tryCut(b); | |
if(cut.type == CutType.NoCut) | |
{ | |
blocks.add(b); | |
} | |
else | |
{ | |
if(cut.type == CutType.Vertical) | |
{ | |
Block b1 = new Block(b.ix, b.iy, cut.offset, b.ih); | |
Block b2 = new Block(b.ix + cut.offset, b.iy, b.iw - cut.offset, b.ih); | |
cutOrMakeBlock(b1); | |
cutOrMakeBlock(b2); | |
} | |
else | |
{ | |
Block b1 = new Block(b.ix, b.iy, b.iw, cut.offset); | |
Block b2 = new Block(b.ix, b.iy + cut.offset, b.iw, b.ih - cut.offset); | |
cutOrMakeBlock(b1); | |
cutOrMakeBlock(b2); | |
} | |
} | |
} | |
boolean cutLottery(int operand, int limit) | |
{ | |
if(random(1.0f) < 0.35f) return random(limit) < operand; | |
return false; | |
} | |
CutDecision tryCut(Block b) | |
{ | |
CutType type = CutType.NoCut; | |
boolean canCutVertically = b.iw >= minBlockWidth * 2; | |
boolean canCutHorizontally = b.ih >= minBlockHeight * 2; | |
boolean mustCutVertically = b.iw > maxBlockWidth; | |
boolean mustCutHorizontally = b.ih > maxBlockHeight; | |
if(mustCutHorizontally && mustCutVertically) | |
{ | |
type = random(1.0f) < 0.5f ? CutType.Horizontal : CutType.Vertical; | |
} | |
else if(mustCutHorizontally) | |
{ | |
type = CutType.Horizontal; | |
} | |
else if(mustCutVertically) | |
{ | |
type = CutType.Vertical; | |
} | |
// neither direction is a must-cut | |
if(type == CutType.NoCut) | |
{ | |
if(canCutHorizontally && canCutVertically) | |
{ | |
if(cutLottery(max(b.iw, b.ih), max(minBlockWidth, minBlockHeight))) | |
{ | |
type = random(1.0f) < 0.5f ? CutType.Horizontal : CutType.Vertical; | |
} | |
} | |
else if(canCutVertically) | |
{ | |
if(cutLottery(b.iw, minBlockWidth)) | |
{ | |
type = CutType.Vertical; | |
} | |
} | |
else if(canCutHorizontally) | |
{ | |
if(cutLottery(b.ih, minBlockHeight)) | |
{ | |
type = CutType.Horizontal; | |
} | |
} | |
if(type == CutType.NoCut) | |
{ | |
return new CutDecision(type, 0); | |
} | |
} | |
if(type == CutType.Vertical) | |
{ | |
return new CutDecision(type, (int)random(b.iw - 2 * minBlockWidth) + minBlockWidth); | |
} | |
else | |
{ | |
return new CutDecision(type, (int)random(b.ih - 2 * minBlockHeight) + minBlockHeight); | |
} | |
} | |
// app | |
int gWidth = 9; | |
int gHeight = 9; | |
int gSize = 40; | |
int borderGapPixels = 10; | |
int innerBorderGapPixels = 0; | |
int fillGapPixels = 5; | |
color[] colors = new color[] { #708C84, #9BA685, #BFAA69, #D9AC59 }; | |
void settings() | |
{ | |
size(gSize * gWidth + borderGapPixels * 2, gSize * gHeight + borderGapPixels * 2); | |
} | |
void setup() | |
{ | |
background(245); | |
strokeWeight(1); | |
blocks = new ArrayList<Block>(); | |
cutOrMakeBlock(new Block(0, 0, gWidth, gHeight)); | |
drawOnce(); | |
} | |
void drawOnce() | |
{ | |
for (int i = 0; i < blocks.size(); i++) | |
{ | |
noFill(); | |
stroke(200); | |
rect( | |
borderGapPixels + blocks.get(i).ix * gSize + innerBorderGapPixels, | |
borderGapPixels + blocks.get(i).iy * gSize + innerBorderGapPixels, | |
blocks.get(i).iw * gSize - innerBorderGapPixels * 2, | |
blocks.get(i).ih * gSize - innerBorderGapPixels * 2); | |
color c = colors[(int)random(colors.length)]; | |
fill(c); | |
noStroke(); | |
rect( | |
borderGapPixels + blocks.get(i).ix * gSize + innerBorderGapPixels + fillGapPixels, | |
borderGapPixels + blocks.get(i).iy * gSize + innerBorderGapPixels + fillGapPixels, | |
blocks.get(i).iw * gSize - (innerBorderGapPixels + fillGapPixels) * 2, | |
blocks.get(i).ih * gSize - (innerBorderGapPixels + fillGapPixels) * 2); | |
} | |
} | |
boolean shouldRedraw = false; | |
void draw() | |
{ | |
if(shouldRedraw) | |
{ | |
clear(); | |
background(245); | |
strokeWeight(1); | |
drawOnce(); | |
shouldRedraw = false; | |
} | |
} | |
void keyPressed() | |
{ | |
if (key == 'A' || key == 'a') | |
{ | |
blocks = new ArrayList<Block>(); | |
cutOrMakeBlock(new Block(0, 0, gWidth, gHeight)); | |
} | |
if (key == 'S' || key == 's') | |
{ | |
save("saved_image.png"); | |
} | |
else | |
{ | |
shouldRedraw = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment