Skip to content

Instantly share code, notes, and snippets.

@tomilov
Last active July 2, 2022 07:11
Show Gist options
  • Save tomilov/28d64a64e215cd756ab0ce87624f7e6c to your computer and use it in GitHub Desktop.
Save tomilov/28d64a64e215cd756ab0ce87624f7e6c to your computer and use it in GitHub Desktop.
make AA box consisting of inherently sorted triangles from two points
#include <iterator>
#include <algorithm>
#include <tuple>
#include <vector>
#include <iostream>
#include <numeric>
#include <functional>
#include <random>
#include <cassert>
#include <cstdlib>
namespace
{
using F = float;
struct Vertex
{
F x, y, z;
bool operator<(const Vertex & rhs) const
{
return std::tie(x, y, z) < std::tie(rhs.x, rhs.y, rhs.z);
}
};
struct Triangle
{
Vertex a, b, c;
bool operator<(const Triangle & rhs) const
{
return std::tie(a, b, c) < std::tie(rhs.a, rhs.b, rhs.c);
}
};
template<typename TriangleOutputIterator>
TriangleOutputIterator putBox(TriangleOutputIterator out, const Vertex & a, const Vertex & b)
{
assert(a.x < b.x);
assert(a.y < b.y);
assert(a.z < b.z);
Vertex v[] = {a, a, a, b, b, b};
v[0].z = b.z;
v[1].y = b.y;
v[2].x = b.x;
v[3].x = a.x;
v[4].y = a.y;
v[5].z = a.z;
*out++ = {a, v[0], v[3]};
*out++ = {a, v[0], v[4]};
*out++ = {a, v[1], v[3]};
*out++ = {a, v[1], v[5]};
*out++ = {a, v[2], v[4]};
*out++ = {a, v[2], v[5]};
*out++ = {v[0], v[3], b};
*out++ = {v[0], v[4], b};
*out++ = {v[1], v[3], b};
*out++ = {v[1], v[5], b};
*out++ = {v[2], v[4], b};
*out++ = {v[2], v[5], b};
return out;
}
constexpr int kIntBboxSize = 10;
constexpr int kFloatDigits = std::numeric_limits<F>::digits;
using RandomValueType = typename std::mt19937::result_type;
using UniformIntDistribution = std::uniform_int_distribution<>;
using UniformIntParam = typename UniformIntDistribution::param_type;
std::mt19937 gen;
UniformIntDistribution uniformInt;
F genFloat()
{
return std::generate_canonical<F, kFloatDigits>(gen);
}
void genComponent(F & f, int min = -kIntBboxSize, int max = +kIntBboxSize)
{
assert(!(max < min));
f = F(uniformInt(gen, UniformIntParam(min, max)));
if ((false)) {
const int pow = uniformInt(gen, UniformIntParam(1, kFloatDigits));
auto fuzz = genFloat();
fuzz += fuzz;
fuzz -= F(1); // lost 1 bit of mantissa's randomness
f += std::scalbn(fuzz, -pow);
if (f < F(min)) {
f += F(max - min);
} else if (F(max) < f) {
f += F(min - max);
}
}
}
} // namespace
int main()
{
for (int i = 0; i < 100000; ++i) {
std::vector<Triangle> box;
Vertex u;
genComponent(u.x, -kIntBboxSize, kIntBboxSize - 1);
genComponent(u.y, -kIntBboxSize, kIntBboxSize - 1);
genComponent(u.z, -kIntBboxSize, kIntBboxSize - 1);
Vertex v;
genComponent(v.x, u.x + 1, kIntBboxSize);
genComponent(v.y, u.y + 1, kIntBboxSize);
genComponent(v.z, u.z + 1, kIntBboxSize);
putBox(std::back_inserter(box), u, v);
for (const auto & [a, b, c] : box) {
assert(!(b < a) && !(c < b));
}
{
auto vertices = {&box[0].a, &box[0].b, &box[2].b, &box[2].c, &box[4].b, &box[4].c, &box[5].c, &box[6].c};
[[maybe_unused]] const auto vertexLess = [](auto l, auto r) { return *l < *r; };
assert(std::is_sorted(std::cbegin(vertices), std::cend(vertices)));
assert(std::adjacent_find(std::cbegin(vertices), std::cend(vertices), std::not_fn(vertexLess)) == std::cend(vertices));
}
if (!std::is_sorted(std::cbegin(box), std::cend(box)) || (std::adjacent_find(std::cbegin(box), std::cend(box), std::not_fn(std::less<Triangle>{})) != std::cend(box))) {
for (const auto & [a, b, c] : box) {
std::cout << a.x << ' ' << a.y << ' ' << a.z << std::endl;
std::cout << b.x << ' ' << b.y << ' ' << b.z << std::endl;
std::cout << c.x << ' ' << c.y << ' ' << c.z << std::endl;
std::cout << std::endl;
}
std::vector<std::size_t> order(box.size());
std::iota(std::begin(order), std::end(order), 0);
const auto less = [&](std::size_t l, std::size_t r) -> bool
{
return box[l] < box[r];
};
std::sort(std::begin(order), std::end(order), less);
std::copy(std::cbegin(order), std::cend(order), std::ostream_iterator<std::size_t>(std::cout, ", "));
std::cout << std::endl;
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment