3D数学读书笔记——向量运算及在c++上的实现
本系列文章由birdlove1987编写。转载请注明出处。
文章链接: http://blog.csdn.net/zhurui_idea/article/details/24782661
開始之前:接上上篇说的,张宇老师说过线性代数研究的就是向量。事实上严谨的说,数学中专门研究向量的分之称作线性代数,线性代数是一个很有趣而且应用广泛的研究
领域,但它与3D数学关注的领域并不同样。3D数学主要关心向量和向量运算的几何意义。
零向量:不论什么集合,都存在 the additive identity element。我们把它表示为 x (变量仅仅是作为代表未知量的占位符存在) ,对集合中随意元素 y ,满足 y + x = y。
n维向量集合的 the additive identity element 就是 n维零向量。
它的每一维都是零。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />
零向量很特殊。由于它是唯一大小为零的向量。对于其它随意数m,存在无数多个大小为m的向量。
它们构成了一个圆。
零向量也是唯一一个没有方向的向量。事实上零向量表示的就是“没有位移”,就像标量零表示“没有数量”一样。
负向量:对于随意集合,元素 x 的加性逆元为 -x,其与x相加等于the additive identity,即 x + (-x) = 0.
运算法则1:向量变负。要得到随意维向量的负向量,仅仅须要简单的将向量地每个分量都变负就可以。
几何解释:向量变负,将得到一个和原来向量大小相等。方向相反的向量。(向量在图中的位置是无关紧要的。仅仅有大小和方向才是最重要的)。
向量大小:事实上向量的大小和方向都没有在向量的数学表示中明白的表示出来。全部向量的大小是须要计算的,向量的大小也常被称作向量的长度或模。
运算法则2:n维向量大小的计算公式例如以下图
线性代数中,向量的大小用向量两边双竖线表示,这和标量的绝对值在标量两边加单竖线表示类似。(和我们在神经网络课上学的范数也很像)。
标量与向量的乘法:尽管标量与向量不能相加。但它们能相乘。
结果得到一个向量,与源向量平行。但长度不同或方向相反。
运算法则3:标量和向量的乘法很直接,将向量的每个分量都与标量相乘就可以。
ps:1. 标量与向量的乘法和除法优先级高于加法和减法。
2. 标量不能除以向量,而且向量不能除以还有一个向量。
3. 负向量能被觉得是乘法的特殊情况。乘以标量-1.
几何解释:几何意义上,向量乘以标量K的效果是以因子|k| 缩放向量的长度。
标准化向量:对很多向量,我们仅仅关心它的方向而不关心其大小,这种情况下,使用单位向量将很方便。
单位向量就是大小为1的向量,单位向量常常也被称作标准化向量。
运算法则4:对于随意非零向量v,都能计算出一个和v方向同样的单位向量 v‘ 这个过程被称作向量的标准化,要标准化向量,将向量除以它的大小就可以。
ps:零向量不能被标准化。数学上这是不同意的,由于将导致除零。几何上也没有意义,由于零向量没用方向。
向量的加法和减法:假设两个向量的维数同样,那么它们能相加,或相减。
结果向量的维数与原向量同样。
向量加减法的记法和标量加减的记法同样。
运算法则5:两个向量相加或相减,将相应分量相加就可以。
ps:(1)向量不能与标量或维数不同的向量相加减。
(2)和标量加法一样,向量加法满足交换律,但向量减法不满足交换律。
向量点乘:向量点乘也常称作向量内积。
运算法则6:向量点乘就是相应分量乘积的和。结果是一个标量。
几何解释:点乘结果描写叙述了两个向量的“类似”程度,点乘结果越大,两个向量越相近。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />
ps:(1)假设a,b中随意一个为零。那么a·b的结果也等于零。可是点乘等于零也可能是两个向量相互垂直。
向量投影:给定两个向量 v 和 n,能将v分解成两个分量:和
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />。它们分别平行和垂直于n
。并满足 v =
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />+
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />。一般称平行分量为
v 在 n 上的投影。
运算法则7:我们使用点乘计算投影。
向量叉乘:向量叉乘又叫叉积。仅可应用于3D向量。
运算法则8:
几何解释:叉乘得到的向量垂直于原来的两个向量。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />
========================华丽的切割线===============================
以下用c++代码实现以下上面出现过的计算过程:
class Vector3D {
public:
float x,y,z;
// 构造函数
// 默认构造函数。不运行不论什么操作
Vector3D() {}
// 复制构造函数
Vector3D(const Vector3D &a) : x(a.x), y(a.y), z(a.z) {}
// 带三个參数的构造函数,三个值完毕初始化
Vector3D(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}
// 重载赋值运算符
Vector3D &operator =(const Vector3D &a) {
x = a.x; y = a.y; z = a.z;
return *this;
}
// 重载比較运算符
bool operator ==(const Vector3D &a) const {
return x==a.x && y==a.y && z==a.z;
}
bool operator !=(const Vector3D &a) const {
return x!=a.x || y!=a.y || z!=a.z;
}
// 向量运算
// 设置零向量
void zero() { x = y = z = 0.0f; }
// 重载负运算符
Vector3D operator –() const { return Vector3D(–x,–y,–z); }
// 重载加减运算符
Vector3D operator +(const Vector3D &a) const {
return Vector3D(x + a.x, y + a.y, z + a.z);
}
Vector3D operator –(const Vector3D &a) const {
return Vector3D(x – a.x, y – a.y, z – a.z);
}
// 重载标量乘、除法运算符
Vector3D operator *(float a) const {
return Vector3D(x*a, y*a, z*a);
}
Vector3D operator /(float a) const {
float oneOverA = 1.0f / a; // 没有对除零检查
return Vector3D(x*oneOverA, y*oneOverA, z*oneOverA);
}
// 重载?=运算符
Vector3D &operator +=(const Vector3D &a) {
x += a.x; y += a.y; z += a.z;
return *this;
}
Vector3D &operator –=(const Vector3D &a) {
x –= a.x; y –= a.y; z –= a.z;
return *this;
}
Vector3D &operator *=(float a) {
x *= a; y *= a; z *= a;
return *this;
}
Vector3D &operator /=(float a) {
float oneOverA = 1.0f / a;
x *= oneOverA; y *= oneOverA; z *= oneOverA;
return *this;
}
// 向量标准化
void normalize() {
float magSq = x*x + y*y + z*z;
if (magSq > 0.0f) { // 检查除零
float oneOverMag = 1.0f / sqrt(magSq);
x *= oneOverMag;
y *= oneOverMag;
z *= oneOverMag;
}
}
// 向量点乘。重载乘法运算符
float operator *(const Vector3D &a) const {
return x*a.x + y*a.y + z*a.z;
}
};
// 求向量模
inline float vectorMag(const Vector3D &a) {
return sqrt(a.x*a.x + a.y*a.y + a.z*a.z);
}
// 计算两向量的叉乘
inline Vector3D crossProduct(const Vector3D &a, const Vector3D &b) {
return Vector3D(a.y*b.z – a.z*b.y,a.z*b.x – a.x*b.z,a.x*b.y – a.y*b.x);
}
// 标量乘法
inline Vector3D operator *(float k, const Vector3D &v) {
return Vector3D(k*v.x, k*v.y, k*v.z);
}
// 计算两点间距离
inline float distance(const Vector3D &a, const Vector3D &b) {
float dx = a.x – b.x;
float dy = a.y – b.y;
float dz = a.z – b.z;
return sqrt(dx*dx + dy*dy + dz*dz);
}
// 全局零向量
extern const Vector3D kZeroVector;
-End-
參考文献:(1)《3D Math Primer for Graphics and Game Development》
(2)百度百科
3D数学读书笔记——向量运算及在c++上的实现的更多相关文章
- 3D数学读书笔记——矩阵基础
本系列文章由birdlove1987编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/24975031 矩 ...
- 3D数学读书笔记——四元数
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25400659 什么是四元数 ...
- 3D数学读书笔记——矩阵基础番外篇之线性变换
本系列文章由birdlove1987编写.转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/25102425 前面有一篇文章 ...
- 3D数学读书笔记——多坐标系和向量基础
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24662453 第一个知识点 ...
- 3D数学读书笔记——3D中的方位与角位移
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25339595 方位和角位移 ...
- 3D数学读书笔记——矩阵进阶
本系列文章由birdlove1987编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/25242725 最终要学习矩阵 ...
- 3D数学学习笔记——笛卡尔坐标系
本系列文章由birdlove1987编写.转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24601215 1.3D数学 ...
- 读书笔记--Android Gradle权威指南(上)
本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 最近看了一本书<Android Gradle 权威指南>,对于 Gradle 理解又更深了,但不想过段时间就又忘光了,所 ...
- 3D数学--学习笔记(五岁以下儿童):总结一些概念(避免遗忘!)
下面是一些概念只是一个简单的解释,这里是它的一个简单的了解! 当人们谈论,我能理解有关. 1.正交投影: 投影.这意味着降维操作. 全部的点都被拉平至垂直的轴(2D)或平面(3D)上.这样的类型的投影 ...
随机推荐
- Adoquery的 moveby和GotoBookmark,RecNo
GotoBookmark 是必须存在的记录,再次返回原来那个记录的位置,但是原来的那个记录必须存在,所以不适合[删除订单后回到原来的位置],因为原来的订单已经不存在了,删除了, moveby(),从当 ...
- Codeforces Gym101502 J-取数博弈
还有J题,J题自己并不是,套的板子,大家写的都一样,因为大家都是套板子过的,贴一下代码,等学会了写一篇博客... J.Boxes Game 代码: 1 //J. Boxes Game-取数博弈-不会, ...
- jenkins按版本发布maven项目
1.先为java这个项目创建三个版本 vim pom.xml vim src/main/java/com/ghz/testweb/App.java git add . git commit -m &q ...
- Codeforces Gym 100338C Important Roads 最短路+Tarjan找桥
原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-an ...
- 【APIO2015】Palembang Bridges
题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 $A$ 和区域 $B$. 每一块区域沿着河岸都建了恰好 $1000000001$ 栋的建筑,每条岸边的建筑都从 $0$ 编号到 $100 ...
- 2017 [六省联考] T2 相逢是问候
4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1205 Solved: 409[Submit][Stat ...
- Codeforces 622F The Sum of the k-th Powers
Discription There are well-known formulas: , , . Also mathematicians found similar formulas for high ...
- PHP平均整数红包算法
<?php function RandomMoney( $money,$num ){ $arr = array(); $total_money = 0; $this_money = $money ...
- 织梦dedecms 去掉后台登陆验证码的方法
那么有什么办法解决呢? 那么现在就给大家解决织梦去掉后台登陆验证码. 这里面分两种版本 一个是织梦5.6的程序 那么织梦5.6程序的解决办法是: 在织梦DedeCms5.6版本可以通过下面路径对验 ...
- ubuntu boot空间不足
在安装 Ubuntu的时候 , 给/boot文件目录分配空间的时候,是100M,/boot可以单独分成一个区,也可以不单独分,在/(根目录)下也会自动为其创建一个boot目录.顺便提一下,Linux分 ...