You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

231 lines
4.9 KiB

#pragma once
#include "real.hpp"
#include <cmath>
#include <array>
#include <assert.h>
template<size_t N>
class Vec {
public:
std::array<real, N> data;
Vec() {
data.fill(0);
}
Vec(std::initializer_list<real> values) {
std::copy(values.begin(), values.end(), data.begin());
}
Vec(real... args) : data{static_cast<real>(args)...} {}
Vec(const Vec<N> &v) {
data = v.data;
}
Vec<N> &operator=(const Vec<N> &v) {
data = v.data;
return *this;
}
real &operator[](size_t index) {
return data[index];
}
const real &operator[](size_t index) const {
return data[index];
}
Vec<N> operator+(const Vec<N> &v) const {
Vec<N> result;
for (size_t i = 0; i < N; ++i) {
result[i] = data[i] + v[i];
}
return result;
}
Vec<N> operator-(const Vec<N> &v) const {
Vec<N> result;
for (size_t i = 0; i < N; ++i) {
result[i] = data[i] - v[i];
}
return result;
}
Vec<N> operator*(real s) const {
Vec<N> result;
for (size_t i = 0; i < N; ++i) {
result[i] = data[i] * s;
}
return result;
}
friend Vec<N> operator*(real s, const Vec<N> &v) {
Vec<N> result;
for (size_t i = 0; i < N; ++i) {
result[i] = s * v[i];
}
return result;
}
Vec<N> operator/(real s) const {
Vec<N> result;
for (size_t i = 0; i < N; ++i) {
result[i] = data[i] / s;
}
return result;
}
real dot(const Vec<N> &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));
}
Vec<N> normalize() const {
return *this / norm();
}
Vec<N> reflect(const Vec<N> &n) const {
return *this - n * 2 * dot(n);
}
};
// specialize template class Vec<3>;
template<>
class Vec<3> {
public:
union {
std::array<real, 3> data;
struct {
real x, y, z;
};
struct {
real u, v, w;
};
};
Vec() : data{0, 0, 0} {}
Vec(real x, real y, real z) : data{x, y, z} {}
Vec(const Vec &v) : data{v.data[0], v.data[1], v.data[2]} {}
Vec &operator=(const Vec &v) {
data[0] = v.data[0];
data[1] = v.data[1];
data[2] = v.data[2];
return *this;
}
real operator[](size_t index) const {
return data[index];
}
real &operator[](size_t index) {
return data[index];
}
Vec operator+(const Vec &v) const {
return {x + v.x, y + v.y, z + v.z};
}
Vec operator-(const Vec &v) const {
return {x - v.x, y - v.y, z - v.z};
}
Vec operator*(real s) const {
return {x * s, y * s, z * s};
}
friend Vec operator*(real s, const Vec &v) {
return {s * v.x, s * v.y, s * v.z};
}
Vec operator/(real s) const {
assert(s != 0);
real inv = 1 / s;
return *this * inv;
}
real dot(const Vec &v) const {
return x * v.x + y * v.y + z * v.z;
}
real length() const {
return std::sqrt(dot(*this));
}
Vec normalize() const {
return *this / length();
}
Vec cross(const Vec &v) const {
return {y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x};
}
};
using Vec2 = Vec<2>;
using Vec3 = Vec<3>;
//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);
// }
//};