Raytracing The Rest of Your Life
在线查看器
参考教程
项目代码
Chapter 1:A Simple Monte
Carlo Program
蒙特卡罗方法(MC)是一种统计模拟方法,是一类很重要的数值计算方法,它是一种使用随机数解决好很多实际问题的方法
1.1 估计\(\pi\)
假设你扔了很多随机的点到方框中,那么有一部分在圆内,其中圆内点和方框点的比例应该就是圆的面积和方框面积的比例,由此:
\[
比例 = \frac{π * R * R}{(2R)*(2R)} = \frac{π}{4}
\]
由于上式和R无关,我们任意取R = 1,圆心位于原点,则
#include <iostream>#include "Math/Random.h"void estimate_π(const size_t points) { int inside = 0; for (int i = 0; i < points; ++i) { double x = 2 * Random::rand01() - 1; ...
Raytracing The Next Week
在线查看器
参考教程
项目代码
Chapter 1:Motion Blur
1.1 运动模糊
光线多了一个属性time,用于记录该光线射入相机的时间
class Ray {public: Ray() {}; Ray(const Point3& orig, const Vec3& dir, const double time = 0) :origin(orig), direction(dir), time(time) {} Ray(const Ray& r) :origin(r.origin), direction(r.direction) {} Point3 Origin() const { return origin; } Vec3 Direction() const { return direction; } double Time() const { return time; } // P(t) = or ...
Raytracing In One Weekend
在线查看器
参考教程
项目代码
Chapter 1:Output an image
1.1 PPM图像
P3 // 文件的类型: Pixmap, ASCII3 2 // 图片的width、height255 // 像素的最大值// 每个像素, 从左上角开始,一行一行扫描设置像素值255 0 0 0 255 00 0 255255 255 0255 255 2550 0 0
Chapter 2:The vec3 class
2.1 向量类,见vec3.h
Chapter 3:Rays,a
simple camera, and background
3.1 光线,见ray.h
\[
p(t) = origin + t * direction
\]
3.2 相机,见camera.h
主要任务是,给定一个\([0,1]^2\)的屏幕坐标,生成一条光线
ray camera::getRay(double u, double v) { // 光线的起点为原点, 方向指向观察平面上的当前像素 ray r(positio ...
OOP Lab4 Person Diary
一、问题描述
Personal Diary是一个命令行程序,包含以下四个程序
pdaddpdlist []pdshowpdremove
1.1 pdadd程序
向日记文件dairy.txt中添加一个实体,包含日记的时间、内容
时间:如果日记的时间与dairy.txt中的已有日记重复,则会将原来的日记替换掉
内容:从stdin中逐行读取日记内容,直到单独的一个'.'/EOF截止
1.2 pdlist程序
按照日期的顺序,列出diary.txt中的日记实体
输入:如果通过命令行参数,输入了开始日期和结束日期,则只输出在这两个日期之间的日记
输出:stdout
1.3 pdshow程序
按照输入的日期,列出diary.txt中的对应日记实体的内容
输入:stdin
输出:stdout
1.4 pdremove程序
按照输入的日期,删除diary.txt中的对应日记
输入:stdin
输出:stdout
返回值:0表示删除成功,1表示删除失败
二、实现思路
2.1 定义的类
2.1.1 Date类
成员变量
...
OOP 第13章:SmartPointer
第13章 SmartPointer13.1 设计目标
记录当前对象被引用了多少次 reference count
类UCObject用来记录次数,use-counted object
类UCPointer用来指向UCObject
智能指针是通过一个类定义的
使用模板实现
重载操作符->和*
13.2 设计类和接口
UCObject:实现reference count
UCPointer:是一个类模板,支持指向任意一个类型的UCObject
String Rep:字符串表示的细节,是可共享的
String:再封装一层,提供给用户
13.3 实现细节
UCObject
#include <assert.h>class UCObject {private: int m_refCount;public: UCObject() : m_refCount(0) { } UCObject(const UCObject&) : m_refCount(0) { } ...
OOP 第12章:Policy-based Design
第12章 Policy-based Design基于策略的设计12.1 The Multiplicity of Software Design
一个问题有很多中正确的解法,不同的解法在不同情况下具有不同的优势
软件需要支持用户的定制,因此需要提供多种情况对应的实现形式
12.1.1 例:创建一个对象的策略// 直接new一个对象template <class T>struct OpNewCreator{ static T* Create(){ return new T; }};// 先分配内存,再调用构造函数template <class T>struct MallocCreator{ static T* Create(){ void* buf = std::malloc(sizeof(T)); if (!buf) return 0; return new(buf) T; }} ...
OOP 第11章:Iterators
第11章 Iterators11.1 Iterator的作用
在算法中使用的统一接口
像指向容器中元素的指针一样工作
通过++操作符顺序访问容器的元素
通过*操作符访问元素的内容
11.1.1 auto_ptrtemplate<class T> class auto_ptr { T *pointee;public: explicit auto_ptr(T *p) { pointee = p;} template <class U> auto_ptr(const auto_ptr<U> &rhs): pointee(rhs.release) { } // 成员函数模板 template<class U> Auto_ptr<T>& operator=(const auto_ptr<U> &rhs) { if (this != &a ...
OOP 第11章:Class Design
第11章 Class Design11.1 类的设计要求
要易于理解,易于维护,易于重用
要做些什么
我们需要多少种类?
何时定义成一个类?
类中有什么接口和数据?
我们需要构造继承来促进接口和代码重用吗?
哪个函数应该是virtual的,以支持运行时的动态绑定?
考量内容
Responsibility-driven design:职责驱动的设计
Coupling:耦合
Cohesion:内聚
Refactoring:重构
11.2 代码质量11.2.1 Coupling 耦合Coupling耦合:指的是一个程序中,不同单元之间的联系
如果两个类紧密地依赖于彼此的许多细节,我们就说它们是紧密耦合tightly coupled的
我们的目标是:尽可能松耦合Loose coupling
直观表述:如果X改变了,在Y中我们需要修改多少代码
Loose coupling松耦合:
理解类X,我们不需要理解类Y
改变类X,我们不需要改变类Y
因此会提高可维护性maintainability
实现松耦合的方法:
回调函数call-back:通过接 ...
OOP 第10章:Exceptions
第10章 Exceptions10.1 IntroductionC++的原则
尽量在编译时,找出可能的错误
代码重用
但是在运行过程中,仍有错误发生,我们需要能够处理未来运行时,可能出现的错误
当出现错误的时候,程序不知道应该如何处理
但是程序知道必须要停止当前进程
让调用者caller处理异常
exception的优点
将代码简化
将描述想要执行的代码与执行的代码分开
10.2 语法10.2.1 callee扔出异常
throw出的是一个异常对象(class)
class VectorIndexError {public: VectorIndexError(int v) : m_badValue(v) { } ~VectorIndexError() { } void diagnostic() { cerr << "index " << m_ badValue << "out of range!"; ...
OOP 第9章:Template
第9章 Template相当于定义了一个 函数/类 的集合
9.1 函数模板9.1.1 函数模板的声明对不同的类型,执行相同的操作时,使用函数模板,比如swap、sort
template <class T> // 或者是<typename T>void swap(T& x, T& y){ T temp = x; x = y; y = temp;}
template:声明模板
class T:声明了参数化类型的名字,在模板函数中,用T作为一个类型名
作为函数的参数
作为函数的返回值
作为函数的中间变量
9.1.2 函数模板的实例化 template instantiation
将一个真实的类型,带入template中
编译器会生成一个新的 函数/类 的定义
在生成的过程中,会检查 语法错误/不安全的调用
模板特化specialization
对特定的类型,执行新的模板函数
int i = 3; int j = 4;swap(i, j); // 实例化 in ...