ruby_wordcram 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.mvn/extensions.xml +8 -0
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/Rakefile +28 -5
- data/docs/_posts/2017-03-07-getting_started.md +3 -2
- data/docs/_posts/2017-03-07-under_the_hood.md +33 -0
- data/lib/WordCram.jar +0 -0
- data/lib/jsoup-1.10.2.jar +0 -0
- data/lib/ruby_wordcram/version.rb +1 -1
- data/lib/ruby_wordcram.rb +1 -2
- data/pom.rb +53 -0
- data/pom.xml +87 -0
- data/ruby_wordcram.gemspec +1 -2
- data/src/cue/lang/Counter.java +141 -0
- data/src/cue/lang/IterableText.java +10 -0
- data/src/cue/lang/NGramIterator.java +151 -0
- data/src/cue/lang/SentenceIterator.java +86 -0
- data/src/cue/lang/WordIterator.java +60 -0
- data/src/cue/lang/stop/StopWords.java +114 -0
- data/src/cue/lang/stop/arabic +351 -0
- data/src/cue/lang/stop/armenian +45 -0
- data/src/cue/lang/stop/catalan +219 -0
- data/src/cue/lang/stop/croatian +2024 -0
- data/src/cue/lang/stop/czech +256 -0
- data/src/cue/lang/stop/danish +94 -0
- data/src/cue/lang/stop/dutch +107 -0
- data/src/cue/lang/stop/english +183 -0
- data/src/cue/lang/stop/esperanto +180 -0
- data/src/cue/lang/stop/farsi +966 -0
- data/src/cue/lang/stop/finnish +235 -0
- data/src/cue/lang/stop/french +543 -0
- data/src/cue/lang/stop/german +231 -0
- data/src/cue/lang/stop/greek +637 -0
- data/src/cue/lang/stop/hebrew +220 -0
- data/src/cue/lang/stop/hindi +97 -0
- data/src/cue/lang/stop/hungarian +202 -0
- data/src/cue/lang/stop/italian +279 -0
- data/src/cue/lang/stop/latin +1 -0
- data/src/cue/lang/stop/norwegian +176 -0
- data/src/cue/lang/stop/polish +138 -0
- data/src/cue/lang/stop/portuguese +204 -0
- data/src/cue/lang/stop/romanian +284 -0
- data/src/cue/lang/stop/russian +652 -0
- data/src/cue/lang/stop/slovak +110 -0
- data/src/cue/lang/stop/slovenian +448 -0
- data/src/cue/lang/stop/spanish +308 -0
- data/src/cue/lang/stop/swedish +114 -0
- data/src/cue/lang/stop/turkish +117 -0
- data/src/cue/lang/unicode/BlockUtil.java +103 -0
- data/src/cue/lang/unicode/Normalizer.java +55 -0
- data/src/cue/lang/unicode/Normalizer6.java +32 -0
- data/src/license.txt +201 -0
- data/src/wordcram/Anglers.java +137 -0
- data/src/wordcram/BBTree.java +133 -0
- data/src/wordcram/BBTreeBuilder.java +61 -0
- data/src/wordcram/Colorers.java +52 -0
- data/src/wordcram/EngineWord.java +73 -0
- data/src/wordcram/Fonters.java +17 -0
- data/src/wordcram/HsbWordColorer.java +28 -0
- data/src/wordcram/ImageShaper.java +91 -0
- data/src/wordcram/Observer.java +9 -0
- data/src/wordcram/PlacerHeatMap.java +134 -0
- data/src/wordcram/Placers.java +74 -0
- data/src/wordcram/PlottingWordNudger.java +38 -0
- data/src/wordcram/PlottingWordPlacer.java +36 -0
- data/src/wordcram/ProcessingWordRenderer.java +42 -0
- data/src/wordcram/RandomWordNudger.java +44 -0
- data/src/wordcram/RenderOptions.java +10 -0
- data/src/wordcram/ShapeBasedPlacer.java +66 -0
- data/src/wordcram/Sizers.java +54 -0
- data/src/wordcram/SketchCallbackObserver.java +70 -0
- data/src/wordcram/SpiralWordNudger.java +31 -0
- data/src/wordcram/SvgWordRenderer.java +110 -0
- data/src/wordcram/SwirlWordPlacer.java +25 -0
- data/src/wordcram/UpperLeftWordPlacer.java +27 -0
- data/src/wordcram/WaveWordPlacer.java +25 -0
- data/src/wordcram/Word.java +357 -0
- data/src/wordcram/WordAngler.java +20 -0
- data/src/wordcram/WordArray.java +18 -0
- data/src/wordcram/WordBag.java +31 -0
- data/src/wordcram/WordColorer.java +25 -0
- data/src/wordcram/WordCounter.java +96 -0
- data/src/wordcram/WordCram.java +920 -0
- data/src/wordcram/WordCramEngine.java +196 -0
- data/src/wordcram/WordFonter.java +24 -0
- data/src/wordcram/WordNudger.java +44 -0
- data/src/wordcram/WordPlacer.java +44 -0
- data/src/wordcram/WordRenderer.java +10 -0
- data/src/wordcram/WordShaper.java +78 -0
- data/src/wordcram/WordSizer.java +46 -0
- data/src/wordcram/WordSkipReason.java +42 -0
- data/src/wordcram/WordSorterAndScaler.java +31 -0
- data/src/wordcram/WordSource.java +5 -0
- data/src/wordcram/text/Html.java +15 -0
- data/src/wordcram/text/Html2Text.java +17 -0
- data/src/wordcram/text/Text.java +15 -0
- data/src/wordcram/text/TextFile.java +23 -0
- data/src/wordcram/text/TextSource.java +5 -0
- data/src/wordcram/text/WebPage.java +23 -0
- metadata +94 -5
- data/lib/cue.language.jar +0 -0
- data/lib/jsoup-1.7.2.jar +0 -0
- data/vendors/Rakefile +0 -51
@@ -0,0 +1,133 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.util.ArrayList;
|
4
|
+
|
5
|
+
import processing.core.PGraphics;
|
6
|
+
|
7
|
+
public class BBTree {
|
8
|
+
|
9
|
+
private final int left;
|
10
|
+
private final int top;
|
11
|
+
private final int right;
|
12
|
+
private final int bottom;
|
13
|
+
private BBTree[] kids;
|
14
|
+
|
15
|
+
private BBTree parent;
|
16
|
+
private int rootX;
|
17
|
+
private int rootY;
|
18
|
+
|
19
|
+
private int swelling = 0;
|
20
|
+
|
21
|
+
BBTree(int left, int top, int right, int bottom) {
|
22
|
+
this.left = left;
|
23
|
+
this.top = top;
|
24
|
+
this.right = right;
|
25
|
+
this.bottom = bottom;
|
26
|
+
}
|
27
|
+
|
28
|
+
void addKids(BBTree... _kids) {
|
29
|
+
ArrayList<BBTree> kidList = new ArrayList<>();
|
30
|
+
for (BBTree kid : _kids) {
|
31
|
+
if (kid != null) {
|
32
|
+
kidList.add(kid);
|
33
|
+
kid.parent = this;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
kids = kidList.toArray(new BBTree[0]);
|
38
|
+
}
|
39
|
+
|
40
|
+
public void setLocation(int left, int top) {
|
41
|
+
rootX = left;
|
42
|
+
rootY = top;
|
43
|
+
}
|
44
|
+
|
45
|
+
private BBTree getRoot() {
|
46
|
+
return parent == null ? this : parent.getRoot();
|
47
|
+
}
|
48
|
+
|
49
|
+
public boolean overlaps(BBTree otherTree) {
|
50
|
+
if (rectCollide(this, otherTree)) {
|
51
|
+
if (this.isLeaf() && otherTree.isLeaf()) {
|
52
|
+
return true;
|
53
|
+
}
|
54
|
+
else if (this.isLeaf()) { // Then otherTree isn't a leaf.
|
55
|
+
for (BBTree otherKid : otherTree.kids) {
|
56
|
+
if (this.overlaps(otherKid)) {
|
57
|
+
return true;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
for (BBTree myKid : this.kids) {
|
63
|
+
if (otherTree.overlaps(myKid)) {
|
64
|
+
return true;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
return false;
|
70
|
+
}
|
71
|
+
|
72
|
+
private boolean rectCollide(BBTree aTree, BBTree bTree) {
|
73
|
+
int[] a = aTree.getPoints();
|
74
|
+
int[] b = bTree.getPoints();
|
75
|
+
|
76
|
+
return a[3] > b[1] && a[1] < b[3] && a[2] > b[0] && a[0] < b[2];
|
77
|
+
}
|
78
|
+
|
79
|
+
private int[] getPoints() {
|
80
|
+
BBTree root = getRoot();
|
81
|
+
return new int[] {
|
82
|
+
root.rootX - swelling + left,
|
83
|
+
root.rootY - swelling + top,
|
84
|
+
root.rootX + swelling + right,
|
85
|
+
root.rootY + swelling + bottom
|
86
|
+
};
|
87
|
+
}
|
88
|
+
|
89
|
+
boolean containsPoint(float x, float y) {
|
90
|
+
BBTree root = getRoot();
|
91
|
+
return root.rootX + this.left < x &&
|
92
|
+
root.rootX + this.right > x &&
|
93
|
+
root.rootY + this.top < y &&
|
94
|
+
root.rootY + this.bottom > y;
|
95
|
+
}
|
96
|
+
|
97
|
+
boolean isLeaf() {
|
98
|
+
return kids == null;
|
99
|
+
}
|
100
|
+
|
101
|
+
void swell(int extra) {
|
102
|
+
swelling += extra;
|
103
|
+
if (!isLeaf()) {
|
104
|
+
for (BBTree kid : kids) {
|
105
|
+
kid.swell(extra);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
public void draw(PGraphics g) {
|
111
|
+
g.pushStyle();
|
112
|
+
g.noFill();
|
113
|
+
|
114
|
+
g.stroke(30, 255, 255, 50);
|
115
|
+
drawLeaves(g);
|
116
|
+
|
117
|
+
g.popStyle();
|
118
|
+
}
|
119
|
+
|
120
|
+
private void drawLeaves(PGraphics g) {
|
121
|
+
if (this.isLeaf()) {
|
122
|
+
drawBounds(g, getPoints());
|
123
|
+
} else {
|
124
|
+
for (BBTree kid : kids) {
|
125
|
+
kid.drawLeaves(g);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
private void drawBounds(PGraphics g, int[] rect) {
|
131
|
+
g.rect(rect[0], rect[1], rect[2], rect[3]);
|
132
|
+
}
|
133
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.awt.Shape; // awt: getBounds2D(), contains(box), intersects(box)
|
4
|
+
import java.awt.geom.Rectangle2D; // awt: from shape bounding box, getX() and Y(), width() and height()
|
5
|
+
|
6
|
+
public class BBTreeBuilder {
|
7
|
+
public BBTree makeTree(Shape shape, int swelling) {
|
8
|
+
Rectangle2D bounds = shape.getBounds2D();
|
9
|
+
int minBoxSize = 1;
|
10
|
+
int x = (int) bounds.getX();
|
11
|
+
int y = (int) bounds.getY();
|
12
|
+
int right = x + (int) bounds.getWidth();
|
13
|
+
int bottom = y + (int) bounds.getHeight();
|
14
|
+
|
15
|
+
BBTree tree = makeTree(shape, minBoxSize, x, y, right, bottom);
|
16
|
+
tree.swell(swelling);
|
17
|
+
return tree;
|
18
|
+
}
|
19
|
+
|
20
|
+
private BBTree makeTree(Shape shape, int minBoxSize, int x, int y,
|
21
|
+
int right, int bottom) {
|
22
|
+
|
23
|
+
int width = right - x;
|
24
|
+
int height = bottom - y;
|
25
|
+
|
26
|
+
if (shape.contains(x, y, width, height)) {
|
27
|
+
return new BBTree(x, y, right, bottom);
|
28
|
+
}
|
29
|
+
else if (shape.intersects(x, y, width, height)) {
|
30
|
+
BBTree tree = new BBTree(x, y, right, bottom);
|
31
|
+
|
32
|
+
boolean tooSmallToContinue = width <= minBoxSize;
|
33
|
+
if (!tooSmallToContinue) {
|
34
|
+
int centerX = avg(x, right);
|
35
|
+
int centerY = avg(y, bottom);
|
36
|
+
|
37
|
+
// upper left
|
38
|
+
BBTree t0 = makeTree(shape, minBoxSize, x, y, centerX, centerY);
|
39
|
+
// upper right
|
40
|
+
BBTree t1 = makeTree(shape, minBoxSize, centerX, y, right, centerY);
|
41
|
+
// lower left
|
42
|
+
BBTree t2 = makeTree(shape, minBoxSize, x, centerY, centerX, bottom);
|
43
|
+
// lower right
|
44
|
+
BBTree t3 = makeTree(shape, minBoxSize, centerX, centerY, right, bottom);
|
45
|
+
|
46
|
+
tree.addKids(t0, t1, t2, t3);
|
47
|
+
}
|
48
|
+
|
49
|
+
return tree;
|
50
|
+
}
|
51
|
+
else { // neither contains nor intersects
|
52
|
+
return null;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
private int avg(int a, int b) {
|
57
|
+
// reminder: x >> 1 == x / 2
|
58
|
+
// avg = (a+b)/2 = (a/2)+(b/2) = (a>>1)+(b>>1)
|
59
|
+
return (a + b) >> 1;
|
60
|
+
}
|
61
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.util.Random;
|
4
|
+
|
5
|
+
import processing.core.PApplet;
|
6
|
+
|
7
|
+
public class Colorers {
|
8
|
+
|
9
|
+
public static WordColorer twoHuesRandomSats(final PApplet host) {
|
10
|
+
|
11
|
+
final float[] hues = new float[] { host.random(256), host.random(256) };
|
12
|
+
|
13
|
+
return new HsbWordColorer(host) {
|
14
|
+
@Override
|
15
|
+
public int getColorFor(Word w) {
|
16
|
+
|
17
|
+
float hue = hues[(int)host.random(hues.length)];
|
18
|
+
float sat = host.random(256);
|
19
|
+
float val = host.random(100, 256);
|
20
|
+
|
21
|
+
return host.color(hue, sat, val);
|
22
|
+
}
|
23
|
+
};
|
24
|
+
}
|
25
|
+
|
26
|
+
public static WordColorer twoHuesRandomSatsOnWhite(final PApplet host) {
|
27
|
+
|
28
|
+
final float[] hues = new float[] { host.random(256), host.random(256) };
|
29
|
+
|
30
|
+
return new HsbWordColorer(host) {
|
31
|
+
@Override
|
32
|
+
public int getColorFor(Word w) {
|
33
|
+
|
34
|
+
float hue = hues[(int)host.random(hues.length)];
|
35
|
+
float sat = host.random(256);
|
36
|
+
float val = host.random(156);
|
37
|
+
|
38
|
+
return host.color(hue, sat, val);
|
39
|
+
}
|
40
|
+
};
|
41
|
+
}
|
42
|
+
|
43
|
+
public static WordColorer pickFrom(final int... colors) {
|
44
|
+
final Random r = new Random();
|
45
|
+
return (Word w) -> colors[r.nextInt(colors.length)];
|
46
|
+
}
|
47
|
+
|
48
|
+
// TODO add an overload that takes 1 int (greyscale), 2 ints (greyscale/alpha), etc
|
49
|
+
public static WordColorer alwaysUse(final int color) {
|
50
|
+
return (Word w) -> color;
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.awt.Shape; // awt: holds it; from the Word
|
4
|
+
import java.awt.geom.AffineTransform; // awt: for translating shapes
|
5
|
+
|
6
|
+
import processing.core.PVector;
|
7
|
+
|
8
|
+
class EngineWord {
|
9
|
+
Word word;
|
10
|
+
int rank;
|
11
|
+
|
12
|
+
private Shape shape;
|
13
|
+
private final BBTreeBuilder bbTreeBuilder;
|
14
|
+
private BBTree bbTree;
|
15
|
+
|
16
|
+
private PVector desiredLocation;
|
17
|
+
private PVector currentLocation;
|
18
|
+
|
19
|
+
EngineWord(Word word, int rank, int wordCount, BBTreeBuilder bbTreeBuilder) {
|
20
|
+
this.word = word;
|
21
|
+
this.rank = rank;
|
22
|
+
this.bbTreeBuilder = bbTreeBuilder;
|
23
|
+
word.setEngineWord(this);
|
24
|
+
}
|
25
|
+
|
26
|
+
void setShape(Shape shape, int swelling) {
|
27
|
+
this.shape = shape;
|
28
|
+
this.bbTree = bbTreeBuilder.makeTree(shape, swelling);
|
29
|
+
}
|
30
|
+
|
31
|
+
Shape getShape() {
|
32
|
+
return shape;
|
33
|
+
}
|
34
|
+
|
35
|
+
boolean overlaps(EngineWord other) {
|
36
|
+
return bbTree.overlaps(other.bbTree);
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
boolean containsPoint(float x, float y) {
|
41
|
+
return bbTree.containsPoint(x, y);
|
42
|
+
}
|
43
|
+
|
44
|
+
void setDesiredLocation(WordPlacer placer, int count, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) {
|
45
|
+
desiredLocation = word.getTargetPlace(placer, rank, count, wordImageWidth, wordImageHeight, fieldWidth, fieldHeight);
|
46
|
+
currentLocation = desiredLocation.copy();
|
47
|
+
}
|
48
|
+
|
49
|
+
void nudge(PVector nudge) {
|
50
|
+
currentLocation = PVector.add(desiredLocation, nudge);
|
51
|
+
bbTree.setLocation((int)currentLocation.x, (int)currentLocation.y);
|
52
|
+
}
|
53
|
+
|
54
|
+
void finalizeLocation() {
|
55
|
+
AffineTransform transform = AffineTransform.getTranslateInstance(
|
56
|
+
currentLocation.x, currentLocation.y);
|
57
|
+
shape = transform.createTransformedShape(shape);
|
58
|
+
bbTree.setLocation((int)currentLocation.x, (int)currentLocation.y);
|
59
|
+
word.setRenderedPlace(currentLocation);
|
60
|
+
}
|
61
|
+
|
62
|
+
PVector getCurrentLocation() {
|
63
|
+
return currentLocation.copy();
|
64
|
+
}
|
65
|
+
|
66
|
+
boolean wasPlaced() {
|
67
|
+
return word.wasPlaced();
|
68
|
+
}
|
69
|
+
|
70
|
+
boolean wasSkipped() {
|
71
|
+
return word.wasSkipped();
|
72
|
+
}
|
73
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.util.Random;
|
4
|
+
|
5
|
+
import processing.core.PFont;
|
6
|
+
|
7
|
+
public class Fonters {
|
8
|
+
|
9
|
+
public static WordFonter alwaysUse(final PFont pfont) {
|
10
|
+
return (Word word) -> pfont;
|
11
|
+
}
|
12
|
+
|
13
|
+
public static WordFonter pickFrom(final PFont... fonts) {
|
14
|
+
final Random r = new Random();
|
15
|
+
return (Word w) -> fonts[r.nextInt(fonts.length)];
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import processing.core.PApplet;
|
4
|
+
import processing.core.PConstants;
|
5
|
+
|
6
|
+
abstract class HsbWordColorer implements WordColorer {
|
7
|
+
private PApplet host;
|
8
|
+
private int range;
|
9
|
+
|
10
|
+
HsbWordColorer(PApplet host) {
|
11
|
+
this(host, 255);
|
12
|
+
}
|
13
|
+
HsbWordColorer(PApplet host, int range) {
|
14
|
+
this.host = host;
|
15
|
+
this.range = range;
|
16
|
+
}
|
17
|
+
|
18
|
+
@Override
|
19
|
+
public int colorFor(Word word) {
|
20
|
+
host.pushStyle();
|
21
|
+
host.colorMode(PConstants.HSB, range);
|
22
|
+
int color = getColorFor(word);
|
23
|
+
host.popStyle();
|
24
|
+
return color;
|
25
|
+
}
|
26
|
+
|
27
|
+
abstract int getColorFor(Word word);
|
28
|
+
}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.awt.Shape;
|
4
|
+
import java.awt.Rectangle;
|
5
|
+
import java.awt.geom.Area;
|
6
|
+
import processing.core.PImage;
|
7
|
+
import java.util.ArrayList;
|
8
|
+
|
9
|
+
public class ImageShaper {
|
10
|
+
|
11
|
+
public Shape shape(PImage image, int color) {
|
12
|
+
RectTree tree = new RectTree(0, 0, image.width, image.height);
|
13
|
+
return tree.toShape(image, color);
|
14
|
+
}
|
15
|
+
|
16
|
+
// TODO combine this somehow with BBTree(Builder). It's the same idea.
|
17
|
+
class RectTree {
|
18
|
+
ArrayList<RectTree> kids = null;
|
19
|
+
|
20
|
+
int left; int top; int right; int bottom;
|
21
|
+
int width; int height;
|
22
|
+
RectTree(int l, int t, int r, int b) {
|
23
|
+
left = l;
|
24
|
+
top = t;
|
25
|
+
right = r;
|
26
|
+
bottom = b;
|
27
|
+
|
28
|
+
width = right - left;
|
29
|
+
height = bottom - top; // Yep: upside-down.
|
30
|
+
|
31
|
+
split();
|
32
|
+
}
|
33
|
+
|
34
|
+
private void split() {
|
35
|
+
|
36
|
+
/*
|
37
|
+
Saying width < 2 OR height < 2 means we miss a few odd pixels.
|
38
|
+
Saying width < 2 AND height < 2 means we get them, but it goes a bit slower.
|
39
|
+
For now, we'll go with faster.
|
40
|
+
*/
|
41
|
+
if (width < 2 || height < 2) return;
|
42
|
+
|
43
|
+
int centerX = avg(left, right);
|
44
|
+
int centerY = avg(top, bottom);
|
45
|
+
kids = new ArrayList<>();
|
46
|
+
kids.add(new RectTree(left, top, centerX, centerY));
|
47
|
+
kids.add(new RectTree(centerX, top, right, centerY));
|
48
|
+
kids.add(new RectTree(left, centerY, centerX, bottom));
|
49
|
+
kids.add(new RectTree(centerX, centerY, right, bottom));
|
50
|
+
}
|
51
|
+
|
52
|
+
private int avg(int a, int b) {
|
53
|
+
// reminder: x >> 1 == x / 2
|
54
|
+
// avg = (a+b)/2 = (a/2)+(b/2) = (a>>1)+(b>>1)
|
55
|
+
return (a + b) >> 1;
|
56
|
+
}
|
57
|
+
|
58
|
+
Shape toShape(PImage img, int color) {
|
59
|
+
Area area = new Area();
|
60
|
+
if (isAllCovered(img, color)) {
|
61
|
+
area.add(new Area(new Rectangle(left, top, width, height)));
|
62
|
+
}
|
63
|
+
else if (kids != null) {
|
64
|
+
kids.forEach((kid) -> {
|
65
|
+
area.add(new Area(kid.toShape(img, color)));
|
66
|
+
});
|
67
|
+
}
|
68
|
+
return area;
|
69
|
+
}
|
70
|
+
|
71
|
+
private Boolean isAllCoveredMemo;
|
72
|
+
private boolean isAllCovered(PImage img, int color) {
|
73
|
+
if (isAllCoveredMemo == null) {
|
74
|
+
if (kids == null) {
|
75
|
+
isAllCoveredMemo = (img.get(left, top) == color);
|
76
|
+
}
|
77
|
+
else {
|
78
|
+
// isAllCoveredMemo = kids.all?(&:isAllCovered);
|
79
|
+
isAllCoveredMemo = true;
|
80
|
+
for (RectTree kid : kids) {
|
81
|
+
if (!kid.isAllCovered(img, color)) {
|
82
|
+
isAllCoveredMemo = false;
|
83
|
+
break;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
return isAllCoveredMemo;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|