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,134 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.awt.Shape; // awt: word->shape->rect
|
4
|
+
import java.awt.geom.Rectangle2D; // awt: intersects(box), x-y-w-h, bounds
|
5
|
+
import java.util.ArrayList;
|
6
|
+
import java.util.HashMap;
|
7
|
+
|
8
|
+
import processing.core.PApplet;
|
9
|
+
import processing.core.PFont;
|
10
|
+
import processing.core.PVector;
|
11
|
+
|
12
|
+
public class PlacerHeatMap {
|
13
|
+
|
14
|
+
private final Word[] words;
|
15
|
+
private final WordFonter fonter;
|
16
|
+
private final WordSizer sizer;
|
17
|
+
private final WordAngler angler;
|
18
|
+
private final WordPlacer placer;
|
19
|
+
private final WordNudger nudger;
|
20
|
+
private final WordShaper shaper;
|
21
|
+
|
22
|
+
PlacerHeatMap(Word[] words, WordFonter fonter, WordSizer sizer, WordAngler angler, WordPlacer placer, WordNudger nudger, WordShaper shaper) {
|
23
|
+
|
24
|
+
this.fonter = fonter;
|
25
|
+
this.sizer = sizer;
|
26
|
+
this.angler = angler;
|
27
|
+
this.placer = placer;
|
28
|
+
this.nudger = nudger;
|
29
|
+
this.shaper = shaper;
|
30
|
+
this.words = words;
|
31
|
+
}
|
32
|
+
|
33
|
+
class RectStack {
|
34
|
+
ArrayList<Rectangle2D> rects = new ArrayList<>();
|
35
|
+
|
36
|
+
void add(int x, int y, int w, int h) {
|
37
|
+
rects.add(new Rectangle2D.Float(x, y, w, h));
|
38
|
+
}
|
39
|
+
|
40
|
+
int howManyIntersect(int x, int y, int w, int h) {
|
41
|
+
int sum = 0;
|
42
|
+
|
43
|
+
sum = rects.stream().filter((r) -> (r.intersects(x, y, w, h))).map((_item) -> 1).reduce(sum, Integer::sum);
|
44
|
+
|
45
|
+
return sum;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
class RectGrid {
|
50
|
+
RectStack stack;
|
51
|
+
HashMap<Rectangle2D, Integer> levels = new HashMap<>();
|
52
|
+
|
53
|
+
RectGrid(RectStack stack) {
|
54
|
+
this.stack = stack;
|
55
|
+
}
|
56
|
+
|
57
|
+
void measure(int x, int y, int w, int h) {
|
58
|
+
Rectangle2D plot = new Rectangle2D.Float(x, y, w, h);
|
59
|
+
int level = stack.howManyIntersect(x, y, w, h);
|
60
|
+
levels.put(plot, level);
|
61
|
+
}
|
62
|
+
|
63
|
+
int maxLevel() {
|
64
|
+
int maxLevel = 0;
|
65
|
+
for (Integer level : levels.values()) {
|
66
|
+
if (level > maxLevel) {
|
67
|
+
maxLevel = level;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
return maxLevel;
|
71
|
+
}
|
72
|
+
|
73
|
+
void draw(PApplet sketch) {
|
74
|
+
int rowHeight = 10;
|
75
|
+
int colWidth = 10;
|
76
|
+
int rows = (int)(sketch.height / (float)rowHeight);
|
77
|
+
int cols = (int)(sketch.width / (float)colWidth);
|
78
|
+
|
79
|
+
for (int i = 0; i < rows; i++) {
|
80
|
+
int y = i * rowHeight;
|
81
|
+
for (int j = 0; j < cols; j++) {
|
82
|
+
int x = j * colWidth;
|
83
|
+
|
84
|
+
measure(x, y, colWidth, rowHeight);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
sketch.colorMode(PApplet.HSB);
|
89
|
+
|
90
|
+
int max = maxLevel();
|
91
|
+
levels.keySet().forEach((rect) -> {
|
92
|
+
Integer level = levels.get(rect);
|
93
|
+
|
94
|
+
int c = sketch.color(0);
|
95
|
+
if (level > 0) {
|
96
|
+
float scaled = (float)level / 8;
|
97
|
+
int hue = (int)PApplet.map(scaled, 0, 1, 85, 0); // 85 = pure green
|
98
|
+
c = sketch.color(hue, 255, 255);
|
99
|
+
}
|
100
|
+
|
101
|
+
sketch.fill(c);
|
102
|
+
sketch.rect((float)rect.getX(), (float)rect.getY(), (float)rect.getWidth(), (float)rect.getHeight());
|
103
|
+
});
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
public void draw(PApplet sketch) {
|
108
|
+
RectStack rectStack = new RectStack();
|
109
|
+
|
110
|
+
for (int i = 0; i < words.length; i++) {
|
111
|
+
Word word = words[i];
|
112
|
+
PFont wordFont = word.getFont(fonter);
|
113
|
+
float wordSize = word.getSize(sizer, i, words.length);
|
114
|
+
float wordAngle = word.getAngle(angler);
|
115
|
+
|
116
|
+
Shape shape = shaper.getShapeFor(word.word, wordFont, wordSize, wordAngle);
|
117
|
+
Rectangle2D rect = shape.getBounds2D();
|
118
|
+
//return r.getHeight() < minShapeSize || r.getWidth() < minShapeSize;
|
119
|
+
|
120
|
+
int wordImageWidth = (int)rect.getWidth();
|
121
|
+
int wordImageHeight = (int)rect.getHeight();
|
122
|
+
|
123
|
+
PVector desiredLocation = word.getTargetPlace(placer, i, words.length,
|
124
|
+
wordImageWidth, wordImageHeight, sketch.width, sketch.height);
|
125
|
+
|
126
|
+
//sketch.rect(desiredLocation.x, desiredLocation.y, wordImageWidth, wordImageHeight);
|
127
|
+
rectStack.add((int)desiredLocation.x, (int)desiredLocation.y,
|
128
|
+
wordImageWidth, wordImageHeight);
|
129
|
+
}
|
130
|
+
|
131
|
+
RectGrid grid = new RectGrid(rectStack);
|
132
|
+
grid.draw(sketch);
|
133
|
+
}
|
134
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.util.Random;
|
4
|
+
|
5
|
+
import processing.core.PApplet;
|
6
|
+
import processing.core.PVector;
|
7
|
+
|
8
|
+
public class Placers {
|
9
|
+
|
10
|
+
public static WordPlacer horizLine() {
|
11
|
+
final Random r = new Random();
|
12
|
+
|
13
|
+
return (Word word, int wordIndex, int wordsCount, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) -> {
|
14
|
+
int centerHorizLine = (int) ((fieldHeight - wordImageHeight) * 0.5);
|
15
|
+
int centerVertLine = (int) ((fieldWidth - wordImageWidth) * 0.5);
|
16
|
+
|
17
|
+
float xOff = (float) r.nextGaussian() * ((fieldWidth - wordImageWidth) * 0.2f);
|
18
|
+
float yOff = (float) r.nextGaussian() * 50;
|
19
|
+
|
20
|
+
return new PVector(centerVertLine + xOff, centerHorizLine + yOff);
|
21
|
+
/*
|
22
|
+
int adjFieldWidth = fieldWidth - wordImageWidth;
|
23
|
+
int adjFieldHeight = fieldHeight - wordImageHeight;
|
24
|
+
|
25
|
+
float xOff = (float) r.nextGaussian();// * 0.2f;
|
26
|
+
float yOff = (float) r.nextGaussian();// * 0.5f;
|
27
|
+
yOff = (float)Math.pow(yOff, 3) * 1.5f;
|
28
|
+
|
29
|
+
return new PVector(PApplet.map(xOff, -2, 2, 0, adjFieldWidth),
|
30
|
+
PApplet.map(yOff, -2, 2, 0, adjFieldHeight));
|
31
|
+
*/ };
|
32
|
+
}
|
33
|
+
|
34
|
+
public static WordPlacer centerClump() {
|
35
|
+
final Random r = new Random();
|
36
|
+
final float stdev = 0.4f;
|
37
|
+
|
38
|
+
return new WordPlacer() {
|
39
|
+
|
40
|
+
@Override
|
41
|
+
public PVector place(Word word, int wordIndex, int wordsCount,
|
42
|
+
int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) {
|
43
|
+
return new PVector(getOneUnder(fieldWidth - wordImageWidth),
|
44
|
+
getOneUnder(fieldHeight - wordImageHeight));
|
45
|
+
}
|
46
|
+
|
47
|
+
private int getOneUnder(float upperLimit) {
|
48
|
+
return PApplet.round(PApplet.map((float) r.nextGaussian()
|
49
|
+
* stdev, -2, 2, 0, upperLimit));
|
50
|
+
}
|
51
|
+
};
|
52
|
+
}
|
53
|
+
|
54
|
+
public static WordPlacer horizBandAnchoredLeft() {
|
55
|
+
final Random r = new Random();
|
56
|
+
return (Word word, int wordIndex, int wordsCount, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) -> {
|
57
|
+
float x = (1 - word.weight) * fieldWidth * r.nextFloat(); // big=left, small=right
|
58
|
+
float y = ((float) fieldHeight) * 0.5f;
|
59
|
+
return new PVector(x, y);
|
60
|
+
};
|
61
|
+
}
|
62
|
+
|
63
|
+
public static WordPlacer swirl() {
|
64
|
+
return new SwirlWordPlacer();
|
65
|
+
}
|
66
|
+
|
67
|
+
public static WordPlacer upperLeft() {
|
68
|
+
return new UpperLeftWordPlacer();
|
69
|
+
}
|
70
|
+
|
71
|
+
public static WordPlacer wave() {
|
72
|
+
return new WaveWordPlacer();
|
73
|
+
}
|
74
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import processing.core.PApplet;
|
4
|
+
import processing.core.PVector;
|
5
|
+
|
6
|
+
/**
|
7
|
+
* If you're using a custom WordNudger, and having difficulty seeing
|
8
|
+
* how well it works, try wrapping it in a PlottingWordNudger. As your
|
9
|
+
* WordCram is drawn, it'll render tiny dots at each location it
|
10
|
+
* nudges your words to, so you can see how well it's working.
|
11
|
+
*/
|
12
|
+
public class PlottingWordNudger implements WordNudger {
|
13
|
+
|
14
|
+
private final PApplet parent;
|
15
|
+
private final WordNudger wrappedNudger;
|
16
|
+
|
17
|
+
public PlottingWordNudger(PApplet _parent, WordNudger _wrappedNudger) {
|
18
|
+
parent = _parent;
|
19
|
+
wrappedNudger = _wrappedNudger;
|
20
|
+
}
|
21
|
+
|
22
|
+
@Override
|
23
|
+
public PVector nudgeFor(Word word, int attempt) {
|
24
|
+
PVector v = wrappedNudger.nudgeFor(word, attempt);
|
25
|
+
parent.pushStyle();
|
26
|
+
parent.noStroke();
|
27
|
+
|
28
|
+
float alpha = attempt/700f;
|
29
|
+
//alpha = (float) Math.pow(alpha, 3);
|
30
|
+
parent.fill(40, 255, 255); //, alpha * 255);
|
31
|
+
|
32
|
+
PVector wordLoc = PVector.add(v, word.getTargetPlace());
|
33
|
+
parent.ellipse(wordLoc.x, wordLoc.y, 3, 3);
|
34
|
+
parent.popStyle();
|
35
|
+
return v;
|
36
|
+
}
|
37
|
+
|
38
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import processing.core.PApplet;
|
4
|
+
import processing.core.PVector;
|
5
|
+
|
6
|
+
/**
|
7
|
+
* If you're using a custom WordPlacer, and having difficulty seeing
|
8
|
+
* how well it works, try wrapping it in a PlottingWordPlacer. As your
|
9
|
+
* WordCram is drawn, it'll render tiny dots at each word's target
|
10
|
+
* location, so you can sort-of see how far off they are when they're
|
11
|
+
* finally rendered.
|
12
|
+
*/
|
13
|
+
public class PlottingWordPlacer implements WordPlacer {
|
14
|
+
|
15
|
+
private final PApplet parent;
|
16
|
+
private final WordPlacer wrappedPlacer;
|
17
|
+
|
18
|
+
public PlottingWordPlacer(PApplet _parent, WordPlacer _wrappedPlacer) {
|
19
|
+
parent = _parent;
|
20
|
+
wrappedPlacer = _wrappedPlacer;
|
21
|
+
}
|
22
|
+
|
23
|
+
@Override
|
24
|
+
public PVector place(Word word, int wordIndex, int wordsCount, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) {
|
25
|
+
PVector v = wrappedPlacer.place(word, wordIndex, wordsCount, wordImageWidth, wordImageHeight, fieldWidth, fieldHeight);
|
26
|
+
parent.pushStyle();
|
27
|
+
parent.noFill();
|
28
|
+
|
29
|
+
parent.stroke(15, 255, 255, 200);
|
30
|
+
|
31
|
+
parent.ellipse(v.x, v.y, 10, 10);
|
32
|
+
parent.popStyle();
|
33
|
+
return v;
|
34
|
+
}
|
35
|
+
|
36
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.awt.Color; // awt: for fill color
|
4
|
+
import java.awt.Graphics2D; // awt: draws the word to the screen
|
5
|
+
import java.awt.RenderingHints; // awt: for constants while rendering a word
|
6
|
+
import java.awt.geom.GeneralPath; // awt: Shape -> Path, fill(path)
|
7
|
+
|
8
|
+
import processing.core.PGraphics;
|
9
|
+
import processing.awt.PGraphicsJava2D;
|
10
|
+
|
11
|
+
class ProcessingWordRenderer implements WordRenderer {
|
12
|
+
PGraphics destination;
|
13
|
+
|
14
|
+
ProcessingWordRenderer(PGraphics destination) {
|
15
|
+
this.destination = destination;
|
16
|
+
}
|
17
|
+
|
18
|
+
@Override
|
19
|
+
public int getWidth() {
|
20
|
+
return destination.width;
|
21
|
+
}
|
22
|
+
|
23
|
+
@Override
|
24
|
+
public int getHeight() {
|
25
|
+
return destination.height;
|
26
|
+
}
|
27
|
+
|
28
|
+
@Override
|
29
|
+
public void drawWord(EngineWord word, Color color) {
|
30
|
+
GeneralPath path2d = new GeneralPath(word.getShape());
|
31
|
+
|
32
|
+
// Graphics2D g2 = (Graphics2D)destination.image.getGraphics();
|
33
|
+
Graphics2D g2 = ((PGraphicsJava2D)destination).g2;
|
34
|
+
|
35
|
+
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
36
|
+
g2.setPaint(color);
|
37
|
+
g2.fill(path2d);
|
38
|
+
}
|
39
|
+
|
40
|
+
@Override
|
41
|
+
public void finish() {}
|
42
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.util.Random;
|
4
|
+
|
5
|
+
import processing.core.PVector;
|
6
|
+
|
7
|
+
/**
|
8
|
+
* A RandomWordNudger, where each attempt's PVector has X & Y coords
|
9
|
+
* distributed randomly around the desired point, multiplied by a standard deviation,
|
10
|
+
* and multiplied by the attempt number (so it gets farther, as it gets more
|
11
|
+
* desperate).
|
12
|
+
*
|
13
|
+
* @author Dan Bernier
|
14
|
+
*/
|
15
|
+
public class RandomWordNudger implements WordNudger {
|
16
|
+
|
17
|
+
private final Random r = new Random();
|
18
|
+
private float stdDev;
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Create a RandomWordNudger with a standard deviation of 0.6.
|
22
|
+
*/
|
23
|
+
public RandomWordNudger() {
|
24
|
+
this(0.6f);
|
25
|
+
}
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Create a RandomWordNudger with your own standard deviation.
|
29
|
+
* @param stdDev
|
30
|
+
*/
|
31
|
+
public RandomWordNudger(float stdDev) {
|
32
|
+
this.stdDev = stdDev;
|
33
|
+
}
|
34
|
+
|
35
|
+
@Override
|
36
|
+
public PVector nudgeFor(Word w, int attempt) {
|
37
|
+
return new PVector(next(attempt), next(attempt));
|
38
|
+
}
|
39
|
+
|
40
|
+
private float next(int attempt) {
|
41
|
+
return (float)r.nextGaussian() * attempt * stdDev;
|
42
|
+
}
|
43
|
+
|
44
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
package wordcram;
|
2
|
+
|
3
|
+
import java.awt.Shape; // awt: passed as arg, turned into Area
|
4
|
+
import java.awt.geom.Area; // awt: from Shape, getBounds2D(), contains(box)
|
5
|
+
import java.awt.geom.Rectangle2D; // awt: from Area, getMinX() and Y(), getMaxX() and Y()
|
6
|
+
import java.util.Random;
|
7
|
+
import processing.core.PVector;
|
8
|
+
|
9
|
+
public class ShapeBasedPlacer implements WordPlacer, WordNudger {
|
10
|
+
|
11
|
+
Area area;
|
12
|
+
float minX;
|
13
|
+
float minY;
|
14
|
+
float maxX;
|
15
|
+
float maxY;
|
16
|
+
Random random;
|
17
|
+
|
18
|
+
public ShapeBasedPlacer(Shape shape) {
|
19
|
+
this.area = new Area(shape);
|
20
|
+
random = new Random();
|
21
|
+
Rectangle2D areaBounds = area.getBounds2D();
|
22
|
+
this.minX = (float) areaBounds.getMinX();
|
23
|
+
this.minY = (float) areaBounds.getMinY();
|
24
|
+
this.maxX = (float) areaBounds.getMaxX();
|
25
|
+
this.maxY = (float) areaBounds.getMaxY();
|
26
|
+
}
|
27
|
+
|
28
|
+
@Override
|
29
|
+
public PVector place(Word w, int rank, int count, int ww, int wh, int fw,
|
30
|
+
int fh) {
|
31
|
+
|
32
|
+
for (int i = 0; i < 1000; i++) {
|
33
|
+
float newX = randomBetween(minX, maxX);
|
34
|
+
float newY = randomBetween(minY, maxY);
|
35
|
+
if (area.contains(newX, newY, ww, wh)) {
|
36
|
+
return new PVector(newX, newY);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
return new PVector(-1, -1);
|
41
|
+
}
|
42
|
+
|
43
|
+
@Override
|
44
|
+
public PVector nudgeFor(Word word, int attempt) {
|
45
|
+
PVector target = word.getTargetPlace();
|
46
|
+
float wx = target.x;
|
47
|
+
float wy = target.y;
|
48
|
+
float ww = word.getRenderedWidth();
|
49
|
+
float wh = word.getRenderedHeight();
|
50
|
+
|
51
|
+
for (int i = 0; i < 1000; i++) {
|
52
|
+
float newX = randomBetween(minX, maxX);
|
53
|
+
float newY = randomBetween(minY, maxY);
|
54
|
+
|
55
|
+
if (area.contains(newX, newY, ww, wh)) {
|
56
|
+
return new PVector(newX - wx, newY - wy);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
return new PVector(-1, -1);
|
61
|
+
}
|
62
|
+
|
63
|
+
float randomBetween(float a, float b) {
|
64
|
+
return a + random.nextFloat() * (b - a);
|
65
|
+
}
|
66
|
+
}
|