-
Notifications
You must be signed in to change notification settings - Fork 74
/
Flood.pde
87 lines (77 loc) · 2.26 KB
/
Flood.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class Flood {
int stackSize = width*height;
int[] stack = new int[stackSize];
int stackPointer;
int threshold;
Point pop() {
if (stackPointer > 0) {
int p = stack[stackPointer];
stackPointer--;
return new Point(p / height, p % height);
} else {
return null;
}
}
void push(int x, int y) {
if(stackPointer < stackSize - 1 && x >= 0 && x < width) {
stackPointer++;
stack[stackPointer] = height * x + y;
}
}
void emptyStack() {
while (pop () != null);
}
int cdist(int c1, int c2) {
int rmean = ( (c1 >> 16 & 0xFF) + (c2 >> 8 & 0xFF) )/2;
int r = (c1 >> 16 & 0xFF) - (c2 >> 8 & 0xFF);
int g = (c1 >> 8 & 0xFF) - (c2 >> 8 & 0xFF);
int b = (c1 & 0xFF) - (c2 & 0xFF);
int weightR = 512 + rmean;
int weightG = 1024;
int weightB = 512 + 255-rmean;
return weightR*r*r + weightG*g*g + weightB*b*b;
}
boolean isSimilar(int colorA, int colorB) {
return cdist(colorA, colorB) < threshold;
}
Flood(int x, int y, int newColor, int oldColor, int threshold) {
this.threshold = threshold;
loadPixels();
if (oldColor == newColor) return;
emptyStack();
int y1;
boolean spanLeft, spanRight;
push(x, y);
Point po;
while ( (po = pop ()) != null) {
y1 = po.y;
while (y1 >= 0 && isSimilar (pixels[po.x + width * y1], oldColor)) y1--;
y1++;
spanLeft = spanRight = false;
while (y1 < height && isSimilar(pixels[po.x + width * y1], oldColor)) {
pixels[po.x + width * y1] = newColor;
if (!spanLeft && po.x > 0 && isSimilar(pixels[po.x - 1 + width * y1], oldColor)) {
push(po.x - 1, y1);
spanLeft = true;
} else if (spanLeft && po.x > 0 && !isSimilar(pixels[po.x - 1 + width * y1], oldColor)) {
spanLeft = false;
}
if (!spanRight && x < width - 1 && isSimilar(pixels[po.x + 1 + width * y1], oldColor)) {
push(po.x + 1, y1);
spanRight = true;
} else if (spanRight && po.x < width - 1 && !isSimilar(pixels[po.x + 1 + width * y1], oldColor)) {
spanRight = false;
}
y1++;
}
}
updatePixels();
}
}
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}