quickhull/NumberGenerator.h

146 lines
4.0 KiB
C++

#include <list>
#include <cstdlib> // for srand, rand
#include <fstream> // ifstream
#include <ctime> // time
#include <algorithm>
class NumberGenerator
{
public:
static std::list<Point> generate_numbers(const int count, const int mode = 1)
{
if (mode == 1)
{
return get_random_numbers(count);
}
else if (mode == 2)
{
return NumberGenerator::get_rectangle_numbers(count);
}
else if (mode == 3)
{
return NumberGenerator::get_circle_numbers(count);
}
else if (mode == 4)
{
return NumberGenerator::get_diagonal_numbers(count);
}
else throw "unspecified rng Mode"; // TODO: could handle in parse args
}
static std::list<Point> read_numbers(const std::string &fileRnd)
{
std::list<Point> points;
std::ifstream in(fileRnd.c_str());
if (in.is_open())
{
std::string line;
std::getline(in, line); // get first line for explizit valueCount
int valCount = std::stoi(line);
float x = 0;
float y = 0;
for (int i = 0; i < valCount; ++i)
{
getline(in, line);
//getline(in, line, ','); // could also be used slightly different but includes newlines :/
size_t pos = line.find(',');
if (pos != std::string::npos)
{
x = std::stof(line.substr(0, pos));
y = std::stof(line.substr(pos + 1));
points.push_back(Point(x, y));
}
else
{
throw "invalid format!";
}
}
}
return points;
}
static std::list<Point> get_random_numbers (const int valCount)
{
std::list<Point> points;
#ifdef _DEBUG
srand(static_cast <unsigned> (0)); // fixed seed for testing
#else
srand(static_cast <unsigned> (time(0)));
#endif
float x = 0;
float y = 0;
for (int i = 0; i < valCount; ++i)
{
x = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (WIDTH - 2*OFFSET)));
y = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (HEIGHT - 2*OFFSET)));
points.push_back(Point(x, y));
}
return points;
}
static std::list<Point> get_rectangle_numbers (const int valCount)
{
std::list<Point> points;
float diff = (2.f * HEIGHT/valCount);
float x = 0;
float y = 0;
for (int i = 0; i < valCount; ++i)
{
x = (i%2 == 0) ? OFFSET : WIDTH - OFFSET;
y = diff/2 + (i/2) * diff;
/*if (i % 4 == 0)
{
x = OFFSET;
}
else
{
x = (i % 4) * WIDTH / 4;
}
y = diff / 4 + (i / 4) * diff;*/
points.push_back(Point(x, y));
}
return points;
}
static std::list<Point> get_circle_numbers (const int valCount)
{
std::list<Point> points;
float rad = HEIGHT/2;
float deg = (float)(2 * 3.14159 / valCount);
float x = 0;
float y = 0;
for (int i = 0; i < valCount; ++i)
{
x = WIDTH/2 + rad * cosf(i * deg);
y = HEIGHT/2 + rad * sinf(i * deg);
points.push_back(Point(x, y));
}
return points;
}
static std::list<Point> get_diagonal_numbers(const int valCount)
{
std::list<Point> points;
float x = 0;
float y = 0;
for (int i = 0; i < valCount; ++i)
{
x = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (std::min(WIDTH, HEIGHT) - 2 * OFFSET)));
points.push_back(Point(x, HEIGHT - x)); // ascending
//points.push_back(Point(x, HEIGHT - x)); // descending
}
return points;
}
};