向量
向量(Vector)是游戏开发中最基础的数学工具,用于表示位置、方向、速度等。LayaAir引擎提供了 Vector2、Vector3、Vector4 三种向量类,分别位于 laya/maths/ 下。
一、Vector2(二维向量)
Section titled “一、Vector2(二维向量)”Vector2 表示2D空间中的点或方向,包含 x、y 两个分量。
1.1 创建与常量
Section titled “1.1 创建与常量”let v = new Laya.Vector2(3, 4);
// 预定义常量(只读,禁止修改)Laya.Vector2.ZERO; // (0, 0)Laya.Vector2.ONE; // (1, 1)1.2 常用方法
Section titled “1.2 常用方法”
(图1-1)
let a = new Laya.Vector2(1, 2);let b = new Laya.Vector2(3, 4);let out = new Laya.Vector2();
// 设置值a.setValue(5, 6);
// 缩放Laya.Vector2.scale(a, 2, out); // out = a * 2
// 点积let dot = Laya.Vector2.dot(a, b); // 标量结果
// 归一化(单位向量)Laya.Vector2.normalize(a, out);
// 两点距离let dist = Laya.Vector2.distance(a, b);
// 标量长度let len = Laya.Vector2.scalarLength(a);
// 判断相等let eq = Laya.Vector2.equals(a, b);
// 克隆let c = a.clone();a.cloneTo(out);
// 与数组互转let arr = a.toArray(); // [x, y]a.fromArray([10, 20]);二、Vector3(三维向量)
Section titled “二、Vector3(三维向量)”Vector3 是3D开发中最核心的向量类型,包含 x、y、z 三个分量。
2.1 创建与常量
Section titled “2.1 创建与常量”let v = new Laya.Vector3(1, 2, 3);
// 预定义常量(只读)Laya.Vector3.ZERO; // (0, 0, 0)Laya.Vector3.ONE; // (1, 1, 1)Laya.Vector3.Up; // (0, 1, 0)Laya.Vector3.UnitX; // (1, 0, 0)Laya.Vector3.UnitY; // (0, 1, 0)Laya.Vector3.UnitZ; // (0, 0, 1)Laya.Vector3.ForwardRH; // (0, 0, -1) 右手坐标系前方Laya.Vector3.ForwardLH; // (0, 0, 1) 左手坐标系前方2.2 基本运算
Section titled “2.2 基本运算”let a = new Laya.Vector3(1, 2, 3);let b = new Laya.Vector3(4, 5, 6);let out = new Laya.Vector3();
Laya.Vector3.add(a, b, out); // 加法Laya.Vector3.subtract(a, b, out); // 减法Laya.Vector3.multiply(a, b, out); // 分量相乘Laya.Vector3.scale(a, 2, out); // 缩放Laya.Vector3.normalize(a, out); // 归一化
let dot = Laya.Vector3.dot(a, b); // 点积Laya.Vector3.cross(a, b, out); // 叉积
let dist = Laya.Vector3.distance(a, b); // 距离let distSq = Laya.Vector3.distanceSquared(a, b); // 距离平方(避免开方,用于比较)let len = Laya.Vector3.scalarLength(a); // 标量长度
// 实例方法a.set(10, 20, 30);let l = a.length();let lsq = a.lengthSquared();a.normalize();let d = a.dot(b);a.cross(b, out);a.vadd(b, out); // 实例加法a.vsub(b, out); // 实例减法a.scale(2, out); // 实例缩放2.3 插值
Section titled “2.3 插值”let start = new Laya.Vector3(0, 0, 0);let end = new Laya.Vector3(10, 10, 10);let out = new Laya.Vector3();
// t 从 0 到 1,实现平滑过渡Laya.Vector3.lerp(start, end, 0.5, out); // out = (5, 5, 5)2.4 范围限制
Section titled “2.4 范围限制”let min = new Laya.Vector3(0, 0, 0);let max = new Laya.Vector3(10, 10, 10);let v = new Laya.Vector3(15, -3, 5);let out = new Laya.Vector3();
Laya.Vector3.Clamp(v, min, max, out); // out = (10, 0, 5)
// 取两向量各分量最小/最大值Laya.Vector3.min(a, b, out);Laya.Vector3.max(a, b, out);2.5 变换
Section titled “2.5 变换”let v = new Laya.Vector3(1, 0, 0);let out = new Laya.Vector3();let out4 = new Laya.Vector4();
// 通过矩阵变换坐标(会做透视除法归一化)Laya.Vector3.transformCoordinate(v, matrix, out);
// 通过矩阵变换为四维向量Laya.Vector3.transformV3ToV4(v, matrix, out4);
// 通过矩阵变换为三维向量Laya.Vector3.transformV3ToV3(v, matrix, out);
// 通过法线矩阵变换法线方向Laya.Vector3.TransformNormal(normal, matrix, out);
// 通过四元数旋转向量Laya.Vector3.transformQuat(v, quaternion, out);三、Vector4(四维向量)
Section titled “三、Vector4(四维向量)”Vector4 包含 x、y、z、w 四个分量,常用于齐次坐标、Shader数据传递。
3.1 创建与常量
Section titled “3.1 创建与常量”let v = new Laya.Vector4(1, 2, 3, 1);
Laya.Vector4.ZERO; // (0, 0, 0, 0)Laya.Vector4.ONE; // (1, 1, 1, 1)Laya.Vector4.UnitX; // (1, 0, 0, 0)Laya.Vector4.UnitY; // (0, 1, 0, 0)Laya.Vector4.UnitZ; // (0, 0, 1, 0)Laya.Vector4.UnitW; // (0, 0, 0, 1)3.2 运算方法
Section titled “3.2 运算方法”let a = new Laya.Vector4(1, 2, 3, 4);let b = new Laya.Vector4(5, 6, 7, 8);let out = new Laya.Vector4();
Laya.Vector4.add(a, b, out);Laya.Vector4.subtract(a, b, out);Laya.Vector4.multiply(a, b, out);Laya.Vector4.scale(a, 2, out);Laya.Vector4.normalize(a, out);Laya.Vector4.lerp(a, b, 0.5, out);
let dot = Laya.Vector4.dot(a, b);let dist = Laya.Vector4.distance(a, b);
// 通过4x4矩阵变换Laya.Vector4.transformByM4x4(v, matrix, out);
// 范围限制Laya.Vector4.Clamp(v, min, max, out);四、实用技巧
Section titled “四、实用技巧”4.1 计算方向向量
Section titled “4.1 计算方向向量”let direction = new Laya.Vector3();Laya.Vector3.subtract(targetPos, currentPos, direction);Laya.Vector3.normalize(direction, direction);4.2 计算两向量夹角
Section titled “4.2 计算两向量夹角”
(图4-1)
let aNorm = new Laya.Vector3();let bNorm = new Laya.Vector3();Laya.Vector3.normalize(a, aNorm);Laya.Vector3.normalize(b, bNorm);let cosAngle = Laya.Vector3.dot(aNorm, bNorm);let angle = Math.acos(cosAngle); // 弧度let degrees = angle * 180 / Math.PI; // 角度4.3 判断物体在前方还是后方
Section titled “4.3 判断物体在前方还是后方”let toTarget = new Laya.Vector3();Laya.Vector3.subtract(targetPos, myPos, toTarget);let dot = Laya.Vector3.dot(forward, toTarget);// dot > 0:前方 | dot < 0:后方 | dot ≈ 0:侧面4.4 计算法线(叉积)
Section titled “4.4 计算法线(叉积)”
(图4-2)
// 由三角形三个顶点计算面法线let edge1 = new Laya.Vector3();let edge2 = new Laya.Vector3();let normal = new Laya.Vector3();Laya.Vector3.subtract(p1, p0, edge1);Laya.Vector3.subtract(p2, p0, edge2);Laya.Vector3.cross(edge1, edge2, normal);Laya.Vector3.normalize(normal, normal);