package wordcram; import java.util.Random; import processing.core.PApplet; import processing.core.PConstants; /** * Some pre-fab WordAnglers. *
* If you want a pretty typical WordAngler, it's probably in here; if you want
* to know how to build your own WordAngler, you can learn from the source for
* these.
*
* @author Dan Bernier
*/
public class Anglers {
/**
* @return a WordAngler that gives a random angle every time it's called.
*/
public static WordAngler random() {
final Random r = new Random();
return (Word w) -> r.nextFloat() * PConstants.TWO_PI;
}
/**
* @param min
* the lower-bound of the angle range
* @param max
* the upper-bound of the angle range
* @return a WordAngler that gives a random angle between min and max, every
* time it's called.
*/
public static WordAngler randomBetween(final float min, final float max) {
final Random r = new Random();
final float difference = max - min;
return (Word w) -> (r.nextFloat() * difference) + min;
}
/**
* @return a WordAngler that angles all words between -7 degrees and 7
* degrees, for a "heaped" effect.
*/
public static WordAngler heaped() {
final float angle = PApplet.radians(7);
return randomBetween(-angle, angle);
}
/**
* If you want all your words to be drawn at the same angle, use this. For
* example, {@link #horiz()} is basically implemented as
* return alwaysUse(0f);
.
*
* @see #horiz()
* @param angle
* The angle all words should be rotated at.
* @return a WordAngler that always returns the given angle parameter.
*/
public static WordAngler alwaysUse(final float angle) {
return (Word w) -> angle;
}
/**
* Just like {@link #alwaysUse(float)}, but it takes multiple angles. If you
* want all your words to be drawn at the same N angles, pass those angles
* to {@link #alwaysUse(float)}. You can pass as many angles as you like.
*
* For example, if you want all your words drawn on 45° and 135°
* angles, use Anglers.pickFrom(radians(45), radians(135))
.
* {@link #hexes()} is a similar example.
*
* @see #alwaysUse(float)
* @see #hexes()
* @param angles
* The angles all words should be rotated at.
* @return A WordAngler that will pick one of the angles, at random, for
* each word.
*/
public static WordAngler pickFrom(final float... angles) {
final Random r = new Random();
return (Word w) -> angles[r.nextInt(angles.length)];
}
/**
* A WordAngler that draws all words at hexagonal angles, or (if you're a
* bit more mathy) 0π/6, 1π/6, 2π/6, 3π/6, 4π/6, and 5π/6.
* It gives a vaguely snow-flake look.
*
* It's implemented with {@link #pickFrom(float...)}. *
* (In retrospect, this is probably not one you'll use very often, so it * might not merit a place in Anglers. But whatever.) * * @see #pickFrom(float...) * @return a WordAngler that draws all words at hexagonal angles. */ public static WordAngler hexes() { float oneSixth = PConstants.TWO_PI / 6f; return pickFrom(0f, oneSixth, 2 * oneSixth, 3 * oneSixth, 4 * oneSixth, 5 * oneSixth); } /** * A WordAngler that draws all words horizontally. It uses * {@link #alwaysUse(float)}. * * @return a WordAngler that draws all words horizontally. */ public static WordAngler horiz() { return alwaysUse(0f); } /** * A WordAngler that draws all words vertically, pointing both up and down. * It uses {@link #pickFrom(float...)}. * * @return a WordAngler that draws all words vertically, pointing both up * and down. */ public static WordAngler upAndDown() { return pickFrom(PConstants.HALF_PI, -PConstants.HALF_PI); } /** * A WordAngler that draws 5/7 words horizontally, and the rest going up and * down. It makes for a pretty nice effect. A WordAngler that draws all * words vertically, pointing both up and down. It uses * {@link #pickFrom(float...)}. * * @return a WordAngler that draws most of the words horizontally, and the * rest vertically. */ public static WordAngler mostlyHoriz() { return pickFrom(0f, 0f, 0f, 0f, 0f, PConstants.HALF_PI, -PConstants.HALF_PI); } }