遵循右手螺旋法则:四指并拢,并且四指弯曲的方向和 a 旋转到 b 的方向一致,此时伸直大拇指,大拇指的方向即为 a b 叉乘结果的方向。
判断两个向量,谁在左,谁在右
计算 a 叉积 b,如果结果 > 0 则 b 在 a 左侧,反之 则 b 在 a 右侧。若叉积结果为 0 表示二者方向重合。
判断一个点是在一个三角形内,还是三角形之外
假设有 3 个向量 a b c 首尾相连构成了一个三角形,此时有一个点 p,依次分别计算出 a x ap、b x bp、c x cp,然后检验这 3 个叉乘结果是否都为正 或 为负。若三个叉乘结果都为正 或 都为负,那么就表明 点p 位于三角形内部。若出现有的叉乘结果为正,有的为负,那么就表明 点p 位于三角形外部。
const a = new Vector2(1,0)
const b = new Vector2(0,1)
console.log(a.cross(b)) // 1
const c = new Vector3(1,0,0)
const d = new Vector3(0,1,0)
c.cross(d)
console.log(c) // Vector3 {x: 0, y: 0, z: 1}
请注意:在Three.js中,绝大多数计算都会直接修改对象本身。
例如上面示例中当 c.cross(d) 执行后,c 的值就会变成计算结果。
Vector2的属性和方法
属性名
对应含义
x
x坐标值,默认为0
y
y坐标值,默认为0
height
y的别名
width
x的别名
方法名
对应含义
.add ( v : Vector2 ) : this
当前向量加上参数 v 向量
.addScalar ( s : Float ) : this
将当前向量的x、y 值分别加上参数 s
.addScaledVector ( v : Vector2, s : Float ) : this
Three.js中的数学转换
点和向量
点
别称: 坐标点
用途: 记录坐标系中某个具体的位置
对应类: Vector2、Vector3、Vector4
示例:
向量(vector)
别称: 线段、矢量、方向
用途: 记录坐标系中某个线段或方向
对应类: Vector2、Vector3、Vector4
示例:
向量的相关知识点:
点积(dot)
别名: 点乘、内积
表达式: a · b = ||a|| ||b|| cosθ
用途:
可以推导出两个向量之间的内夹角 θ (弧度)
若我们知道两个向量 a、b 的夹角为 θ,就可以计算出一个向量a 在另外一个向量b 上的投影,即 cosθ * ||b||
同理可以得出 sinθ * ||b|| 为两个向量之间最大的距离
我们还可以通过两个向量的夹角 θ 的值,来判断这两个向量的前后关系。
运算律: 符合交换律、分配率、结合律
对应方法: a.dot(b)
计算结果: 一个数字(number)
示例:
叉积(cross)
别名: 叉乘、外积
表达式: a x b
用途:
计算出同时垂直于两个向量的垂直向量。因此可以方便从一个二维平面构建出一个 3 维坐标系。也会应用于光栅化计算中。
遵循右手螺旋法则:四指并拢,并且四指弯曲的方向和 a 旋转到 b 的方向一致,此时伸直大拇指,大拇指的方向即为 a b 叉乘结果的方向。
判断两个向量,谁在左,谁在右
计算 a 叉积 b,如果结果 > 0 则 b 在 a 左侧,反之 则 b 在 a 右侧。若叉积结果为 0 表示二者方向重合。
判断一个点是在一个三角形内,还是三角形之外
假设有 3 个向量 a b c 首尾相连构成了一个三角形,此时有一个点 p,依次分别计算出 a x ap、b x bp、c x cp,然后检验这 3 个叉乘结果是否都为正 或 为负。若三个叉乘结果都为正 或 都为负,那么就表明 点p 位于三角形内部。若出现有的叉乘结果为正,有的为负,那么就表明 点p 位于三角形外部。
运算律: 不符合交换律,a x b 和 b x a 的结果不相同。
对应方法: a.cross(b)
计算结果: 对于二维来说结果是一个数字(number)、对于三维来说结果是一个向量(Vector3)
示例:
Vector2的属性和方法
曼哈顿距离
(参见表格下方注解)默认 offset 为0
component
在这里的意思为 “分量”曼哈顿
长度alpha 取值范围 0 - 1,若 alpha 为 0 则相当于不做任何变动,若 alpha 为 1 则相当于将当前向量变为 v
alpha 取值范围 0 - 1,若 alpha 为 0 则相当于结果为 v1,若 alpha 为 1 则结果为 v2
转化后的向量方向不变,但长度为 1,被称为
归一化
以 x 为例 若 x < 0 则 x = 0,若 x > 0 则 x = Math.floor(x),y 也类似
相当于执行 .set(scalar, scalar)
并返回该数组。若 arry 为空则创建一个新的数组,offset 默认值为 0
虽然 Three.js 中 Vector2 提供了这么多方法,但是他们大体上可以归类为以下几种:
直接修改 x、y 的值:
修改限定 x、y 的取值范围:
设置或获取向量的其他形式:
向量长度相关:
向量距离相关:
向量的加减乘除:
向量的一些其他运算:
曼哈顿距离
传统几何概念中,我们计算 2 个点的距离使用的是 2 点划直线的方式。
在计算的过程中需要使用求平方和开根号,这种方式虽然无比精确但人类口算有点难。
曼哈顿距离
是19 世纪由数学家 赫尔曼·闵可夫斯基 发明的。他将计算 2 点之间的距离简化为:| x1 - x2 | + | y1 - y2 |
这个公式之所以叫 “曼哈顿距离”,是因为解释该公式的时候是以美国纽约曼哈顿区为示例。
曼哈顿区的道路几乎为横平竖直的 井字形道路。当出租车司机预估从 A街口 到达 B街口 所需要的距离时,就可以采用上述方式来预估出距离。
所以曼哈顿距离又被称为
出租车距离
。曼哈顿距离的定义,实际上是为了在现实生活中帮我们快速计算某些距离的一种简化方式。
Vector3的方法
假设法线具有单位长度(也就是说法线长度不能为 0)
以 x 为例 若 x < 0 则 x = 0,若 x > 0 则 x = Math.floor(x),y 也类似
this.x = radius Math.sin(theta)、this.y = y、
this.z = radius Math.cos(theta)
正规矩阵(normal matrix):
与自己的共轭转置矩阵对应的复系数方块矩阵。
线性插值(linear interpolation):
线性插值的意思即表示 2 点之间的直线上,计算点的位置公式。
假设 2 点构成了一个抛物线,有专门计算该抛物线上点位置公式,而线性插值是指将 2 点之间连接直线,求该直线上的点位置公式。
Vector4的方法
所谓矩阵变换实际上也是两个矩阵相乘。
若 s 的值为 0,则当前向量会被设置为 (0,0,0,0)
例如 this.x *= v.x,这与 .applyMatrix() 中 “与四阶矩阵相乘” 是不同的。
旋转
在 3D 空间中,物体的变换有以下几种:
执行顺序:
对于位移和缩放是不需要考虑执行顺序的,例如我们要对一个长方体进行缩放或平移,无论先操作 x 还是 y 都不影响最终结果。
但是对于旋转而言却不是这样的,旋转操作需要严格设定好执行的先后顺序。
假设有一个打乱的魔方,若执行下面的 2 种操作:
以上 2 种操作 向上或向左 的执行顺序不同,可以想象,最终魔方呈现的结果也是不一样的。
对于物体的旋转而言,方向执行的先后顺序不同,其旋转后的结果状态也会不同。
绕轴旋转:
假设我们说绕某轴旋转,实际情况就是对应这个轴的坐标不会发生变化,变化的是另外两个轴。
顺指针与逆时针:
在二维旋转中,默认我们将 逆时针旋转为正,顺时针旋转为负。
但是在三维旋转中,是不存在 顺时针 或 逆时针 旋转这个概念的。
右手螺旋法则:
虽然三维空间中并不存在 顺时针和逆时针的概念,但是对于某一个轴旋转,依然是有正旋转和负旋转之分的。
判定旋转是正还是负,靠右手螺旋法则来界定。
假设我们现在要绕 x 轴旋转,那么右手螺旋法则的界定方式为:
飞机旋转的行业术语:
你可以想象一下现在有一个正在平稳飞行中的飞机。
机身左右平移被称为:偏航(yaw)
机身左右旋转被称为:滚转(roll)
机头机尾上下变化被称为:仰俯(pitch)
如何描述旋转?
在 3D 空间中,一共有 3 种数学方式可以描述和记录旋转。
矩阵稍后再讲,本小节只谈论 欧拉角与四元数。
欧拉角(euler)
欧拉角是由数学家 欧拉 发明的,所以叫 欧拉角。
欧拉角 通过定义 x y z 3 个轴的旋转角度来描述一个旋转变化。
但是由于 x y z 旋转的依次顺序不同,其结果也不同,所以在 Three.js 中的 欧拉角 Euler 类 还增加了第 4 个属性:order,即表示旋转顺序,默认值为 “XYZ”。
记录欧拉角的 3 个值:
由于 order 的默认值为 “XYZ”,所以日常使用中我们可以忽略这个属性值,而只记录 x y z 这 3 个属性值。
欧拉角的缺点:
欧拉角的 3 个值 x y z 执行顺序必须相对固定,若执行顺序不同其结果也不同。
这个现象被称为 “万向节死锁”。
欧拉角比较难易 “计算” ,比如一个物体由当前旋转状态变换为另外一种旋转状态,实际上会有多种 变换方式 都可以达到目的,也就是无法使用 唯一的一种变换来描述,增加变换的复杂性。
同一个欧拉角的 x y z 的值可以是不同的数字,因此很难 “倒推还原” 之前的状态和预期目标状态。
欧拉角的优点:
四元数(quaternion)
四元数是由数学家 哈密顿 发明的数学概念,四元数解决了 欧拉角 的一些缺点问题。
四元数,顾名思义,使用 4 个数字 x y z w 来描述一个旋转变换。
四元数实际上是使用简化版的 四维空间 来解决 三维空间中的旋转变换。
四元数的优点:
四元数的缺点:
欧拉角(Euler)的属性和方法
由 X、Y、Z 共有 6 种组合方式:
因此 .order 的值应该是以上 6 种中的一种。
将当前欧拉角的 order 设置为参数中的 order。order 为可选参数
四元数(quaternion)的属性和方法
所谓旋转共轭就是指围绕旋转轴做反方向的旋转。
你需要把四元数理解成四维空间中的一个向量
请注意这个与 .multiply() 相乘的顺序是相反的,而相乘顺序不同其结果也不同。
假定 axis 已经被归一化
静态方法:.slerpFlat()
.slerpFlat ( dst : Array, dstOffset : Integer, src0 : Array, srcOffset0 : Integer, src1 : Array, srcOffset1 : Integer, t : Float ) : null
类似于四元数实例的 .slerp() 方法,但直接对平面数组进行操作。
矩阵(matrix)
关于矩阵的相关概念不再过多叙述。
矩阵的几个结论:
三维矩阵(Matrix3)的属性和方法
三阶矩阵和三维矩阵只是称呼不同,都是表示 3 x 3 矩阵。
矩阵元素排列顺序
补充说明:
.element 的默认值为:
假设我们现在更改一下 三维矩阵的元素值:
从上面输出可以清晰看到,.element 输出的数组是按照 列优先 的方式排列的。
你不能对行或列为0的矩阵进行翻转,如果尝试这样做,该方法将生成一个零矩阵。
该方法内部执行的内容为:
先从参数 m 左上角获得 3 x 3 的矩阵 m3,然后再将 m3 依次进行转逆、转置。
也就是相当于刚 new Matrix3() 时得到的矩阵。
行列式:
请注意,行列式和我们之前提到的 行阵列、列阵列 完全不是一个意思。
行列式取值为一个标量,也就是一个具体的数字。
行列式可以看做是有向面积或体积的概念在一般的欧几里得空间中的推广。
或者说在 N 维欧几里得空间中,行列式描述的是一个线性变换对 “体积” 造成的影响。
基向量
在线性代数(linear algebra)中,基(basis) 是描述刻画向量空间的基本工具。
向量空间的基是它的一个特殊子集,基的元素称为基向量。
四维矩阵的重要意义
四维矩阵是用来解决 3D 空间中所有的矩阵变换(平移、旋转、剪切、缩放、反射、正交、透视投影等)。
四维矩阵的重要程度无与伦比。
所有 Object3D 对象都有的 3 个四维矩阵:
Object3D.matrix:存储物体的本地变换矩阵。这里的 “本地” 是相对父级对象而言。
Object3D.matrixWorld:对象的全局或世界变换矩阵。如果对象没有父级则 .matrixWorld 等于 .matrix。
Object3D.modelViewMatrix:对象相对于相机坐标系的变换矩阵。.modelViewMatrix 是物体世界变换矩阵乘以摄像机相对于世界空间变换矩阵的逆矩阵。
注意,Object3D.normalMatrix 并不是一个四维矩阵,而是一个三维矩阵。
所有相机 Camera 都有的 3 个四维矩阵:
提取位置(平移)、旋转和缩放
有多种选项可用于从 Matrix4 中提取位置、旋转和缩放。
四维矩阵(Matrix4)的属性和方法
也就是说修改当前矩阵的旋转分量。
请注意矩阵的 .lookAt() 和 相机(Camera)的 .lookAt() 参数和含义均不相同。
并将当前矩阵设置为该透视投影矩阵。
并将当前矩阵设置为该正交投影矩阵。
由于 euler 的 .order 可能存在 6 种顺序,所以该矩阵也共有 6 种可能的结果。
会修改当前矩阵
会修改当前矩阵
相当于第1列的元素都乘以 v.x,第2列的元素都乘以 v.y,第3列的元素都乘以 v.z,第4列保持不变。
尽管参数是一个 Vector3,但是在这里可以把它(.x,.y,.z)看做是 3 个列的缩放分量
也就是 第4 列前 3 个元素的值
也就是 第4 列前 3 个元素的值
射线(Ray)
射线的作用:
射线是由一个原点向一个确定的方向发射的线。在 Three.js 中射线主要用于 Raycaster(光线投射) 中,用于在 3D 空间中拾取物体。
这里说的 “拾取物体” 实际上就是鼠标点击选中物体。
射线(Ray)的属性和方法
射线的绝大多数方法都是针对以上 2 个属性进行操作的。
this.origin.applyMatrix4(matrix4)、
this.direction.transformDirection(matrix4)
若 optionalPointOnRay 有值则将接收射线上距离线段最近的点、
若 optionalPointOnSegment 有值则将接收线段上距离射线最近的点。
若不相交则返回 null。
若相交且 target 有值则将相交点赋值给 target。
若不相交则返回 null。
若相交且 target 有值则将相交点赋值给 target。
若不相交则返回 null。
若相交且 target 有值则将相交点赋值给 target。
若不相交则返回 null。
参数 backfaceCulling 表示是否使用背面剔除。
若相交且 target 有值则将相交点赋值给 target。
轴对齐包围盒(Box2/Box3)
包围盒的定义:
包围盒顾名思义,就是用一个体积更大的 “盒子” 包围住物体,当我们需要对物体进行碰撞检测时通过对该包围盒的碰撞检测来 “大约” 作出判断结果。
包围盒碰撞检测主要作用是通过牺牲掉一些精准度来减少碰撞检测计算量。
常见的包围盒算法:
AABB包围盒(Axis-aligned bounding box)
包围球(sphere)
方向包围盒OBB(oriented bounding box)
固定方向凸包FDH(Fixed directions hulls 或 k-DOP)
在本小节中提到的 Box2、Box3 均属于 AABB包围盒,也就是轴对齐包围盒。
二维轴对齐包围盒(Box2)的属性和方法
默认值为 ( + Infinity, + Infinity )
默认值为( - Infinity, - Infinity )
空包围盒
按照道理,包围盒的上边界数值应该大于下边界,但是如果情况相反,那么我们就认定该包围盒虽然存在但是一个空的包围盒,也就是说该包围盒内部包含任何顶点。
若参数 point 本身就在包围盒内部则包围盒不做任何修改,也就是说包围盒只会扩大,不会收窄。
若 scalar 为正数则相当于扩展,若 scalar 为负数则相当于收缩。
由于 vector 的 x y 都有可能为负数,所以该操作也可能会收缩当前包围盒。
例如 x 维度比例为:( point.x - this.min.x ) / ( this.max.x - this.min.x )
请注意该方法并不会去判断 2 个盒子是否真的相交。
该方法只是将 “相交盒子” 上线设置为两者上线中较小者、下限设置为两者下限中的较大者。
也就是说即使两个盒子本身不相交,但是也会返回一个盒子,且该盒子的 .min 和 .max 均有值,只不过该盒子会被视为空盒子。
参数 points 为数组,数组元素均为 Vector2。
实际上就是可以包围这 2 个包围盒的包围盒。
三维轴对齐包围盒(Box3)的属性和方法
实际上是将该包围盒的 8 个顶点( 8 个 vector3) 依次都执行 Vecotr3.applyMatrix4(matrix)
该方法可能会导致一个比严格需要的更大的框。
如果 point 本身就在当前包围盒内,并不会缩小当前包围盒
例如 x 维度比例为:( point.x - this.min.x ) / ( this.max.x - this.min.x )
若当前为空包围盒则返回 (0,0,0)
如果两个包围盒不相交,则清空当前包围盒。
注意,若下边界等于上边界,此时的包围盒仅为 1 个点,并不会判定当前包围盒为空,会返回 false。
设置当前包围盒的边界,确保可以包裹住 array 中每 3 个元素为一组所代表的 点。
请注意 .expandByObject(object) 是将当前包围盒扩展到可以包裹住 object,而 .setFromObject(object) 是将当前包围盒设置为 object 的包围盒。
首先清空当前包围盒,然后设置当前包围盒的上下边界,确保可以包裹住 points 中所有的点。
准确来讲和 .setFromObject() 方法类似,并不是扩展,而是匹配。
平面(Plane)
平面的定义:
在三维空间中无限延伸的二维平面。
平面方程用 “单位长度(归一化)的法向量” 和 “常数” 表示 海塞法向量( Hessian normal form )形式。
平面方程:
平面方程是指空间中所有处于同一平面的点所对应的方程。
一般形式为 :Ax + By + Cz + D = 0
但是该公式有一种特殊情况,即 海塞法向量。
海塞法向量:
法线形式
是一种当直线或平面的 法向量 已知时,使用向量方程
描述直线或者平面的另一种表示形式。平面的任何点都可以通过平面的法向量和该点到该平面的已知点的矢量差的点积来描述。
此点积必须为零。
一种特殊的形式是
海塞法向量(Hessian normal form)
,其中法向量被归一化到值为 1。海塞法向量的结论是:
任何一点 到平面的距离都可以简单表示为 D =n0 x0 + d
以上能理解多少算多少,但是请记住上述文字中提到的 “单位长度(归一化)的法向量” 和 “常数” 。
平面(Plane)的属性和方法
补充说明:
你可以脑补一下这个画面,来看一下一个平面是如何被确定(规定)的:
以原点为球心,半径为 constant 的球
当我们知道这个球表面某个点的平面法向量 normal 后,就可以反向计算出该点的位置
沿球心到这个点可以产生一个向量,继而得到垂直于该向量的平面
我们再回过头看一下关于平面的定义:
在三维空间中无限延展的二维平面
该平面由 海塞法向量 定义
海塞法向量由 “一个归一化的法向量” 和 一个“常数” 构成
是不是就更加容易理解了。
optionalNormalMatrix 为可选参数,
如果提供则使用该参数,
如果不提供则内部自己根据 matrix 计算得出:_normalMatrix.getNormalMatrix( matrix )
该共面点会写入到参数 target 中。
补充:这个共面点实际上就是在上面提到的 “这个球表面某个点”
若不相交则返回 null,
若 line 与当前平面共面(线段在当前平面里),则返回该线段的起始点。
这样相当于把当前平面变为 “以球为介质” 的对面的平面
实际上 .normal 本身就应该是被归一化的,这里是假设 .normal 存在未被归一化的情况。
如果当前本身 .normal 就已经是被归一化的,那么执行该方法后不会有任何变化,同时 constant 也不会有任何变化。
参数中的 x y z 为设置法向量 的 x y z 值,
参数中 w 为设置常量 .constant 的值
如果三个点在一条直线上,即这 3 个点无法构成一个平面,则将抛出错误。
通过右手螺旋法则来确定(向量叉乘)平面的 法向量 normal。
注意这只会影响平面的常量,不会影响平面的法向量。
球(Sphere)
一个球是由球心和半径所定义的。
球(Sphere)的属性和方法
在内部实际上发生的矩阵变化为:
1、球心根据 matrix 进行位移
2、半径根据 matrix 进行缩放
1、若参数 point 位于球内或表面,则不做任何修改直接返回 point。
2、若参数 point 位于球外,则返回最接近 point 的球表面的那个点。
实际上就是判断一下球心到 point 的距离是否大于球的半径
若该点位于球内则距离将为负数。
若该点位于球内则当前球不会发生任何变化。
若当前球为空,那么返回的也是一个空的包围盒。
实际上就是计算一下这两个球心距离是否大于这两个球半径相加之和。
如果第二个参数 optionalCenter 有值则使用该值作为球的中心点。
如果没有第二个参数 则通过 points 计算出它们的中心点。
球的半径是不会发生变化的。
球坐标(Spherical)
球坐标的定义:
球坐标也被称为 球面坐标。
笛卡尔直角坐标系是由相互垂直的 3 个轴线 x y z 构成。
而球坐标系则是发生在一个 “球体” 上的坐标系。
二维球坐标:
假设有一个半径为 r 的圆圈,当我们想描述该圆圈上的某个点的位置时,我们只需知道该点与圆形的连线 与 水平方向的夹角 θ 是多少,就可以通过计算出该点的位置。
也就是说,我们可以使用 (r, θ) 这两个数字来描述一个点的位置信息。
那么这种方式就算是 二维球坐标。
按照这种逻辑,我们可以延展到三维球坐标系。
也就是说需要在 r 和 θ 基础上再增加一个维度的数值。
三维球坐标的3个构成元素:
因此可以通过使用 (r, φ, θ) 来表示球极坐标,如同使用 (x,y,z) 来表达笛卡尔坐标。
但是请记住:在 Three.js Spherical 中 (r, φ, θ) 分别对应 3 个属性:
你可能一时无法理解上面的定义方式,那么可以做下面的脑补画面,有助于理解。
球坐标的脑补画面:
假设现在有一个半径为 r 的大球体
这个球体有一半(下半截)被埋在土地里
此时你直立站在球体内部中心位置,且你有一双透视眼,可以透过土地看到被埋在地下的球体
你可以左右 360 度转身,让自己面部朝向不同的水平方向
你头部还可以上下俯仰,比如仰头看天,低头看地,你头部的俯仰范围只能在 0 - 180 度之间
那么通过不断转身 和 头部的俯仰变化,你的目光就可以看到这个这个球体所有的内部表面位置
在上面这个场景中,有 3 个元素:
球体的半径 r
你头部仰俯的角度 φ,取值范围 0 - 180度
你水平转身的角度 θ,取值范围 0 - 360度
也就是说通过 r 、φ(.phi 极角、仰角)、θ(.theta 方位角) 三个数值即可表示出球体内部(表面)的某个位置。
关于取值范围的约定:
在数学中,1/2 、4/8、16/32 它们的值是相同的,但是在现实生活中,当我们想要表达数量的 “一半” 时,我们会使用 1/2,而不是 4/8、16/32。
因为 1/2 足够简单明了,这是我们约定、首选的方案。
同样的道理,对于角度而言,30度和 390度 他们实际上是相同的。
但是我们会约定、首选使用 30度 而不是 390度。
所以对于球坐标而言,在 Three.js 中约定:
这些约定都是人为的,例如在有的球坐标系中会约定:
还有,在 Three.js 中球坐标约定的是 (r, φ, θ),但是在别的系统中可能写成 (r, θ, φ)。
球坐标与笛卡尔坐标之间的互相转换:
具体数学公式就不罗列了。
球坐标系提供有一个 .setFromCartesianCoords() 的方法可以将笛卡尔坐标转化为球坐标。
例如轨道控制器 OrbitControls 就使用到球坐标,让相机绕着被观察的物体 按照球体轨迹 切换视角。
补充说明:
对于计算机而言更容易理解 笛卡尔直角系坐标,但是对于我们人类而言更容易理解和使用 球坐标。
例如:
当我们描述某个建筑位置时,我们可能会说:东南角 200 米
在射击场景中,我们会告知队友:你的 3 点钟 方向有敌人
球坐标(Spherical)的属性和方法
请注意并不是将 this.radius 直接设置为 vec3.x,在内部执行的是 .setFromCartesianCoords( vec3.x, vec3.y, vec3.z )
圆柱坐标(Cylindrical)
圆柱坐标的定义:
在上一节中,我们提到了 二维球坐标,二维球坐标实际上就是一个平面圆对应的相关坐标。
那么我们只需要给这个平面圆增加一个 高度(厚度),就会由一个平面圆变为一个圆柱体。
这就是圆柱坐标的由来。
圆柱坐标(Cylindrical)的属性和方法
三角形(Triangle)
一个三角形是由 3 个 三维点坐标(Vector3) 所定义的。
三角形(Triangle)的属性和方法
若参数 point 本身位于三角形内部则不作任何修改直接返回 point。
若三角形仅为一个点(不是一个正常的三角形),则返回 (0,0,0)
这里说的 平面是指 3D 空间中无限延展的 平面。
设置当前三角形的三个角依次为:
this.a 的值为 points[i0]
this.b 的值为 points[i1]
this.c 的值为 points[i2]
三角形的各种 心:
视椎体(Frustum)
视椎体的定义:
视椎体也被称为 平接头体。
由 上下左右前后 共 6 个面构成。
在 Three.js 中视椎体主要应用于镜头的视野:透视相机和正交相机
视椎体 6 个面的顺序说明:
在我们初始化并设置一个正交相机时 平面是有明确的顺序的。
但是对于视椎体本身而言 6 个面的顺序是无所谓的。
就好像我们描述一个三角形时,三角形的三个角的顺序发生变化并不影响这个三角形的形状。
视椎体(Frustum)的属性和方法
在内部实际上是创建一个中心点位于 (0,0),
半径为 0.5 的平方根 也就是 0.7071067811865476 ,
然后再将该球体使用 精灵 sprite 的世界变化矩阵,
最终将得到的球体与当前视椎进行相交检测。
插值器(Interpolant)
插值器的定义:
插值器不是某种几何图形,而是一种用于表达曲线上某种时间或路径间隔的抽象基类。
由于是抽象类,所以该类的一些属性都是需要用户自己去设定的。
插值器(Interpolant)的属性和方法
颜色(Color)
请注意,颜色 是一种色彩数学对象模型,这与本文上面所将的 线性代数变换、坐标、几何图形等全部不属于同一类。
颜色 Color 初始化时合法的颜色值:
请注意颜色本身不包含透明度信息。
颜色(Color)的属性和方法
也就是说 this.r += color.r,g 和 b 同样也这样操作
参数 gammaFactor 为可选参数,默认值为 2。
参数 gammaFactor 为可选参数,默认值为 2。
offset 默认值为 0
例如 "ffffff" ,请注意是小写字母
会把该对象赋值给 target。
例如:"rgb(255,0,0)"
若 alpha 为 0 则当前颜色不变。
若 alpha 为 1 则当前颜色变为参数 color。
请注意在内部计算时的方法不同于 .lerp()
其中 h s l 取值范围均为 0 - 1
其中 h s l 取值范围均为 0 - 1
其中参数 r g b 取值范围均为 0 - 1
请注意颜色字符串字母是不区分大小写的。
若分量减去后结果为负数 则将该分量值设置为 0
参数 offset 默认值为 0
圆柱体球谐函数3(SphericalHarmonics3)
这个类也是 Three.js 数据库中的一个类,只不过目前实在不太明白,也暂时用不到该类,所以暂时不做学习。
通用数学函数(MathUtils)类
Three.js 给我们提供了一个 通用数学函数 的工具类。
该类名字为 MathUtils,没有属性,为我们提供了大量的 静态数学函数。
你可以把 MathUtils 看作是对 JS 内置的 Math 的补充。
若 t 为 0 则返回 x,若 t 为 1 则返回 y。