1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
bool Image::generateDiamondMethod1 (float * buffer,const int &width, const int &height, const float &maxYcoords,const float &minYcoords)
{
float maxY=2048;
float minY=0;
/// set range keeping scale
float NewMax = 1.0f;
float NewMin = 0.0f;
float NewRange = (NewMax - NewMin);
float lowfloat=1.0f;
float highfloat=1.0f;
//struct to hold values when writing to a file
struct sPoint
{
float x, y, z;
} point;
unsigned int DATA_SIZE=width+1;
//an initial seed value for the corners of the data
double SEED = 0.0f;
float diamond[DATA_SIZE][DATA_SIZE];
//initialise the values of the corners++
diamond[0][0] = SEED;
diamond[0][DATA_SIZE-1] = SEED;
diamond[DATA_SIZE-1][0] = SEED;
diamond[DATA_SIZE-1][DATA_SIZE-1] = SEED;
float h =300.0; //the range (-h -> h) for the average offset
srand(513); //seed the random generator
//side length is the distance of a single square side
//or distance of diagonal in diamond
//each iteration we are looking at smaller squares and diamonds, we decrease the variation of the offset
for (int sideLength = DATA_SIZE-1; sideLength >= 2; sideLength /= 2, h /= 2.0)
{
int halfSide = sideLength/2;
//generate new square values
for(int x=0; x<DATA_SIZE-1; x+=sideLength)
{
for(int y=0; y<DATA_SIZE-1; y+=sideLength)
{
//x,y is upper left corner of the square
//calculate average of existing corners
float avg = diamond[x][y] + //top left
diamond[x+sideLength][y] + //top right
diamond[x][y+sideLength] + //lower left
diamond[x+sideLength][y+sideLength]; //lower right
avg /= 4.0;
//center is average plus random offset in the range (-h, h)
float offset = (-h) + rand() * (h - (-h)) / RAND_MAX;
diamond[x+halfSide][y+halfSide] = avg + offset;
} //for y
} // for x
//Generate the diamond values
//Since diamonds are staggered, we only move x by half side
//NOTE: if the data shouldn't wrap the x < DATA_SIZE and y < DATA_SIZE
for (int x=0; x<DATA_SIZE-1; x+=halfSide)
{
for (int y=(x+halfSide)%sideLength; y<DATA_SIZE-1; y+=sideLength)
{
//x,y is center of diamond
//we must use mod and add DATA_SIZE for subtraction
//so that we can wrap around the array to find the corners
float avg =
diamond[(x-halfSide+DATA_SIZE)%DATA_SIZE][y] + //left of center
diamond[(x+halfSide)%DATA_SIZE][y] + //right of center
diamond[x][(y+halfSide)%DATA_SIZE] + //below center
diamond[x][(y-halfSide+DATA_SIZE)%DATA_SIZE]; //above center
avg /= 4.0;
//new value = average plus random offset
//calc random value in the range (-h,+h)
float offset = (-h) + rand() * (h - (-h)) / RAND_MAX;
avg = avg + offset;
//update value for center of diamond
diamond[x][y] = avg;
//wrap values on the edges
//remove this and adjust loop condition above
//for non-wrapping values
if (x == 0) diamond[DATA_SIZE-1][y] = avg;
if (y == 0) diamond[x][DATA_SIZE-1] = avg;
} //for y
} //for x
} //for sideLength
//Calculate minY and maxY values
for (int i = 0; i<DATA_SIZE-1; i++)
{
for(int j=0; j<DATA_SIZE-1; j++)
{
if (diamond[i][j] > maxY)
maxY = diamond[i][j];
if (diamond[i][j] < minY)
minY = diamond[i][j];
}
}
//print out the data
for(int x=0; x < DATA_SIZE-1; x++)
{
for(int y=0; y < DATA_SIZE-1; y++)
{
//populate the point struct
float floaty = diamond[x][y];
//change range to 0..1
diamond[x][y] = (floaty - minY) / (maxY - minY);
}
}
// loop through all the floats then convert to grayscale setting the color basis to .5 (forcing values 0 to 1)
for(unsigned x = 0; x<width; x++)
{
for(unsigned y = 0; y<height; y++)
{
/// incremennt memory which seems to work
int index = x+(y*width);
buffer[index]=diamond[x][y];
}
}
return true;
}
|