0%

01 - 三维向量类

1. 成员变量

Vector3 类实现时,函数的声明和定义均在头文件 Vector3.h 中进行

1
float x, y, z;

2. 构造函数

1
2
3
4
5
6
7
8
// 默认构造函数,不执行任何操作
Vector3() : x(0), y(0), z(0) {}

// 复制构造函数
Vector3(const Vector3& a) : x(a.x), y(a.y), z(a.z) {}

// 带参数的构造函数,用三个值完成初始化
Vector3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}

3. 重载操作符

3.1 赋值

1
2
3
4
Vector3& operator =(const Vector3& a) {
x = a.x; y = a.y; z = a.z;
return *this;
}

3.2 判断 “==”

1
2
3
4
5
6
7
bool operator ==(const Vector3& a) const {
return x == a.x && y == a.y && z == a.z;
}

bool operator !=(const Vector3& a) const {
return x != a.x || y != a.y || z != a.z;
}

3.3 向量运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 重载一元“-”运算符
Vector3 operator -() const { return Vector3(-x, -y, -z); }

// 重载二元“+”和“-”运算符
Vector3 operator +(const Vector3& a) const {
return Vector3(x + a.x, y + a.y, z + a.z);
}

Vector3 operator -(const Vector3& a) const {
return Vector3(x - a.x, y - a.y, z - a.z);
}

// 与标量的乘、除法
Vector3 operator *(float a) const {
return Vector3(x * a, y * a, z * a);
}

Vector3 operator /(float a) const {
float oneOverA = 1.0f / a;
// 注意,这里没有检查除零
return Vector3(x * oneOverA, y * oneOverA, z * oneOverA);
}

// 重载自反运算符
Vector3& operator +=(const Vector3& a) {
x += a.x; y += a.y; z += a.z;
return *this;
}

Vector3& operator -=(const Vector3& a) {
x -= a.x; y -= a.y; z -= a.z;
return *this;
}

Vector3& operator *=(float a) {
x *= a; y *= a; z *= a;
return *this;
}

Vector3& operator /=(float a) {
float oneOverA = 1.0f / a;
x *= oneOverA; y *= oneOverA; z *= oneOverA;
return *this;
}

// 向量点乘,重载标准的乘法运算符
float operator *(const Vector3& a) const {
return x * a.x + y * a.y + z * a.z;
}

4. 其他操作

1
2
3
4
5
6
7
8
9
10
11
12
13
// 置为零向量
void zero() { x = y = z = 0.0f; }

// 向量标准化
void normalize() {
float magSq = x * x + y * y + z * z;
if (magSq > 0.0f) { // 检查除零
float oneOverMag = 1.0f / sqrt(magSq);
x *= oneOverMag;
y *= oneOverMag;
z *= oneOverMag;
}
}

5. 全局变量

1
2
// 提供一个全局零向量
extern const Vector3 kZeroVector;

6. 非成员函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 求向量模
inline float vectorMag(const Vector3& a) {
return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
}

// 计算两向量的叉乘
inline Vector3 crossProduct(const Vector3& a, const Vector3& b) {
return Vector3(
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 Vector3 operator *(float k, const Vector3& v) {
return Vector3(k * v.x, k * v.y, k * v.z);
}

// 计算两点间的距离
inline float distance(const Vector3& a, const Vector3& b) {
float dx = a.x - b.x;
float dy = a.y - b.y;
float dz = a.z - b.z;
return sqrt(dx * dx + dy * dy + dz * dz);
}

// 计算两点之间的距离,平方。经常有用
// 比较距离时,因为平方根比较慢
inline float distanceSquared(const Vector3& a, const Vector3& b) {
float dx = a.x - b.x;
float dy = a.y - b.y;
float dz = a.z - b.z;
return dx * dx + dy * dy + dz * dz;
}