triangleInt method
Gets a random number centered around center
with range
(inclusive)
using a triangular distribution. For example triangleInt(8, 4)
will
return values between 4 and 12 (inclusive) with greater distribution
towards 8.
This means output values will range from (center - range)
to
(center + range)
inclusive, with most values near the center, but not
with a normal distribution. Think of it as a poor man's bell curve.
The algorithm works essentially by choosing a random point inside the triangle, and then calculating the x coordinate of that point. It works like this:
Consider Center 4, Range 3:
*
* | *
* | | | *
* | | | | | *
--+-----+-----+--
0 1 2 3 4 5 6 7 8
-r c r
Now flip the left half of the triangle (from 1 to 3) vertically and move it over to the right so that we have a square.
.-------.
| V
|
| R L L L
| . R R L L
. . R R R L
. . . R R R R
--+-----+-----+--
0 1 2 3 4 5 6 7 8
Choose a point in that square. Figure out which half of the triangle the point is in, and then remap the point back out to the original triangle. The result is the x coordinate of the point in the original triangle.
Implementation
int triangleInt(int center, int range) {
if (range < 0) {
throw ArgumentError("The argument \"range\" must be zero or greater.");
}
// Pick a point in the square.
int x = inclusive(range);
int y = inclusive(range);
// Figure out which triangle we are in.
if (x <= y) {
// Larger triangle.
return center + x;
} else {
// Smaller triangle.
return center - range - 1 + x;
}
}