#pragma once #include #include #include #include namespace SwanCommon { template struct Vector2 { T x; T y; MSGPACK_DEFINE(x, y) constexpr Vector2(T x = 0, T y = 0): x(x), y(y) {} constexpr Vector2(std::pair p): x(p.first), y(p.second) {} constexpr Vector2 &set(T x, T y) { this->x = x; this->y = y; return *this; } constexpr T length() const { return (T)std::sqrt((double)squareLength()); } constexpr T squareLength() const { return this->x * this->x + this->y * this->y; } constexpr Vector2 sign() const { return Vector2(x > 0 ? 1 : -1, y > 0 ? 1 : -1); } constexpr Vector2 scale(T sx, T sy) const { return Vector2(x * sx, y * sy); } constexpr Vector2 scale(T s) const { return scale(s, s); } constexpr Vector2 norm() const { return *this / length(); } constexpr T dot(const Vector2 &vec) const { return x * vec.x + y * vec.y; } constexpr operator std::pair() const { return std::pair(x, y); } constexpr operator Vector2() const { return Vector2(x, y); } constexpr bool operator==(const Vector2 &vec) const { return x == vec.x && y == vec.y; } constexpr bool operator!=(const Vector2 &vec) const { return !(*this == vec); } constexpr Vector2 operator-() const { return Vector2(-x, -y); } constexpr Vector2 operator+(const Vector2 &vec) const { return Vector2(x + vec.x, y + vec.y); } constexpr Vector2 &operator+=(const Vector2 &vec) { x += vec.x; y += vec.y; return *this; } constexpr Vector2 operator-(const Vector2 &vec) const { return Vector2(x - vec.x, y - vec.y); } constexpr Vector2 &operator-=(const Vector2 &vec) { x -= vec.x; y -= vec.y; return *this; } constexpr Vector2 operator*(const Vector2 &vec) const { return Vector2(x * vec.x, y * vec.y); } constexpr Vector2 &operator*=(const Vector2 &vec) { x *= vec.x; y *= vec.y; return *this; } constexpr Vector2 operator*(T num) const { return Vector2(x * num, y * num); } constexpr Vector2 operator*=(T num) { x *= num; y *= num; return *this; } constexpr Vector2 operator/(const Vector2 &vec) const { return Vector2(x / vec.x, y / vec.y); } constexpr Vector2 &operator/=(const Vector2 &vec) { x /= vec.x; y /= vec.y; return *this; } constexpr Vector2 operator/(T num) const { return Vector2(x / num, y / num); } constexpr Vector2 operator/=(T num) { x /= num; y /= num; return *this; } static const Vector2 ZERO; template friend std::ostream &operator<<(std::ostream &os, const Vector2 &vec); }; template const Vector2 Vector2::ZERO = Vector2(0, 0); template std::ostream &operator<<(std::ostream &os, const Vector2 &vec) { os << '(' << vec.x << ", " << vec.y << ')'; return os; } using Vec2 = Vector2; using Vec2i = Vector2; }