Jump to content
• Advertisement

# Strange random with srand

This topic is 5198 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

Hi all... This class is supposed to give a random number, that stays the same when i enter the same x and y. The strange thing is that when i use very low random seeds (like 5) my random texture (this gives the random numbers to a perlin noise function that creates the texture) gets very dark. When i use (rand()%100000)/100000 i see only black but with the (rand()%1000)/1000. Everything is bright red (I'm not using the green and blue channels here). I thought that (rand()%1000)/1000 would just deliver me the rest of rand()/1000 and then to make my number between 0 and 1 i divide it by 1000. So it should always be between 0 and 1. This seems to be untrue. Anyone know why? Please help...

#### Share this post

##### Share on other sites
Advertisement
#ifndef NOISE_H#define NOISE_H// All noise amplitudes rannge between 0 and 1.// The inputs range between 0 and 1 (for the 1th octave, there is no 0th octave),// so the second octave is 1/2 and the third 1/4 etc.// Only the FillArray* functions use inputs between 0..Width and 0..Height// and return values between Min and Max.#include <stdlib.h>#include <iostream.h>#include <math.h>class cNoiseGen2D{public:	cNoiseGen2D()				{randseed = 0;}	cNoiseGen2D(int RandSeed)	{randseed = RandSeed;}	float Get(float x, float y)	{									srand( (int)(randseed + x * y * randseed) ); 									return ((float)(rand()%1000))/1000;								}	void Reset(int RandSeed)	{randseed = RandSeed;}private:	int randseed;};class cPerlin2D{public:	// constructor	cPerlin2D(int RandSeed, int Octaves, float Persistence) 		{			gen.Reset(RandSeed); 			octaves = Octaves; 			persistence = Persistence;			maxval = 0;			for (int i = 0; i <= octaves; i++)			{				maxval += pow(persistence, i);			}		}	// Sets the randseed.	void SetRandseed(int RandSeed) {gen.Reset(RandSeed);}	// the higher the persistence the less the amplitude of high freq noise lowers (1 is no lowering).	void SetPersistence(float Persistence)			{		persistence = Persistence;		maxval = 0;		for (int i = 0; i <= octaves; i++)		{			maxval += pow(persistence, i);		}	}	// the number of octaves.	void SetOctaves(int Octaves)					{		octaves = Octaves;		maxval = 0;		for (int i = 0; i <= octaves; i++)		{			maxval += pow(persistence, i);		}	}	// gets the value of the amplitude at x, y.	float Get(float x, float y);	// fills an array with the dimensions 0..width, 0.. height with random chars. (range 0..255)	bool FillArrayb(char * array[], int Width, int Height, char Min, char Max);	// fills an array with the dimensions 0..width, 0.. height with random ints. (range 0..10000)	bool FillArrayi(int * array[], int Width, int Height, int Min, int Max);	// fills an array with the dimensions 0..width, 0.. height with random floats. (range 0..1)	bool FillArrayf(float * array[], int Width, int Height, float Min, float Max);private:	// the function returns an interpolated value between I and J. Returns I when Fraction = 0 and J when Fraction = 1.	float InterpolateCos(float I, float J, float Fraction);	// returns the interpolated noise amplitude for a certain x and y.	float InterpolateNoise(float x, float y);	int octaves;	float maxval; // maxval is used to calculate the maximum value that Get can return, so it can be scaled back to 0..1	float persistence;	cNoiseGen2D gen;};#endif

and this is the .cpp file:
#include "noise.h"float cPerlin2D::Get(float x, float y){	float total = 0;	float freq;	float amp;	for (int i = 0; i <= octaves; i++)	{		freq = pow(2, i);		amp = pow(persistence, i);		total += InterpolateNoise(x * freq, y * freq) * amp;	}	total /= maxval;	return total;}float cPerlin2D::InterpolateCos(float I, float J, float Fraction){	float ft = Fraction * 3.1415927f;	float f = (1.0f - cos(ft)) * 0.50f;	return (I*(1.0f-f) + J*f);}float cPerlin2D::InterpolateNoise(float x, float y){	int ix = int(x); // integer	float fx = x - ix; // fractional	int iy = int(y); // integer	float fy = y - iy; // fractional	float v1 = gen.Get(ix, iy);	float v2 = gen.Get(ix+1, iy);	float v3 = gen.Get(ix,	 iy+1);	float v4 = gen.Get(ix+1, iy+1);	float i1 = InterpolateCos(v1, v2, fx);	float i2 = InterpolateCos(v3, v4, fx);    return InterpolateCos(i1, i2, fy);}

#### Share this post

##### Share on other sites
ok, i found out the x*y are floats and are so small the seed is 0 every time. When i multiply them by a large number i get better results, but not very random anymore, it seems to repeat a lot

#### Share this post

##### Share on other sites
Why are you reseeding your random number generator every time you get a random number?

#### Share this post

##### Share on other sites
Yes i am, because i need to get the same (semi) random number everytime i put the same x and y in this function. Since I want to be able to access them again later. This way I won't need an array of random numbers for my perlin noise. Otherwise these (at high freq) would become immense.

#### Share this post

##### Share on other sites
This is the old generator i used, but i can't seem to seed it, cause I don't get the formula and all the numbers in it seem to be primes.
float Get(float x, float y){	int n = x + y * 57;	n = (n<<13) ^ n;	float out = (1.0 - (float)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);    	// this returns a number between -1 and 1	out = (out + 1) / 2; // now 0..1	return out;}

#### Share this post

##### Share on other sites
Quote:
 Original post by Marty666So it should always be between 0 and 1. This seems to be untrue. Anyone know why?

It *is* between 0 and 1. rand()%1000 will give a number between 0 and 999. (rand()%1000)/1000 will always be 0. The numerator can only get to 999, and doing an integer divide, the result is always 0. Try dividing by 1000.0f instead.

You're using x and y as floats, but you're treating them as integers (x+1, y+1, etc...) instead of values between 0 and 1. This might be fine (I've never done perlin noise, so I'm not sure if it matters at all). What's not fine is that your random numbers are seeded by x+y*57, which means that each line will be a duplicate of the line above it, and 57 pixels to the side, so you'll just be getting staggered rows of identical data.

#### Share this post

##### Share on other sites
Hi... I guess your mistaking my last post with the previous ones. The last works just fine, but i am unable to seed it. Just try it out...
rand() gives a number between 0 and RAND_MAX, which is defined at 0x7fff so that's quite large. By %1000 I take off al the miltiples of 1000, so it's 0..999 and by dividing by 1000 i make it between 0.000 and 0.999. The 1000 just means I want a precision of three decimals. 100 would have been 2 decimals. This in theory should work, but not in my code. For some numbers I get a nice random texture with low contrast. The lower the number the more brightness and the higher the less. I can't seem to find out why that happenes. I'll stick with my previous random function for now. But thanks anyways. If you know how to seed that one, please let me know.

Thanx,
Marty

#### Share this post

##### Share on other sites
Quote:
 rand() gives a number between 0 and RAND_MAX, which is defined at 0x7fff so that's quite large.
Yup.
Quote:
 By %1000 I take off al the miltiples of 1000, so it's 0..999
Yup
Quote:
 and by dividing by 1000 i make it between 0.000 and 0.999.
Nope... I covered that in my post. You make it 0, always.
Quote:
 The 1000 just means I want a precision of three decimals. 100 would have been 2 decimals.
I know what you're trying to do, and why it doesn't work.
Quote:
 This in theory should work, but not in my code
Right. Which is why my post above explained why it didn't work (integer divide) and suggested a fix (floating point divide).

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement

• ### Popular Contributors

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5
• Advertisement

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633730
• Total Posts
3013579
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!