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); } }