gaussian_rand() -> gaussian_rands(), log_rand() -> log_rands()

This commit is contained in:
Revar Desmera
2019-11-06 22:19:19 -08:00
parent 5addbe8184
commit 5cca83958f
4 changed files with 63 additions and 20 deletions

View File

@@ -18,12 +18,12 @@ module leaf(s) {
module branches(minsize){ module branches(minsize){
if($parent_size2.x>minsize) { if($parent_size2.x>minsize) {
attach(TOP) attach(TOP)
zrot(gaussian_rand(90,20)) zrot(gaussian_rands(90,20)[0])
zrot_copies(n=floor(log_rand(2,5,4))) zrot_copies(n=floor(log_rands(2,5,4)[0]))
zrot(gaussian_rand(0,5)) zrot(gaussian_rands(0,5)[0])
yrot(gaussian_rand(30,10)) yrot(gaussian_rands(30,10)[0])
let( let(
sc = gaussian_rand(0.7,0.05), sc = gaussian_rands(0.7,0.05)[0],
s1 = $parent_size.z*sc, s1 = $parent_size.z*sc,
s2 = $parent_size2.x s2 = $parent_size2.x
) )
@@ -32,7 +32,7 @@ module branches(minsize){
} else { } else {
recolor("springgreen") recolor("springgreen")
attach(TOP) zrot(90) attach(TOP) zrot(90)
leaf(gaussian_rand(100,5)); leaf(gaussian_rands(100,5)[0]);
} }
} }
recolor("lightgray") cylinder(d1=300, d2=250, l=1500) branches(10); recolor("lightgray") cylinder(d1=300, d2=250, l=1500) branches(10);

View File

@@ -259,39 +259,49 @@ function log2(x) = ln(x)/ln(2);
// min = Minimum integer value to return. // min = Minimum integer value to return.
// max = Maximum integer value to return. // max = Maximum integer value to return.
// N = Number of random integers to return. // N = Number of random integers to return.
// seed = Random number seed. // seed = If given, sets the random number seed.
// Example: // Example:
// ints = rand_int(0,100,3); // ints = rand_int(0,100,3);
// int = rand_int(-10,10,1)[0]; // int = rand_int(-10,10,1)[0];
function rand_int(min,max,N,seed=undef) = function rand_int(min, max, N, seed=undef) =
assert(max >= min, "Max value cannot be smaller than min") assert(max >= min, "Max value cannot be smaller than min")
let (rvect = is_def(seed) ? rands(min,max+1,N,seed) : rands(min,max+1,N)) let (rvect = is_def(seed) ? rands(min,max+1,N,seed) : rands(min,max+1,N))
[for(entry = rvect) floor(entry)]; [for(entry = rvect) floor(entry)];
// Function: gaussian_rand() // Function: gaussian_rands()
// Usage: // Usage:
// gaussian_rand(mean, stddev) // gaussian_rands(mean, stddev, [N], [seed])
// Description: // Description:
// Returns a random number with a gaussian/normal distribution. // Returns a random number with a gaussian/normal distribution.
// Arguments: // Arguments:
// mean = The average random number returned. // mean = The average random number returned.
// stddev = The standard deviation of the numbers to be returned. // stddev = The standard deviation of the numbers to be returned.
function gaussian_rand(mean, stddev) = // N = Number of random numbers to return. Default: 1
let(s=rands(0,1,2)) mean + stddev*sqrt(-2*ln(s.x))*cos(360*s.y); // seed = If given, sets the random number seed.
function gaussian_rands(mean, stddev, N=1, seed=undef) =
let(nums = is_undef(seed)? rands(0,1,N*2) : rands(0,1,N*2,seed))
[for (i = list_range(N)) mean + stddev*sqrt(-2*ln(nums[i*2]))*cos(360*nums[i*2+1])];
// Function: log_rand() // Function: log_rands()
// Usage: // Usage:
// log_rand(minval, maxval, factor); // log_rands(minval, maxval, factor, [N], [seed]);
// Description: // Description:
// Returns a single random number, with a logarithmic distribution. // Returns a single random number, with a logarithmic distribution.
// Arguments: // Arguments:
// minval = Minimum value to return. // minval = Minimum value to return.
// maxval = Maximum value to return. `minval` <= X < `maxval`. // maxval = Maximum value to return. `minval` <= X < `maxval`.
// factor = Log factor to use. Values of X are returned `factor` times more often than X+1. // factor = Log factor to use. Values of X are returned `factor` times more often than X+1.
function log_rand(minval, maxval, factor) = // N = Number of random numbers to return. Default: 1
-ln(1-rands(1-1/pow(factor,minval), 1-1/pow(factor,maxval), 1)[0])/ln(factor); // seed = If given, sets the random number seed.
function log_rands(minval, maxval, factor, N=1, seed=undef) =
assert(maxval >= minval, "maxval cannot be smaller than minval")
let(
minv = 1-1/pow(factor,minval),
maxv = 1-1/pow(factor,maxval),
nums = is_undef(seed)? rands(minv, maxv, N) : rands(minv, maxv, N, seed)
) [for (num=nums) -ln(1-num)/ln(factor)];
// Function: segs() // Function: segs()

View File

@@ -168,9 +168,42 @@ module test_log2() {
test_log2(); test_log2();
// TODO: Tests for rand_int() module test_rand_int() {
// TODO: Tests for gaussian_rand() nums = rand_int(-100,100,1000,seed=2134);
// TODO: Tests for log_rand() assert(len(nums)==1000);
for (num = nums) {
assert(num>=-100);
assert(num<=100);
assert(num==floor(num));
}
}
test_rand_int();
module test_gaussian_rands() {
nums1 = gaussian_rands(0,10,1000,seed=2132);
nums2 = gaussian_rands(0,10,1000,seed=2130);
nums3 = gaussian_rands(0,10,1000,seed=2132);
assert(len(nums1)==1000);
assert(len(nums2)==1000);
assert(len(nums3)==1000);
assert(nums1==nums3);
assert(nums1!=nums2);
}
test_gaussian_rands();
module test_log_rands() {
nums1 = log_rands(0,100,10,1000,seed=2189);
nums2 = log_rands(0,100,10,1000,seed=2310);
nums3 = log_rands(0,100,10,1000,seed=2189);
assert(len(nums1)==1000);
assert(len(nums2)==1000);
assert(len(nums3)==1000);
assert(nums1==nums3);
assert(nums1!=nums2);
}
test_log_rands();
module test_segs() { module test_segs() {

View File

@@ -8,7 +8,7 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
BOSL_VERSION = [2,0,9]; BOSL_VERSION = [2,0,10];
// Section: BOSL Library Version Functions // Section: BOSL Library Version Functions