目 录CONTENT

文章目录

【一周学会光线追踪】工具类

千年的霜雪
2025-04-08 / 0 评论 / 0 点赞 / 6 阅读 / 0 字 / 正在检测是否收录...

三维向量类 vec3.h

#pragma once

#include <cmath>
#include <iostream>

// 三维向量类,用于表示单个像素的颜色
// 每个维度都为 double
class vec3 {
public:
	double e[3];

	vec3() : e{0, 0, 0} {}
	vec3(double e0, double e1, double e2) : e{e0, e1, e2} {}

	double x() const { return e[0]; }
	double y() const { return e[1]; }
	double z() const { return e[2]; }

	vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); }
	double operator[](int i) const { return e[i]; }
	double& operator[](int i) { return e[i]; }

	vec3& operator+=(const vec3& v)
	{
		e[0] += v.e[0];
		e[1] += v.e[1];
		e[2] += v.e[2];
		return *this;
	}

	vec3& operator*=(double t)
	{
		e[0] *= t;
		e[1] *= t;
		e[2] *= t;
		return *this;
	}

	vec3& operator/=(double t)
	{
		return *this *= 1 / t;
	}

	// 长度
	double length() const
	{
		return std::sqrt(length_squared());
	}

	// 长度的平方
	double length_squared() const
	{
		return e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
	}
};

using point3 = vec3;


// Vector3 utility Functions

inline std::ostream& operator<<(std::ostream& out, const vec3& v)
{
	return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2];
}

inline vec3 operator+(const vec3& u, const vec3& v)
{
	return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]);
}

inline vec3 operator-(const vec3& u, const vec3& v)
{
	return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]);
}

inline vec3 operator*(const vec3& u, const vec3& v)
{
	return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]);
}

inline vec3 operator*(double t, const vec3& v)
{
	return vec3(t * v.e[0], t * v.e[1], t * v.e[2]);
}

inline vec3 operator*(const vec3& v, double t)
{
	return t * v;
}

inline vec3 operator/(const vec3& v, double t)
{
	return (1 / t) * v;
}

// 点积
inline double dot(const vec3& u, const vec3& v)
{
	return u.e[0] * v.e[0]
		+ u.e[1] * v.e[1]
		+ u.e[2] * v.e[2];
}

// 叉积
inline vec3 cross(const vec3& u, const vec3& v)
{
	return vec3(
		u.e[1] * v.e[2] - u.e[2] * v.e[1],
		u.e[2] * v.e[0] - u.e[0] * v.e[2],
		u.e[0] * v.e[1] - u.e[1] * v.e[0]
	);
}

// 单位化向量
inline vec3 unit_vector(const vec3& v)
{
	return v / v.length();
}

射线类 ray.h

#pragma once

#include "vec3.h"

/*
* 射线被作为一个函数看待
* P(t) = A + tb
* P是沿3D直线的一个3D位置
* A是射线的起点
* b是射线的方向
* 参数t是一个实数(double) 对于不同的t的取值,代表着沿P(t)移动点
*/

// 射线类
class ray {
public:
	ray() {}

	ray(const point3& origin, const vec3& direction) : orig(origin), dir(direction)
	{ }

	const point3& origin() const { return orig; }
	const vec3& direction() const { return dir; }

	// 上文中的函数 P(t)
	point3 at(double t) const
	{
		return orig + t * dir;
	}

private:
	point3 orig; // 起点
	vec3 dir; // 方向
};

工具头文件 color.h

其中封装了将颜色写入到标准输出流的函数

#pragma once

#include "vec3.h"

#include <iostream>

using color = vec3;

// 将单个像素的颜色写入输出流中
void write_color(std::ostream& out, const color& pixel_color)
{
	auto r = pixel_color.x();
	auto g = pixel_color.y();
	auto b = pixel_color.z();

	// 将 [0,1] 范围内的值映射至 [0,255] 范围内(byte)
	int rbyte = int(255.999 * r);
	int gbyte = int(255.999 * g);
	int bbyte = int(255.999 * b);

	out << rbyte << ' ' << gbyte << ' ' << bbyte << '\n';
}
0

评论区