#pragma once #include "real.hpp" #include #include #include #include template class VecBase { public: std::array data; VecBase() { data.fill(0); } VecBase(std::initializer_list values) { std::copy(values.begin(), values.end(), data.begin()); } template explicit VecBase(Args... args) : data{static_cast(args)...} { static_assert(sizeof...(args) == N, "Argument count must match vector size."); } explicit VecBase(const VecBase &v) { data = v.data; } VecBase &operator=(VecBase v) { *this = std::move(v); return *this; } real &operator[](size_t index) { if (index >= N) throw std::out_of_range("Index out of range"); return data[index]; } const real &operator[](size_t index) const { if (index >= N) throw std::out_of_range("Index out of range"); return data[index]; } Derived operator+(const VecBase &v) const { Derived result; for (size_t i = 0; i < N; ++i) { result[i] = data[i] + v[i]; } return result; } Derived operator-(const VecBase &v) const { Derived result; for (size_t i = 0; i < N; ++i) { result[i] = data[i] - v[i]; } return result; } Derived operator*(real s) const { Derived result; for (size_t i = 0; i < N; ++i) { result[i] = data[i] * s; } return result; } friend Derived operator*(real s, const VecBase &v) { Derived result; for (size_t i = 0; i < N; ++i) { result[i] = s * v[i]; } return result; } Derived operator/(real s) const { Derived result; for (size_t i = 0; i < N; ++i) { result[i] = data[i] / s; } return result; } real dot(const VecBase &v) const { real sum = 0; for (size_t i = 0; i < N; ++i) { sum += data[i] * v[i]; } return sum; } real norm() const { return std::sqrt(dot(*this)); } Derived normalize() const { return static_cast(*this / norm()); } Derived reflect(const Derived &n) const { return static_cast(*this - n * 2 * dot(n)); } }; // Vec<2> 特化 class Vec2 : public VecBase { public: Vec2() : VecBase() {} Vec2(real x, real y) : VecBase(x, y) {} Vec2(const Vec2& v) : VecBase(v.x(), v.y()) {} Vec2 &operator=(const Vec2& v) { data = v.data; return *this; } real& x() { return data[0]; } real& y() { return data[1]; } const real& x() const { return data[0]; } const real& y() const { return data[1]; } real& u() { return data[0]; } real& v() { return data[1]; } const real& u() const { return data[0]; } const real& v() const { return data[1]; } }; class Vec3 : public VecBase { public: Vec3() : VecBase() {} Vec3(real x, real y, real z) : VecBase(x, y, z) {} Vec3(const Vec3& v) : VecBase(v.x(), v.y(), v.z()) {} Vec3 &operator=(const Vec3& v) { data = v.data; return *this; } real& x() { return data[0]; } real& y() { return data[1]; } real& z() { return data[2]; } real x() const { return data[0]; } real y() const { return data[1]; } real z() const { return data[2]; } real& u() { return data[0]; } real& v() { return data[1]; } real& w() { return data[2]; } real u() const { return data[0]; } real v() const { return data[1]; } real w() const { return data[2]; } Vec3 cross(const Vec3& v) const { return {y() * v.z() - z() * v.y(), z() * v.x() - x() * v.z(), x() * v.y() - y() * v.x()}; } }; using Pt3Array = std::vector; using Pt2Array = std::vector; //class Vec3 { //public: // real x, y, z; // Vec3(): x(0), y(0), z(0) {} // Vec3(real x, real y, real z): x(x), y(y), z(z) {} // Vec3(const Vec3& v): x(v.x), y(v.y), z(v.z) {} // Vec3& operator=(const Vec3& v) { // x = v.x; // y = v.y; // z = v.z; // return *this; // } // Vec3 operator+(const Vec3& v) const { // return Vec3(x + v.x, y + v.y, z + v.z); // } // Vec3 operator-(const Vec3& v) const { // return Vec3(x - v.x, y - v.y, z - v.z); // } // Vec3 operator*(real s) const { // return Vec3(x * s, y * s, z * s); // } // Vec3 operator*(const Vec3& v) const { // return Vec3(x * v.x, y * v.y, z * v.z); // } // Vec3 operator-() const { // return Vec3(-x, -y, -z); // } // friend Vec3 operator*(real s, const Vec3& v) { // return Vec3(s * v.x, s * v.y, s * v.z); // } // Vec3 operator/(real s) const { // return Vec3(x / s, y / s, z / s); // } // real dot(const Vec3& v) const { // return x * v.x + y * v.y + z * v.z; // } // Vec3 cross(const Vec3& v) const { // return Vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); // } // real norm() const { // return sqrt(x * x + y * y + z * z); // } // Vec3 normalize() const { // return *this / norm(); // } // Vec3 reflect(const Vec3& n) const { // return *this - n * 2 * dot(n); // } //};