vector.h

#pragma once
#include <iostream>
#include <assert.h>

namespace math {
template<typename T>
class Vector3;

template<typename T>
class Vector4;

template<typename T>
class Vector2 {
public:
Vector2() { x = y = 0; }
Vector2(T x, T y) :x(x), y(y) {}
Vector2(const Vector2<T>& v) :x(v.x), y(v.y) {}
Vector2(const Vector3<T>& v) :x(v.x), y(v.y) {}
Vector2(const Vector4<T>& v) :x(v.x), y(v.y) {}

/*
* 取得向量某个元素
* int a = v[1]
*/
T operator[](int i) const {
assert(i >= 0 && i < 2);

if (i == 0) return x;

return y;
}

/*
* 给向量某个元素赋值
* v[1]=6
*/
T& operator[](int i) {
assert(i >= 0 && i < 2);

if (i == 0) return x;

return y;
}

//等号运算符重载
Vector2<T> operator=(const Vector3<T>& v) {
x = v.x; y = v.y;
return *this;
}

Vector2<T> operator=(const Vector4<T>& v) {
x = v.x; y = v.y;
return *this;
}

/*
* 加法
* v = v1+v2
*/
Vector2<T> operator+(const Vector2<T>& v) const {
return Vector2(x + v.x, y + v.y);
}

/*
* 加法并赋值
* v += v2
*/
Vector2<T> operator+=(const Vector2<T>& v) {
x += v.x; y += v.y;
return *this;
}

/*
* 乘法
* v = v1 * s
*/
Vector2<T> operator*(T s) const {
return Vector2(x * s, y * s);
}

/*
* 乘法并赋值
* v *= s
*/
Vector2<T> operator*=(T s) {
x *= s; y *= s;
return *this;
}

/*
* 除法
* v = v1 / f
*/
Vector2<T> operator/(T f) const {
assert(f != 0);
float inv = static_cast<T>(1) / f;
return Vector2(x * inv, y * inv);
}

/*
* 除法并赋值
* v /= f
*/
Vector2<T> operator/=(T f) {
assert(f != 0);
float inv = static_cast<T>(1) / f;
x *= inv; y *= inv;
return *this;
}

/*
* 负号操作
* v = -v1
*/
Vector2<T> operator-() {
return Vector2(-x, -y);
}

void print() {
std::cout << "Vector2 is:" << std::endl;
std::cout << "x = " << x << ", y = " << y << std::endl;
std::cout << std::endl;
}

public:
T x, y;
};


template<typename T>
class Vector3 {
public:
Vector3() { x = y = z = 0; }
Vector3(T x, T y, T z) :x(x), y(y), z(z) {}
Vector3(const Vector3<T>&v):x(v.x), y(v.y), z(v.z) {}
Vector3(const Vector4<T>&v):x(v.x), y(v.y), z(v.z) {}

T operator[](int i) const {
assert(i >= 0 && i <= 2);

if (i == 0) return x;
if (i == 1) return y;

return z;
}

T& operator[](int i) {
assert(i >= 0 && i <= 2);

if (i == 0) return x;
if (i == 1) return y;

return z;
}

Vector3<T> operator=(const Vector2<T>& v) {
x = v.x; y = v.y;
return *this;
}

Vector3<T> operator=(const Vector4<T>& v) {
x = v.x; y = v.y; z = v.z;
return *this;
}

Vector3<T> operator+(const Vector3<T>& v) const {
return Vector3<T>(x + v.x, y + v.y, z + v.z);
}

Vector3<T> operator+=(const Vector3<T>& v) {
x += v.x; y += v.y; z += v.z;
return *this;
}

Vector3<T> operator-(const Vector3<T>& v) const {
return Vector3(x - v.x, y - v.y, z - v.z);
}

Vector3<T> operator-=(const Vector3<T>& v) {
x -= v.x; y -= v.y; z -= v.z;
return *this;
}

Vector3<T> operator*(T s) const {
return Vector3(x * s, y * s, z * s);
}

Vector3<T> operator*=(T s) {
x *= s; y *= s; z *= s;
return *this;
}

Vector3<T> operator/(T f) const {
assert(f != 0);
float inv = 1.0 / f;
return Vector3(x * inv, y * inv, z * inv);
}

Vector3<T> operator/=(T f) {
assert(f != 0);
float inv = 1.0 / f;
x *= inv; y *= inv; z *= inv;
return *this;
}

Vector3<T> operator-() const {
return Vector3<T>(-x, -y, -z);
}

void print() {
std::cout << "Vector3 is:" << std::endl;
std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl;
std::cout << std::endl;
}

public:
T x, y, z;
};

template<typename T>
class Vector4 {
public:
Vector4() { x = y = z = w = 0; }
Vector4(T x, T y, T z, T w) :x(x), y(y), z(z), w(w) {}
Vector4(const Vector4<T>&v):x(v.x), y(v.y), z(v.z), w(v.w) {}

T operator[](int i) const {
assert(i >= 0 && i <= 3);

if (i == 0) return x;
if (i == 1) return y;
if (i == 2) return z;

return w;
}

T& operator[](int i) {
assert(i >= 0 && i <= 3);

if (i == 0) return x;
if (i == 1) return y;
if (i == 2) return z;

return w;
}

Vector4<T> operator=(const Vector2<T>& v) {
x = v.x; y = v.y;;
return *this;
}

Vector4<T> operator=(const Vector3<T>& v) {
x = v.x; y = v.y; z = v.z;
return *this;
}

Vector4<T> operator+(const Vector4<T>& v) const {
return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
}

Vector4<T> operator+=(const Vector4<T>& v) {
x += v.x; y += v.y; z += v.z; w += v.w;
return *this;
}

Vector4<T> operator-(const Vector4<T>& v) const {
return Vector4<T>(x - v.x, y - v.y, z - v.z, w - v.w);
}

Vector4<T> operator-=(const Vector4<T>& v) {
x -= v.x; y -= v.y; z -= v.z; w -= v.w;
return *this;
}

Vector4<T> operator*(T s) const {
return Vector4(x * s, y * s, z * s, w * s);
}

Vector4<T> operator*=(T s) {
x *= s; y *= s; z *= s; w *= s;
return *this;
}

Vector4<T> operator*=(const Vector3<T>& v) {
x *= v.x; y *= v.y; z *= v.z;
return *this;
}

Vector4<T> operator/(T f) const {
assert(f != 0);
float inv = 1.0 / f;
return Vector4(x * inv, y * inv, z * inv, w * inv);
}

Vector4<T> operator/=(T f) {
assert(f != 0);
float inv = 1.0 / f;
x *= inv; y *= inv; z *= inv; w *= inv;
return *this;
}

Vector4<T> operator-() const {
return Vector3(-x, -y, -z, -w);
}

void print() {
std::cout << "Vector4 is:" << std::endl;
std::cout << "x = " << x << ", y = " << y << ", z = " << z << ", w = " << w << std::endl;
std::cout << std::endl;
}

public:
T x, y, z, w;
};

using vec2f = Vector2<float>;
using vec2i = Vector2<int>;
using vec3f = Vector3<float>;
using vec3i = Vector3<int>;
using vec4f = Vector4<float>;
using vec4i = Vector4<int>;
}

