现在我们已经学习了笛卡尔坐标系统的概念,同事也学习了点和向量相对于坐标的位置,我们现在可以学习一些在点和向量上的最基本的操作,你会在很多的3D程序中发现这些基础的函数。
(1)C++中的向量类
首先让我们定义一个C++向量类
template<typename T>
class Vec3 {
public:
// 3 most basic ways of initializing a vector
Vec3() : x(T(0)), y(T(0)), z(T(0)) {}
Vec3(const T &xx) : x(xx), y(xx), z(xx) {}
Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
T x, y, z;
};
(2)向量的长度
向我们之前的段落中提到的,一个向量可以看作是有原点和终点的箭头表示。一个向量不仅指定了从A点到B点的方向,同时也可以得到它们之间的距离。可以通过下面的公式很容易地得到它们的长度,
在数学上,双竖线表示向量的长度。向量的长度有时候也叫做norm 或者标量(magnitude).
template<typename T>
class Vec3 {
public:
// 3 most basic ways of initializing a vector
Vec3() : x(T(0)), y(T(0)), z(T(0)) {}
Vec3(const T &xx) : x(xx), y(xx), z(xx) {}
Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
T x, y, z;
// length can be a method from the class
T length() {
return sqrt(x*x + y*y + z*z);
}
};
// or you can also compute the length in a function which is not part of the class
template<typename T>
T length(const Vec3<T> &v) {
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}
(3)求单位向量
英语中单位向量有两种表示,normalize或者是normalise.在日常中使用美国语法,所以我们使用的normalize.
单位向量是长度为1的向量,如图1所示。也叫做单位向量。求单位向量很简单。我们首先求向量的长度,然后向量的每个坐标除以相应的长度。数学表达式:
记住C++实现可能已经最优化。首先确定向量的长度是否大于0(因为不允许除以0),然后我们计算向量长度的倒数,最后向量的每个坐标值乘以这个倒数而不是除以向量的长度。你是知道的,计算机中乘法远比除法简单。这个最优化很重要,因为在渲染中单位化是一个很常见的操作,它可以应用于成千上万的向量中,或许会更多。在这个级别上,任何小的优化都可以节省很多的时间。虽然很多时候编译器会帮你干这件事情,但是你可以在你的代码中准确地表达你的意图。
template<typename T>
class Vec3 {
public:
// 3 most basic ways of initializing a vector
Vec3() : x(T(0)), y(T(0)), z(T(0)) {}
Vec3(const T &xx) : x(xx), y(xx), z(xx) {}
Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
T x, y, z;
// length can be a method from the class
T length() {
return sqrt(x*x + y*y + z*z);
}
// as a method of the class Vec3
Vec3<T>& norma