diff --git a/examples/fractal_tree.scad b/examples/fractal_tree.scad index ba4373d..c367a76 100644 --- a/examples/fractal_tree.scad +++ b/examples/fractal_tree.scad @@ -18,12 +18,12 @@ module leaf(s) { module branches(minsize){ if($parent_size2.x>minsize) { attach(TOP) - zrot(gaussian_rand(90,20)) - zrot_copies(n=floor(log_rand(2,5,4))) - zrot(gaussian_rand(0,5)) - yrot(gaussian_rand(30,10)) + zrot(gaussian_rands(90,20)[0]) + zrot_copies(n=floor(log_rands(2,5,4)[0])) + zrot(gaussian_rands(0,5)[0]) + yrot(gaussian_rands(30,10)[0]) let( - sc = gaussian_rand(0.7,0.05), + sc = gaussian_rands(0.7,0.05)[0], s1 = $parent_size.z*sc, s2 = $parent_size2.x ) @@ -32,7 +32,7 @@ module branches(minsize){ } else { recolor("springgreen") 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); diff --git a/math.scad b/math.scad index b51c862..70dab70 100644 --- a/math.scad +++ b/math.scad @@ -259,39 +259,49 @@ function log2(x) = ln(x)/ln(2); // min = Minimum integer value to return. // max = Maximum integer value to return. // N = Number of random integers to return. -// seed = Random number seed. +// seed = If given, sets the random number seed. // Example: // ints = rand_int(0,100,3); // 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") let (rvect = is_def(seed) ? rands(min,max+1,N,seed) : rands(min,max+1,N)) [for(entry = rvect) floor(entry)]; -// Function: gaussian_rand() +// Function: gaussian_rands() // Usage: -// gaussian_rand(mean, stddev) +// gaussian_rands(mean, stddev, [N], [seed]) // Description: // Returns a random number with a gaussian/normal distribution. // Arguments: // mean = The average random number returned. // stddev = The standard deviation of the numbers to be returned. -function gaussian_rand(mean, stddev) = - let(s=rands(0,1,2)) mean + stddev*sqrt(-2*ln(s.x))*cos(360*s.y); +// N = Number of random numbers to return. Default: 1 +// 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: -// log_rand(minval, maxval, factor); +// log_rands(minval, maxval, factor, [N], [seed]); // Description: // Returns a single random number, with a logarithmic distribution. // Arguments: // minval = Minimum value to return. // 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. -function log_rand(minval, maxval, factor) = - -ln(1-rands(1-1/pow(factor,minval), 1-1/pow(factor,maxval), 1)[0])/ln(factor); +// N = Number of random numbers to return. Default: 1 +// 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() diff --git a/tests/test_math.scad b/tests/test_math.scad index 304fe14..994ae76 100644 --- a/tests/test_math.scad +++ b/tests/test_math.scad @@ -168,9 +168,42 @@ module test_log2() { test_log2(); -// TODO: Tests for rand_int() -// TODO: Tests for gaussian_rand() -// TODO: Tests for log_rand() +module test_rand_int() { + nums = rand_int(-100,100,1000,seed=2134); + 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() { diff --git a/version.scad b/version.scad index 8af989f..45c5acf 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,9]; +BOSL_VERSION = [2,0,10]; // Section: BOSL Library Version Functions