Random number generator
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/05/2008 at 10:12, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 10.1.1
Platform: Mac OSX ;
Language(s) : C.O.F.F.E.E ;---------
Can anyone tell me why the following COFFEE code requires at least two calls of the Get01 or Get11 members to generate a non-sequential random number? If I execute the function by playing the timeline forward, random1 creeps from roughly -.9 to 0.9 in increments of rougly 0.05, whereas random2 and random3 seem to generate true random numbers between -1 and 1 even though the same time() seed is used for initialization. I guess my real question is...how do I fix this to avoid processing a behind the scenes random prior to creating a genuine pseudorandom.
Thanksmain(doc, op)
{
var random = new(Random);
random->Init(time());
println("random1 = ", random->Get11());
println("random2 = ", random->Get11());
println("random3 = ", random->Get11());
} -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/05/2008 at 15:04, xxxxxxxx wrote:
Where do you want to create random numbers, is this an expression or a script? If it is an expression you should init the random class only once when the class is created and then call Get11() every time the expression is evaluated.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/05/2009 at 05:35, xxxxxxxx wrote:
Hey!
I'm having a similar related problem. I'm using an expresso / Thinking Particles setup with a COFFEE node which gets "iterated over" for each particle from a pBorn node. I'm using a combination of the birth number of each particle and the time to create a random seed but the results coming from the random number object appear to have a clearly visible pattern to them. I can't do as suggested here and create one instance of the random object as the COFFEE node presumably "runs" once in its entirety per particle birth. I'm on the verge of writing my own pseudo random number generating code but it would be a lot better if I could use the in-built functions. Anyone know how?
Thanks! sCam
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/05/2009 at 11:16, xxxxxxxx wrote:
Still not getting anywhere with this.
I'm still quite new to COFFEE and didn't realize you can declare "global" variables and functions outside the "main" section. Even doing that and therefore being able to follow the advice about only instantiating the random object once is still giving the same results as gj210 originally posted. In fact, to further clarify, what you seem to get is a sequential sequence on the first call (that starts off very low...like 0.00001), and then a pseudo random (yet still essentially sequential) sequence on the second call. Either way it's all completely unusable at the moment. It's not great that any language has had me battling away for a day just trying to make a flippin random number I really hope someone can help!
Cheer, sCam
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/05/2009 at 12:25, xxxxxxxx wrote:
It took me a while to implement Matthias's suggestion above, but he is correct and it works.
In my understanding, a particular seed builds a virtual table (in actuality, I'm suppose it modifies the pseudo random function somehow, others can correct me on this, but you can imagine it as a table specific to that seed.) Each time mRand->Get11() is called thereafter will pull a number, in a repeatable manner, from this "table". As long as you don't rebuild the table with init() and your random calls are less than umpteen-billion^23, you should never see a pattern. If you rebuild the table each frame for example, even if you provide relatively different seeds, as the SDK warns, you will get similar outputs or outputs based on the input pattern of your seeds (this was my problem).
In your case, I would create a seed builder at the start of your function like:>
\> var gMyRandomTable; //Declare each table as a global \> main(doc, op) \> { \> if(!gMyRandomTable) //Your table does not yet exist \> { \> gMyRandomTable = new(Random); \> var vSeed = 1; //If you want the run repeatable (Probably what you want) \> // var vSeed = time(); //Unrepeatable random each time \> //unless you capture the time() seed \> gMyRandomTable->Init(vSeed); \> } \> /\*Now iterate through your particles and call one of the \> gMyRandomTable-Get...() functions to do whatever. You \> don't need time, you don't need pBorn, you don't want to \> change the seed\*/ \> var i; \> for (i=0; i<5; i++) \> println("fori = ", i, " rnd= ", gMyRandomTable->Get11()); \> } \>
When you click through a couple frames, you'll see no repeat. When you hit execute again, no matter what frame, the printed lines should start over.
If you don't use the global, the table will rebuild and the Get...() will start from the beginning on each frame. There may be a better way, but this works for me. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/05/2009 at 13:32, xxxxxxxx wrote:
Can't tell if this might help but,
I remember having some problem "getting" random
and instead ended up using SNoise ...
It's a noise field so one can pick any position in space/time
to get random within a frame.
Sort of like:>
\> var any = particlenumber?/position?/or what you have; \> var myNoise = new(Noise); \> \> var myRandom = myNoise->SNoise(any , time\*mytimemultiplier); \>
Cheers
Lennart -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/05/2009 at 13:57, xxxxxxxx wrote:
Hi guys,
In my experience noise can have the same pattern producing results if you set it up incorrectly. If you set the random correctly, it WILL be random and its easy. Others can correct me, but I imagine is will also be less expensive than noise. Post some example code if you're still having problems and I'm sure we can fix it quickly.
As Matthias says, if in a class, initialize it only once when you first call the class, if in the main() function as in my example above, then the global variable works...may not be the ideal way for genuine coders, but it'll get you where you need to go.
Regards,
Graham -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/05/2009 at 17:42, xxxxxxxx wrote:
... for your specific goals... until someone wiser shows us a better way.