#pragma once #include #include namespace Nimbin { namespace Random { inline int int_MinMax(int min, int max) { std::mt19937 rng(std::random_device{}()); std::uniform_int_distribution dist(min, max); return dist(rng); } inline double unit() { static std::mt19937 rng(std::random_device{}()); static std::uniform_real_distribution dist(0.0, 1.0); return dist(rng); } } // Rendom namespace Math { struct Vec3 { double x{}, y{}, z{}; Vec3() = default; Vec3(double x_, double y_, double z_) : x(x_), y(y_), z(z_) {} Vec3& operator+=(const Vec3& other) { x += other.x; y += other.y; z += other.z; return *this; } Vec3& operator-=(const Vec3& other) { x -= other.x; y -= other.y; z -= other.z; return *this; } Vec3& operator*=(double s) { x *= s; y *= s; z *= s; return *this; } Vec3& operator/=(double s) { x /= s; y /= s; z /= s; return *this; } }; inline Vec3 operator+(Vec3 a, const Vec3& b) { return a += b; } inline Vec3 operator-(Vec3 a, const Vec3& b) { return a -= b; } inline Vec3 operator*(Vec3 v, double s) { return v *= s; } inline Vec3 operator/(Vec3 v, double s) { return v /= s; } inline double dot(const Vec3& a, const Vec3& b) { return a.x*b.x + a.y*b.y + a.z*b.z; } inline Vec3 cross(const Vec3& a, const Vec3& b) { return { a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x }; } inline double length_sq(const Vec3& v) { return dot(v, v); } inline double length(const Vec3& v) { return SDL_sqrt(length_sq(v)); } inline Vec3 normalize(const Vec3& v) { double len = length(v); return (len > 1e-9) ? v / len : Vec3{}; } inline double distance_sq(const Vec3& a, const Vec3& b) { return length_sq(b - a); } inline double distance(const Vec3& a, const Vec3& b) { return length(b - a); } inline double lerp(double a, double b, double t) { return a + (b - a) * t; } inline Vec3 lerp(const Vec3& a, const Vec3& b, double t) { return { lerp(a.x, b.x, t), lerp(a.y, b.y, t), lerp(a.z, b.z, t) }; } } // namespace } // namespace Nimbin