matrix.h

#pragma once
#include <iostream>
#include <assert.h>
#include "vector.h"

namespace math {
template<typename T>
class Matrix44;

/*
* m0 m3 m6
* m1 m4 m7
* m2 m5 m8
*/
template<typename T>
class Matrix33 {
public:
Matrix33() {}
Matrix33(T v) {
m[0] = m[4] = m[8] = v;
}

Matrix33(const Matrix33<T>& src) {
memcpy((void*)m, (void*)src.m, sizeof(T) * 9);
}

Matrix33(const Matrix44<T>& src) {
m[0] = src.m[0]; m[3] = src.m[4]; m[6] = src.m[8];
m[1] = src.m[1]; m[4] = src.m[5]; m[7] = src.m[9];
m[2] = src.m[2]; m[5] = src.m[6]; m[8] = src.m[10];
}

Matrix33<T> operator*(const T& s) {
Matrix33<T> result;

auto col0 = this->getColum(0) * s;
auto col1 = this->getColum(1) * s;
auto col2 = this->getColum(2) * s;

result.setColum(col0, 0);
result.setColum(col1, 1);
result.setColum(col2, 2);

return result;
}

Vector3<T> operator*(const Vector3<T>& v) {
return Vector3(
v.x * m0 + v.y * m3 + v.z * m6,
v.x * m1 + v.y * m4 + v.z * m7,
v.x * m2 + v.y * m5 + v.z * m8,
);
}

void set(const uint32_t& row, const uint32_t& col, T t) {
assert(row < 3 && col < 3);
m[col * 3 + row] = t;
}

void set(
T m00, T m01, T m02,
T m10, T m11, T m12,
T m20, T m21, T m22
) {
m[0] = m00; m[3] = m01; m[6] = m02;
m[1] = m10; m[4] = m11; m[7] = m12;
m[2] = m20; m[5] = m21; m[8] = m22;
}

Matrix33<T> identity() {
set(
1, 0, 0,
0, 1, 0,
0, 0, 1
);

return *this;
}

Vector3<T> getColum(const uint32_t& col) const {
assert(col < 3);
return Vector3<T>(m[col * 3], m[col * 3 + 1], m[col * 3 + 2]);
}

void setColum(const Vector3<T>& cvalue, const uint32_t& col) {
assert(col < 3);
m[col * 3] = cvalue.x; m[col * 3 + 1] = cvalue.y; m[col * 3 + 2] = cvalue.z;
}

void printMatrix() {
std::cout << "Matrix33 is:" << std::endl;
std::cout << m[0] << "," << m[3] << "," << m[6] << std::endl;
std::cout << m[1] << "," << m[4] << "," << m[7] << std::endl;
std::cout << m[2] << "," << m[5] << "," << m[8] << std::endl;
std::cout << std::endl;
}

public:
T m[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
};

/*
* m0 m4 m8 m12
* m1 m5 m9 m13
* m2 m6 m10 m14
* m3 m7 m11 m15
*/
template<typename T>
class Matrix44 {
public:
Matrix44() {}
Matrix44(T v) {
m[0] = m[5] = m[10] = m[15] = v;
}

Matrix44(const Matrix44<T>& src) {
memcpy((void*)m, (void*)src.m, sizeof(T) * 16);
}

Matrix44<T> operator*(const T& s) {
Matrix44<T> result;

auto col0 = this->getColum(0) * s;
auto col1 = this->getColum(1) * s;
auto col2 = this->getColum(2) * s;
auto col3 = this->getColum(3) * s;

result.setColum(col0, 0);
result.setColum(col1, 1);
result.setColum(col2, 2);
result.setColum(col3, 3);

return result;
}

Vector4<T> operator*(const Vector4<T>& v) {
return Vector4(
v.x * m[0] + v.y * m[4] + v.z * m[8] + v.w * m[12],
v.x * m[1] + v.y * m[5] + v.z * m[9] + v.w * m[13],
v.x * m[2] + v.y * m[6] + v.z * m[10] + v.w * m[14],
v.x * m[3] + v.y * m[7] + v.z * m[11] + v.w * m[15]
);
}

T get(const uint32_t& row, const uint32_t& col) const {
assert(row < 4 && col < 4);
return m[col * 4 + row];
}

void set(const uint32_t& row, const uint32_t& col, T t) {
assert(row < 4 && col < 4);
m[col * 4 + row] = t;
}

void set(
T m00, T m01, T m02, T m03,
T m10, T m11, T m12, T m13,
T m20, T m21, T m22, T m23,
T m30, T m31, T m32, T m33
) {
m[0] = m00; m[4] = m01; m[8] = m02; m[12] = m03;
m[1] = m10; m[5] = m11; m[9] = m12; m[13] = m13;
m[2] = m20; m[6] = m21; m[10] = m22; m[14] = m23;
m[3] = m30; m[7] = m31; m[11] = m32; m[15] = m33;
}

Matrix44<T> identity() {
set(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);

return *this;
}

Vector4<T> getColum(const uint32_t& col) const {
assert(col < 4);
return Vector4<T>(
m[col * 4],
m[col * 4 + 1],
m[col * 4 + 2],
m[col * 4 + 3]);
}

void setColum(const Vector4<T>& cvalue, const uint32_t& col) {
assert(col < 4);
m[col * 4] = cvalue.x;
m[col * 4 + 1] = cvalue.y;
m[col * 4 + 2] = cvalue.z;
m[col * 4 + 3] = cvalue.w;
}

void printMatrix() {
std::cout << "Matrix44 is:" << std::endl;
std::cout << m[0] << "," << m[4] << "," << m[8] << "," << m[12] << std::endl;
std::cout << m[1] << "," << m[5] << "," << m[9] << "," << m[13] << std::endl;
std::cout << m[2] << "," << m[6] << "," << m[10] << "," << m[14] << std::endl;
std::cout << m[3] << "," << m[7] << "," << m[11] << "," << m[15] << std::endl;
std::cout << std::endl;
}

public:
T m[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
};

using Mat3f = Matrix33<float>;
using Mat4f = Matrix44<float>;
}