|
![](/i/fill.gif) |
This is an attempt at a "random" number generator in povray.
I have not tested it that much but the results *look* random
to me. The actual random number generator only works with
8 bit values so I call it four times multiply those results
to get a single float value.
Dunno if it will work under mega pov: might have to rename
some of the variables first.
Enjoy
Pete
--
#version 3.1;
#declare I = 0; // 1st index
#declare J = 0; // second index
#declare S = array[256] // thrash array
#declare K = array[256] // thrash init array
// this next array is where you put the starting seed.
// Put in four positive integer numbers, each in the
// range 0 to 99999999.
#declare thrash_seed = array[4]{
68726648,
05634878,
77888472,
98989388
}
// pop seeds into init array
#declare K[0] = int(thrash_seed[0] / (256 * 256 * 256));
#declare K[1] = mod(int(thrash_seed[0] / (256 * 256)), 256);
#declare K[2] = mod(int(thrash_seed[0] / 256), 256);
#declare K[3] = mod(thrash_seed[0], 256);
#declare K[4] = int(thrash_seed[1] / (256 * 256 * 256));
#declare K[5] = mod(int(thrash_seed[1] / (256 * 256)), 256);
#declare K[6] = mod(int(thrash_seed[1] / 256), 256);
#declare K[7] = mod(thrash_seed[1], 256);
#declare K[8] = int(thrash_seed[2] / (256 * 256 * 256));
#declare K[9] = mod(int(thrash_seed[2] / (256 * 256)), 256);
#declare K[10] = mod(int(thrash_seed[2] / 256), 256);
#declare K[11] = mod(thrash_seed[2], 256);
#declare K[12] = int(thrash_seed[3] / (256 * 256 * 256));
#declare K[13] = mod(int(thrash_seed[3] / (256 * 256)), 256);
#declare K[14] = mod(int(thrash_seed[3] / 256), 256);
#declare K[15] = mod(thrash_seed[3], 256);
// copy/spread out the seeds into the thrasher array
#declare cc = 0;
#while (cc < (256 / 16))
#declare K[cc + 16] = K[cc];
#declare K[cc + 32] = K[cc];
#declare K[cc + 48] = K[cc];
#declare K[cc + 64] = K[cc];
#declare K[cc + 80] = K[cc];
#declare K[cc + 96] = K[cc];
#declare K[cc + 112] = K[cc];
#declare K[cc + 128] = K[cc];
#declare K[cc + 144] = K[cc];
#declare K[cc + 160] = K[cc];
#declare K[cc + 176] = K[cc];
#declare K[cc + 192] = K[cc];
#declare K[cc + 208] = K[cc];
#declare K[cc + 224] = K[cc];
#declare K[cc + 240] = K[cc];
#declare cc = cc + 1;
#end
// now initialize S array
#declare cc = 0;
#while (cc < 256)
#declare S[cc] = cc;
#declare cc = cc + 1;
#end
// shuffle S using K
#render "shuffle S using K ... \n"
#declare I = 0;
#while (I < 256)
#declare J = mod((J + S[I] + K[I]), 256);
#declare swap_temp = S[I];
#declare S[I] = S[J];
#declare S[J] = swap_temp;
#declare I = I + 1;
#end
// you could toss the K array at this point since we won't use it.
#declare I = 0;
#declare J = 0;
#macro fetch_one_256() // returns integer value in range 0-255
#declare I = mod((I + 1), 256);
#declare J = mod((J + S[I]), 256);
#declare swap_temp = S[I];
#declare S[I] = S[J];
#declare S[J] = swap_temp;
#local T = mod((S[I] + S[J]), 256);
S[T]
#end
#macro waste_1000() // toss the first 1000 random numbers
// to make a better random
#render "waste_1000 starting\n"
#local cc = 0;
#while (cc < 1000)
#local dummy = fetch_one_256();
#local cc = cc + 1;
#end
#render "waste_1000 finishing\n"
#end
#macro fetch_float() // same output as rand(), but no input parameter
// first build a float value from 4 bytes
#local ff_result = fetch_one_256() * (256 * 256 * 256) +
fetch_one_256() * (256 * 256) +
fetch_one_256() * 256 +
fetch_one_256();
// second scale to 0.0 - 1.0 range
#local ff_result = ff_result / (256 * 256 * 256 * 256);
ff_result // done
#end
waste_1000()
// new test the random
#declare ntsc = false;
global_settings {
assumed_gamma 2.2
}
camera {
location 0
direction <0, 0, 1.5>
#if (ntsc = true)
right <(640 / 400) * (10/11), 0, 0>
#else
right <(640/480), 0, 0>
#end
up <0, 1, 0>
rotate x*50
rotate y*-20
translate <14, 50, -34>
}
#macro rrange(rlo, rhi) // return rand float in specified range
#local real_low = min(rlo, rhi);
#local real_high = max(rlo, rhi);
#local rresult = real_low + fetch_float() * (real_high - real_low);
rresult
#end
#macro rnd_rotate()
rotate <360 * fetch_float(), 360 * fetch_float(), 360 * fetch_float()>
#end
#macro rnd_translate()
translate <
4 - 8 * fetch_float(),
4 - 8 * fetch_float(),
4 - 8 * fetch_float()
>
#end
#macro perturb()
rnd_translate()
rnd_rotate()
#end
plane { // floor
<0, 1, 0>, 0
pigment {
checker
color rgb 1,
color rgb 0.8
scale 8
}
finish { ambient 0.5 diffuse 0.5 }
normal {
agate
bump_size -0.2
perturb()
}
}
#render "floor done\n"
#declare cc = 0;
#while (cc < 400)
#declare xx = rrange(-7.5, 7.5);
#declare yy = rrange(0.5, 15.5);
#declare zz = rrange(-7.5, 7.5);
#local orange = fetch_float();
#local sky_blue = fetch_float();
sphere {
<xx, yy, zz>, 0.5
pigment { color rgb orange * <1, 0.5, 0> + sky_blue * <0, 0.5, 1> }
finish { ambient 0.4 diffuse 0.6 }
}
#declare cc = cc + 1;
#end
light_source {
<0, 0, -3000>
color rgb 0.5
rotate x*34
rotate y*41
}
light_source {
<0, 0, -3000>
color rgb 0.5
rotate x*90
}
/* actual end of this file */
Post a reply to this message
|
![](/i/fill.gif) |