基础光线追踪(2) - 向量

完成 Vector.h 的编写。

Vector

由于后期可能会做单独优化,这里不使用模板编写 Vector,仅编写使用 float 的三维向量。
编写 Vector.h

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef _BASIC_RAY_TRACING_VECTOR_H_
#define _BASIC_RAY_TRACING_VECTOR_H_
#include <cmath>
#include <iostream>

struct Vector3f final {
union {
float a[3];

struct {
float x, y, z;
};

struct {
float r, g, b;
};
};

Vector3f() : a() {}
Vector3f(float x, float y, float z) : x(x), y(y), z(z) {}
Vector3f(float *a) {
this->a[0] = a[0];
this->a[1] = a[1];
this->a[2] = a[2];
}

const Vector3f &operator+() const { return *this; }
Vector3f operator-() const { return {-x, -y, -z}; }
float operator[](int i) const { return a[i]; }
float &operator[](int i) { return a[i]; }

Vector3f operator+(const Vector3f &other) const {
return {x + other.x, y + other.y, z + other.z};
}

Vector3f operator-(const Vector3f &other) const {
return {x - other.x, y - other.y, z - other.z};
}

Vector3f &operator+=(const Vector3f &other) {
x += other.x;
y += other.y;
z += other.z;
return *this;
}

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

float length() const { return sqrtf(x * x + y * y + z * z); }
float length2() const { return x * x + y * y + z * z; }

Vector3f &normalize() {
float inv = 1.0f / length();
x *= inv;
y *= inv;
z *= inv;
return *this;
}

Vector3f getNormalizedVector() const { return Vector3f(*this).normalize(); }

friend std::istream &operator>>(std::istream &is, Vector3f &vec) {
is >> vec.x >> vec.y >> vec.z;
return is;
}

Vector3f operator*(const Vector3f &other) const {
return {x * other.x, y * other.y, z * other.z};
}

Vector3f &operator*=(const Vector3f &other) {
x *= other.x;
y *= other.y;
z *= other.z;
return *this;
}

friend Vector3f operator*(float t, const Vector3f &vec) {
return {vec.x * t, vec.y * t, vec.z * t};
}

Vector3f operator*(float t) const { return {x * t, y * t, z * t}; }

Vector3f &operator*=(float t) {
x *= t;
y *= t;
z *= t;
return *this;
}

Vector3f operator/(const Vector3f &other) const {
return {x / other.x, y / other.y, z / other.z};
}

Vector3f &operator/=(const Vector3f &other) {
x /= other.x;
y /= other.y;
z /= other.z;
return *this;
}

Vector3f operator/(float t) const { return {x / t, y / t, z / t}; }

Vector3f &operator/=(float t) {
x /= t;
y /= t;
z /= t;
return *this;
}
};

float dot(const Vector3f &a, const Vector3f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }

Vector3f cross(const Vector3f &a, const Vector3f &b) {
return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
}

using Color3f = Vector3f;
using Point3f = Vector3f;
#endif

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×