Skip to content

Commit 900ff12

Browse files
authored
Working on the Overlapping Model (#44)
* overlapping model * overlapping model quick try * debug lines * it woiks * simplify, store adjcenies * fix comments * debugging conflicts * stuck where it shouldn't be stuck * with recursion * recursion depth of 10 * working overlapping * DIM 40 * working on WFC overlapping * working on opening logo animation * rendering for thumb and animation * refactor directories and add Processing ports * update the README * tiled not tiling * GIFs * gifs
1 parent 383324c commit 900ff12

File tree

242 files changed

+2814
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

242 files changed

+2814
-21
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
.DS_Store
1+
.DS_Store
2+
render*
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
// --------------------------------------------
3+
// Class: Cell
4+
// --------------------------------------------
5+
class Cell {
6+
float x, y, w;
7+
int index;
8+
9+
ArrayList<Integer> options; // Which tile indices are still valid
10+
boolean collapsed;
11+
boolean checked;
12+
13+
// Keep track of previous # of options for entropy
14+
int previousTotalOptions = -1;
15+
// Shannon Entropy
16+
float entropy;
17+
boolean needsRedraw;
18+
19+
Cell(ArrayList<Tile> tiles, float x, float y, float w, int index) {
20+
this.x = x;
21+
this.y = y;
22+
this.w = w;
23+
this.index = index;
24+
this.collapsed = false;
25+
this.checked = false;
26+
this.needsRedraw = true;
27+
options = new ArrayList<Integer>();
28+
29+
// Start with *all* tile indices
30+
for (int i = 0; i < tiles.size(); i++) {
31+
options.add(i);
32+
}
33+
}
34+
35+
// Compute Shannon entropy for the cell
36+
void calculateEntropy() {
37+
// If the # of options hasn't changed, skip
38+
if (this.previousTotalOptions == this.options.size()) {
39+
return;
40+
}
41+
this.previousTotalOptions = this.options.size();
42+
43+
// Compute total frequency
44+
float totalFreq = 0;
45+
for (int optIndex : options) {
46+
totalFreq += tiles.get(optIndex).frequency;
47+
}
48+
49+
// Shannon Entropy = - sum( p * log2(p) )
50+
float e = 0;
51+
for (int optIndex : options) {
52+
float freq = tiles.get(optIndex).frequency;
53+
float p = freq / totalFreq;
54+
if (p > 0) {
55+
e -= p * (log(p) / log(2));
56+
}
57+
}
58+
this.entropy = e;
59+
}
60+
61+
// Render the cell
62+
void show() {
63+
if (!this.needsRedraw) return;
64+
65+
if (options.size() == 0) {
66+
// In conflict: draw nothing or maybe highlight
67+
} else if (collapsed) {
68+
// If the cell is collapsed, draw the tile's center color
69+
int tileIndex = options.get(0);
70+
PImage img = tiles.get(tileIndex).img;
71+
renderCell(img, x, y, w);
72+
} else {
73+
// Average center color of all possible tiles
74+
float sumR = 0;
75+
float sumG = 0;
76+
float sumB = 0;
77+
for (int idx : options) {
78+
PImage img = tiles.get(idx).img;
79+
int center = (TILE_SIZE / 2) + (TILE_SIZE / 2) * TILE_SIZE;
80+
int col = img.pixels[center];
81+
sumR += red(col);
82+
sumG += green(col);
83+
sumB += blue(col);
84+
}
85+
sumR /= options.size();
86+
sumG /= options.size();
87+
sumB /= options.size();
88+
noStroke();
89+
fill(sumR, sumG, sumB);
90+
rect(x, y, w, w);
91+
}
92+
this.needsRedraw = false;
93+
}
94+
}
+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// --------------------------------------------
2+
// Class: Tile
3+
// --------------------------------------------
4+
class Tile {
5+
PImage img;
6+
int index;
7+
int frequency;
8+
9+
// Each tile has adjacency lists for each direction
10+
ArrayList<Integer>[] neighbors;
11+
12+
// Constructor
13+
Tile(PImage img, int index) {
14+
this.img = img;
15+
this.index = index;
16+
this.frequency = 1; // Start with frequency=1
17+
neighbors = new ArrayList[4];
18+
for (int k = 0; k < 4; k++) {
19+
neighbors[k] = new ArrayList<Integer>();
20+
}
21+
}
22+
23+
// Determine which tiles can neighbor this tile in each direction
24+
void calculateNeighbors(ArrayList<Tile> allTiles) {
25+
for (int i = 0; i < allTiles.size(); i++) {
26+
Tile other = allTiles.get(i);
27+
if (overlapping(other, EAST)) {
28+
neighbors[EAST].add(i);
29+
}
30+
if (overlapping(other, WEST)) {
31+
neighbors[WEST].add(i);
32+
}
33+
if (overlapping(other, NORTH)) {
34+
neighbors[NORTH].add(i);
35+
}
36+
if (overlapping(other, SOUTH)) {
37+
neighbors[SOUTH].add(i);
38+
}
39+
}
40+
}
41+
42+
// Check if this tile and 'other' match in a given direction
43+
boolean overlapping(Tile other, int direction) {
44+
// Make sure pixel data is loaded
45+
this.img.loadPixels();
46+
other.img.loadPixels();
47+
int w = TILE_SIZE;
48+
49+
if (direction == EAST) {
50+
// Compare right edge of 'this' to left edge of 'other'
51+
for (int x = 1; x < w; x++) {
52+
for (int y = 0; y < w; y++) {
53+
int indexA = (x + y * w);
54+
int indexB = (x - 1 + y * w);
55+
if (differentColor(this.img, indexA, other.img, indexB)) {
56+
return false;
57+
}
58+
}
59+
}
60+
return true;
61+
} else if (direction == WEST) {
62+
// Compare left edge of 'this' to right edge of 'other'
63+
for (int x = 0; x < w - 1; x++) {
64+
for (int y = 0; y < w; y++) {
65+
int indexA = (x + y * w);
66+
int indexB = (x + 1 + y * w);
67+
if (differentColor(this.img, indexA, other.img, indexB)) {
68+
return false;
69+
}
70+
}
71+
}
72+
return true;
73+
} else if (direction == NORTH) {
74+
// Compare top edge of 'this' to bottom edge of 'other'
75+
for (int y = 0; y < w - 1; y++) {
76+
for (int x = 0; x < w; x++) {
77+
int indexA = (x + y * w);
78+
int indexB = (x + (y + 1) * w);
79+
if (differentColor(this.img, indexA, other.img, indexB)) {
80+
return false;
81+
}
82+
}
83+
}
84+
return true;
85+
} else if (direction == SOUTH) {
86+
// Compare bottom edge of 'this' to top edge of 'other'
87+
for (int y = 1; y < w; y++) {
88+
for (int x = 0; x < w; x++) {
89+
int indexA = (x + y * w);
90+
int indexB = (x + (y - 1) * w);
91+
if (differentColor(this.img, indexA, other.img, indexB)) {
92+
return false;
93+
}
94+
}
95+
}
96+
return true;
97+
}
98+
return false;
99+
}
100+
}
101+
102+
103+
// Utility: check if two pixels differ
104+
boolean differentColor(PImage imgA, int indexA, PImage imgB, int indexB) {
105+
int cA = imgA.pixels[indexA];
106+
int cB = imgB.pixels[indexB];
107+
return cA != cB;
108+
}

0 commit comments

Comments
 (0)