pbpt
Loading...
Searching...
No Matches
transform.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "homogeneous.hpp"
4#include "math/bounding_box.hpp"
5#include "ray.hpp"
6#include "vector.hpp"
7#include "matrix.hpp" // Assumes this includes vector.hpp and point.hpp
8#include "point.hpp"
9
17
18namespace pbpt::math {
19
26
27class Transform {
28
29public:
30
31 // --- 仿射变换 (Affine Transformations) ---
32
38 static constexpr Transform translate(const Vec3& t) noexcept {
39 return Transform(Mat4(
40 1, 0, 0, t.x(),
41 0, 1, 0, t.y(),
42 0, 0, 1, t.z(),
43 0, 0, 0, 1
44 ));
45 }
46
52 static constexpr Transform scale(Float s) noexcept {
53 return Transform(Mat4(
54 s, 0, 0, 0,
55 0, s, 0, 0,
56 0, 0, s, 0,
57 0, 0, 0, 1
58 ));
59 }
60
66 static constexpr Transform scale(const Vec3& s) noexcept {
67 return Transform(Mat4(
68 s.x(), 0, 0, 0,
69 0, s.y(), 0, 0,
70 0, 0, s.z(), 0,
71 0, 0, 0, 1
72 ));
73 }
74
80 static constexpr Transform rotate_x(Float angle_rad) noexcept {
81 const Float s = sin(angle_rad);
82 const Float c = cos(angle_rad);
83 return Transform(Mat4(
84 1, 0, 0, 0,
85 0, c, -s, 0,
86 0, s, c, 0,
87 0, 0, 0, 1
88 ));
89 }
90
96 static constexpr Transform rotate_y(Float angle_rad) noexcept {
97 const Float s = sin(angle_rad);
98 const Float c = cos(angle_rad);
99 return Transform(Mat4(
100 c, 0, s, 0,
101 0, 1, 0, 0,
102 -s, 0, c, 0,
103 0, 0, 0, 1
104 ));
105 }
106
112 static constexpr Transform rotate_z(Float angle_rad) noexcept {
113 const Float s = sin(angle_rad);
114 const Float c = cos(angle_rad);
115 return Transform(Mat4(
116 c, -s, 0, 0,
117 s, c, 0, 0,
118 0, 0, 1, 0,
119 0, 0, 0, 1
120 ));
121 }
122
129static constexpr Transform rotate(Float angle_rad, const Vec3& axis) noexcept {
130 // 确保旋转轴是单位向量,这对于公式的正确性至关重要
131 const Vec3 a = axis.normalized();
132 const Float s = sin(angle_rad);
133 const Float c = cos(angle_rad);
134 const Float omc = 1.0f - c; // one-minus-cosine
135
136 const Float ax = a.x();
137 const Float ay = a.y();
138 const Float az = a.z();
139
140 // 罗德里格斯旋转公式的矩阵形式
141 return Transform(Mat4(
142 c + ax * ax * omc, ax * ay * omc - az * s, ax * az * omc + ay * s, 0,
143 ay * ax * omc + az * s, c + ay * ay * omc, ay * az * omc - ax * s, 0,
144 az * ax * omc - ay * s, az * ay * omc + ax * s, c + az * az * omc, 0,
145 0, 0, 0, 1
146 ));
147}
148
149 // --- 视图/摄像机变换 (View/Camera Transformations) ---
150
159 static constexpr Transform look_at(const Pt3& eye, const Pt3& target, const Vec3& up) noexcept {
160 const Vec3 f = (target - eye).normalized(); // Forward vector
161 const Vec3 s = f.cross(up).normalized(); // Right vector
162 const Vec3 u = s.cross(f); // Recalculated Up vector
163
164 return Transform(Mat4(
165 s.x(), s.y(), s.z(), -s.dot(eye.to_vector()),
166 u.x(), u.y(), u.z(), -u.dot(eye.to_vector()),
167 -f.x(), -f.y(), -f.z(), f.dot(eye.to_vector()),
168 0, 0, 0, 1
169 ));
170 }
171
172
173 // --- 投影变换 (Projection Transformations) ---
174
185 static constexpr Transform perspective(Float fov_y_rad, Float aspect_ratio, Float z_near, Float z_far) noexcept {
186 const Float tan_half_fovy = tan(fov_y_rad / 2.0);
187 return Transform(Mat4(
188 1.0 / (aspect_ratio * tan_half_fovy), 0, 0, 0,
189 0, 1.0 / (tan_half_fovy), 0, 0,
190 0, 0, z_far / (z_far - z_near), -z_far * z_near / (z_far - z_near),
191 0, 0, 1.0, 0
192 ));
193
194 }
195
209 static constexpr Transform orthographic(Float left, Float right, Float bottom, Float top, Float z_near, Float z_far) noexcept {
210
211 return Transform(Mat4(
212 2.0 / (right - left), 0, 0, -(right + left) / (right - left),
213 0, 2.0 / (top - bottom), 0, -(top + bottom) / (top - bottom),
214 0, 0, 1.0 / (z_far - z_near), -z_near / (z_far - z_near),
215 0, 0, 0, 1
216 ));
217 }
218
219private:
220 Mat4 m_mat{};
221
222public:
223 constexpr Transform() noexcept = default;
224 constexpr Transform(const Mat4& mat) : m_mat(mat) {}
225
226 constexpr const Mat4& mat() const { return m_mat; }
227
228 constexpr Transform& operator*=(const Transform& rhs) noexcept {
229 m_mat = m_mat * rhs.m_mat;
230 return *this;
231 }
232
233 constexpr Transform operator*(const Transform& rhs) const noexcept {
234 return Transform(m_mat * rhs.m_mat);
235 }
236
242 constexpr Pt3 operator*(const Pt3& point) const noexcept {
243 return (m_mat * Homo3(point)).to_point();
244 }
245
251 constexpr Vec3 operator*(const Vec3& vec) const noexcept {
252 return (m_mat * Homo3(vec)).to_vector();
253 }
254
260 constexpr Normal3 operator*(const Normal3& normal) const noexcept {
261 auto result = (m_mat.inversed().transposed() * Homo3(normal)).to_vector();
262 return Normal3(result);
263 }
264
265 constexpr Ray3 operator*(const Ray3& ray) const noexcept {
266 return Ray3(
267 *this * ray.origin(),
268 *this * ray.direction()
269 );
270 }
271
272 constexpr Bound3 operator*(const Bound3& bound) const noexcept {
273 return Bound3 {*this * bound.min(), *this * bound.max()};;
274 }
275
276};
277
278
279} // namespace pbpt
constexpr Normal3 operator*(const Normal3 &normal) const noexcept
Transforms a normal using the transform matrix.
Definition transform.hpp:260
static constexpr Transform rotate(Float angle_rad, const Vec3 &axis) noexcept
Creates a rotation matrix from an arbitrary axis and an angle (Rodrigues' rotation formula).
Definition transform.hpp:129
static constexpr Transform scale(Float s) noexcept
Creates a 4x4 uniform scaling matrix.
Definition transform.hpp:52
static constexpr Transform scale(const Vec3 &s) noexcept
Creates a 4x4 non-uniform scaling matrix.
Definition transform.hpp:66
static constexpr Transform rotate_y(Float angle_rad) noexcept
Creates a 4x4 rotation matrix around the Y-axis.
Definition transform.hpp:96
constexpr Pt3 operator*(const Pt3 &point) const noexcept
Transforms a point using the transform matrix.
Definition transform.hpp:242
static constexpr Transform rotate_x(Float angle_rad) noexcept
Creates a 4x4 rotation matrix around the X-axis.
Definition transform.hpp:80
static constexpr Transform orthographic(Float left, Float right, Float bottom, Float top, Float z_near, Float z_far) noexcept
Creates a left-handed orthographic projection matrix.
Definition transform.hpp:209
static constexpr Transform translate(const Vec3 &t) noexcept
Creates a 4x4 translation matrix.
Definition transform.hpp:38
constexpr Vec3 operator*(const Vec3 &vec) const noexcept
Transforms a vector using the transform matrix.
Definition transform.hpp:251
static constexpr Transform look_at(const Pt3 &eye, const Pt3 &target, const Vec3 &up) noexcept
Creates a view matrix (a.k.a. camera matrix) using the "look-at" method.
Definition transform.hpp:159
static constexpr Transform rotate_z(Float angle_rad) noexcept
Creates a 4x4 rotation matrix around the Z-axis.
Definition transform.hpp:112
static constexpr Transform perspective(Float fov_y_rad, Float aspect_ratio, Float z_near, Float z_far) noexcept
Creates a left-handed perspective projection matrix.
Definition transform.hpp:185
constexpr T & x() noexcept
Accesses the first component (x-axis).
Definition vector.hpp:88
constexpr T & z() noexcept
Accesses the third component (z-axis).
Definition vector.hpp:92
constexpr T dot(const Vector &rhs) const noexcept
Calculates the dot product of this vector and another.
Definition vector.hpp:330
constexpr Vector cross(const Vector &rhs) const noexcept
Calculates the cross product of this vector and another.
Definition vector.hpp:342
constexpr Vector normalized() const
Returns a new vector that is a normalized version of this one.
Definition vector.hpp:294
constexpr T & y() noexcept
Accesses the second component (y-axis).
Definition vector.hpp:90
Defines a class for N-dimensional homogeneous coordinates.
Defines a generic, RxC-dimensional, constexpr-friendly matrix class and its views.
The namespace for math library implementation.
Definition bounding_box.hpp:9
float Float
The primary floating-point type used throughout the math library.
Definition global.hpp:29
Vector< Float, 3 > Vec3
A 3-dimensional vector of type Float.
Definition vector.hpp:565
Homogeneous< Float, 3 > Homo3
A 3-dimensional homogeneous coordinate using the library's default Float type.
Definition homogeneous.hpp:226
constexpr T cos(T x)
Calculates the cosine of an angle with constexpr support.
Definition function.hpp:252
Point< Float, 3 > Pt3
A 3-dimensional point of type Float.
Definition point.hpp:274
Normal< Float, 3 > Normal3
A 3-dimensional vector of type Float.
Definition vector.hpp:579
Ray< Float, 3 > Ray3
A 3-dimensional ray of type Float, commonly used in 3D graphics.
Definition ray.hpp:109
Matrix< Float, 4, 4 > Mat4
A 4x4 matrix of type Float.
Definition matrix.hpp:811
constexpr T sin(T x)
Calculates the sine of an angle with constexpr support.
Definition function.hpp:216
constexpr T tan(T x)
Calculates the tangent of an angle with constexpr support.
Definition function.hpp:271
BoundingBox< Float, 3 > Bound3
3D bounding box
Definition bounding_box.hpp:221
Defines a generic, N-dimensional Point class and its geometric operations.
Defines a generic, N-dimensional geometric Ray class.
Defines a generic, N-dimensional, constexpr-friendly vector class.