#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
bool generateDiamondMethod1 (const int &height)
{
static const int width = 1024;
//an initial seed value for the corners of the data
float SEED = 0.0f;
static const unsigned int DATA_SIZE=width+1;
std::vector< std::vector<float> > diamond( DATA_SIZE, std::vector<float>(DATA_SIZE) );
//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 =200; //the range (-h -> h) for the average offset
srand(512); //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)%DATA_SIZE][y] + //top right
diamond[x][ (y+sideLength)%DATA_SIZE] + //lower left
diamond[(x+sideLength)%DATA_SIZE][(y+sideLength)%DATA_SIZE]; //lower right
avg /= 4.0;
//center is average plus random offset in the range (-h, h)
float offset = (-h) + (float)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) + (float)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
cout << "\r\nData Size " << DATA_SIZE;
cout << "\r\nImage Size " << width << "x" << width;
cout << "\r\nLocation1 "<< diamond[305][742];
cout << "\r\nLocation2 " <<diamond[288][732];
/// Set maxY and minY to 0.0f
float maxY = diamond[1][1];
float minY = diamond[1][1];
cout << "\r\nMinimumY " << minY;
cout << "\r\nMaximumY " << maxY;
cout << "(Loop to find highest and new minimum)";
for (int x = 0; x<DATA_SIZE; x++)
{
for(int y = 0; y<DATA_SIZE; y++)
{
if ((float)diamond[x][y] > maxY)
{
maxY = diamond[x][y];
}
if ((float)diamond[x][y] < minY)
{
minY = diamond[x][y];
}
}
}
cout << "\r\nMinimumY " << minY;
cout << "\r\nMaximumY " << maxY << "\r\n";
/// Calculate height from 0 to 1
for(int x=0; x < DATA_SIZE; x++)
{
for(int y=0; y < DATA_SIZE; y++)
{
//change range to 0..1
diamond[x][y] = (diamond[x][y] - minY) / (maxY - minY);
}
}
/// Copy color float from create texture
for(unsigned y = 0; y<width; y++)
{
for(unsigned x = 0; x<height; x++)
{
/// incremennt memory which seems to work
int index = (y*width)+x;
//buffer[index]=diamond[x][y];
}
}
return true;
}
int main()
{
generateDiamondMethod1(1024);
}