1. Math 数学相关
1.1. 1.向量相关
1.1.1. 基础知识
- 向量在图形学中的表示
向量可以用其次坐标来表示
A =
向量的转置
=
向量长度的计算
=
- 向量相加(add): 平行四边形法则或者三角形法则
1.1.2. 向量的运算
a.向量点乘(dot)
· =
向量点乘后得到的结果是一个数值
- for 2D
· = · = +
- for 3D
· = · = + +
几何意义:
表征或计算两个向量之间的夹角:如果向量 a 和 b 是单位向量, = ·
b 向量在 a 向量方向上的投影
向量点乘在图形学中的实际应用
计算两个向量的夹角:比如计算光照方向和物体表面之间的夹角
投影阴隐的计算
把一个向量分解为两个垂直方向上的向量
向量点乘的正负可以表示两个向量的方向是否接近:比如金属的高光反射,不接近就看不到反射的光。
向量点乘满足交化率结合律和分配率
b.向量叉乘(cross)
x =
向量点乘后得到的结果是一个向量
- 数字大小
x = =
- 方向:右手螺旋定则
x = +
x = -
几何意义
方向的意义:可以通过两个向量的叉乘,生成第三个垂直于a,b的法向量,从而构建X、Y、Z坐标系
数值的意义:在二维空间中,叉乘还有另外一个几何意义就是:aXb等于由向量a和向量b构成的平行四边形的面积。
向量点乘在图形学中的实际应用
判定左和右:比如判断向量 a 在向量 b 的左侧还是右侧
判定里和外:比如判断一个点是否在一个三角形的内部
面积计算:比如计算复杂几何体的表面积
向量点乘不满足交化率,但是满足结合律和分配率
1.2. 2.矩阵相关
矩阵乘法口诀:左取行,右取列,相乘再相加,行列定位置。
向量点乘不满足交化率,但是满足结合律和分配率
1.2.1. a.矩阵乘法合法性
A =
B =
我们能不能把它们相乘得到 AB 必须满足一个条件:A 矩阵的列数必须等于 B 矩阵的行数。
1.2.2. b.矩阵的转置
- 行列转置
=
- 特性
1.2.3. c.矩阵在图形学中的实际应用
矩阵乘以向量:向量必须是一个列向量,实际就是我们的变换。
矩阵乘法结合律:比如视图矩阵乘以投影矩阵。
1.2.4. d.矩阵变换
- 平移
* =
- 缩放
* =
- 旋转
绕x轴旋转α度对应的旋转矩阵Rx
* =
绕y轴旋转α度对应的旋转矩阵Ry
* =
绕z轴旋转α度对应的旋转矩阵Rz
* =
1.3. 3.欧拉对象 Euler、四元数 Quaternion 和旋转矩阵
欧拉对象、四元数和旋转矩阵都是用来表达对象的旋转信息。欧拉对象和四元数存在的意义:为了给旋转变换做插值。
// Euler( x : Float, y : Float, z : Float, order : String )
// x - (optional) 用弧度表示x轴旋转量。 默认值是 0。
// y - (optional) 用弧度表示y轴旋转量。 默认值是 0。
// z - (optional) 用弧度表示z轴旋转量。 默认值是 0。
// order - (optional) 表示旋转顺序的字符串,默认为'XYZ'(必须是大写)。
const Euler = new THREE.Euler( Math.PI/4, 0, Math.PI/2, 'XYZ');
Euler.x = Math.PI/4;
Euler.y = Math.PI/2;
Euler.z = Math.PI/4;
Euler.order = 'YZX'
// 绕单位向量Vector3(x, y, z) 表示的轴旋转 θ 度
// k = sinθ/2
// q = ( xk , yk , z*k, cosθ/2)
// 【下面的例子是:将点(0, 0, 1)绕 Y 轴旋转 90 度,得到新的坐标(1, 0, 0)】
const quaternion = new THREE.Quaternion();
// 旋转轴 new THREE.Vector3(0, 1, 0)
// 旋转角度 Math.PI / 2
const angle = Math.PI / 2
quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), angle)
console.log('查看四元数结构', quaternion);
const k = Math.sin(angle / 2)
console.log('查看数组', [0 * k , 1 * k , 0 * k, Math.cos(angle / 2)]);
const vector = new THREE.Vector3( 0, 0, 1 );
const newVector = vector.clone().applyQuaternion( quaternion );
console.log('旋转后的新坐标', newVector)