116 lines
2.8 KiB
C++
116 lines
2.8 KiB
C++
#include "generator.h"
|
|
#include "aliases.h"
|
|
#include "point_types.h"
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
|
|
#define X_MIN -180.0
|
|
#define X_MAX 180.0
|
|
#define Y_MIN -90.0
|
|
#define Y_MAX 90.0
|
|
|
|
f64 generate_random_double(f64 min, f64 max);
|
|
Point generate_random_point(f64 x_min, f64 x_max, f64 y_min, f64 y_max);
|
|
PointPair generate_random_pair(f64 x_min, f64 x_max, f64 y_min, f64 y_max);
|
|
|
|
void fill_pairs_array(PairArray *pairs, bool clustered) {
|
|
if (clustered) {
|
|
u64 digit_count = (u64)log10(pairs->count) + 1;
|
|
|
|
u64 cluster_count = 0;
|
|
|
|
if (digit_count > 2) {
|
|
cluster_count = digit_count * 8;
|
|
} else {
|
|
cluster_count = digit_count;
|
|
}
|
|
|
|
Point clusters[cluster_count];
|
|
f64 radii[cluster_count];
|
|
|
|
u64 pairs_per_cluster = pairs->count / cluster_count;
|
|
u64 generated_pairs = 0;
|
|
u64 pairs_to_generate = 0;
|
|
|
|
for (u64 i = 0; i < cluster_count; ++i) {
|
|
clusters[i] = {
|
|
generate_random_double(X_MIN, X_MAX),
|
|
generate_random_double(Y_MIN, Y_MAX),
|
|
};
|
|
|
|
radii[i] = generate_random_double(0.0, (digit_count - 1) * 40.0);
|
|
|
|
f64 cluster_x_min = clusters[i].x - radii[i];
|
|
if (cluster_x_min < X_MIN) {
|
|
cluster_x_min = X_MIN;
|
|
}
|
|
|
|
f64 cluster_x_max = clusters[i].x + radii[i];
|
|
if (cluster_x_max > X_MAX) {
|
|
cluster_x_max = X_MAX;
|
|
}
|
|
|
|
f64 cluster_y_min = clusters[i].y - radii[i];
|
|
if (cluster_y_min < Y_MIN) {
|
|
cluster_y_min = Y_MIN;
|
|
}
|
|
|
|
f64 cluster_y_max = clusters[i].y + radii[i];
|
|
if (cluster_y_max > Y_MAX) {
|
|
cluster_y_max = Y_MAX;
|
|
}
|
|
|
|
pairs_to_generate = 0;
|
|
|
|
if (generated_pairs + pairs_per_cluster < pairs->count) {
|
|
pairs_to_generate = pairs_per_cluster;
|
|
} else {
|
|
pairs_to_generate = pairs->count - generated_pairs;
|
|
}
|
|
|
|
for (u64 i = 0; i < pairs_to_generate; ++i) {
|
|
// clang-format off
|
|
pairs->pairs[generated_pairs + i] = generate_random_pair(
|
|
cluster_x_min,
|
|
cluster_x_max,
|
|
cluster_y_min,
|
|
cluster_y_max
|
|
);
|
|
// clang-format on
|
|
}
|
|
|
|
generated_pairs += pairs_to_generate;
|
|
}
|
|
} else {
|
|
for (u64 i = 0; i < pairs->count; ++i) {
|
|
pairs->pairs[i] = generate_random_pair(X_MIN, X_MAX, Y_MIN, Y_MAX);
|
|
}
|
|
}
|
|
}
|
|
|
|
f64 generate_random_double(f64 min, f64 max) {
|
|
u32 num = rand();
|
|
|
|
f64 result = min + (((f64)num / (f64)RAND_MAX) * (max - min));
|
|
|
|
return result;
|
|
}
|
|
|
|
Point generate_random_point(f64 x_min, f64 x_max, f64 y_min, f64 y_max) {
|
|
Point p = {
|
|
generate_random_double(x_min, x_max),
|
|
generate_random_double(y_min, y_max),
|
|
};
|
|
|
|
return p;
|
|
}
|
|
|
|
PointPair generate_random_pair(f64 x_min, f64 x_max, f64 y_min, f64 y_max) {
|
|
PointPair pair = {
|
|
generate_random_point(x_min, x_max, y_min, y_max),
|
|
generate_random_point(x_min, x_max, y_min, y_max),
|
|
};
|
|
|
|
return pair;
|
|
}
|