3D向量类
支持的能力
- 存取向量的各分量(x)
- 向量间的赋值操作
- 比较两向量是否相同
- 将向量置为零向量
- 向量求负
- 求向量的模
- 向量与标量的乘除法
- 向量标准化
- 向量加减法
- 计算两点(点用向量表示)间距离
- 向量点乘
- 向量叉乘
示例
ts
export class Vector3 {
x: number;
y: number;
z: number;
// 最好不要做缺省处理,如果偏好缺省处理,最好是初始化为零向量
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = z;
}
// 比较两向量是否相同
isEqual(vector: Vector3): boolean {
return vector.x === this.x && vector.y === this.y && vector.z === this.z;
}
// 将向量置为零向量
zero() {
this.x = 0;
this.y = 0;
this.z = 0;
}
// 向量加法
plus(vector: Vector3): Vector3 {
return new Vector3(this.x + vector.x, this.y + vector.y, this.z + vector.z);
}
// 向量减法
subtract(vector: Vector3): Vector3 {
return new Vector3(this.x - vector.x, this.y - vector.y, this.z - vector.z);
}
// 向量与标量的乘积 和 点乘(向量与向量的乘积)
multiply(factor: number | Vector3): number | Vector3 {
if (factor instanceof Vector3) {
// 向量点乘
return this.x * factor.x + this.y * factor.y + this.z * factor.z;
} else {
// 向量与标量相乘
return new Vector3(factor * this.x, factor * this.y, factor * this.z);
}
}
// 向量与标量的除法
division(factor: number): Vector3 {
return new Vector3(this.x / factor, this.y / factor, this.z / factor);
}
// 取向量的模
vectorMag(): number {
return Math.sqrt(this.x ** 2 + this.y ** 2 + this.z ** 2);
}
// 向量标准化
normalize(): Vector3 {
const length = this.vectorMag();
return new Vector3(this.x / length, this.y / length, this.z / length);
}
}
export class Vector3Helper {
private constructor() {}
// 两向量的叉乘
static crossProduct(vector: Vector3, vector1: Vector3): Vector3 {
return new Vector3(
vector.y * vector1.z - vector.z * vector1.y,
vector.z * vector1.x - vector.x * vector1.z,
vector.x * vector1.y - vector.y * vector1.x,
);
}
// 两向量之间的距离
static distance(vector: Vector3, vector1: Vector3): number {
return vector.subtract(vector1).vectorMag();
}
}
优化建议
对于频繁创建/销毁对象场景,可以通过维护对象池减少频繁创建/销毁对象的开销。基本思想是:
- 需要创建对象时,从对象池去取
- 使用完对象后,放回对象池
但是维护对象池会面临许多问题:
- 其他代码段一直保持这对象池中对象的引用,导致无法GC
- 对象池中的对象状态可能会在使用过程中改变