Files
Nitro_Render_V3/packages/utils/src/Vector3d.ts
T
2024-04-03 09:27:56 +02:00

216 lines
4.9 KiB
TypeScript

import { IVector3D } from '@nitrots/api';
export class Vector3d implements IVector3D
{
private _length: number = NaN;
constructor(
private _x: number = 0,
private _y: number = 0,
private _z: number = 0)
{}
public static sum(vector1: IVector3D, vector2: IVector3D): Vector3d
{
if(!vector1 || !vector2) return null;
return new Vector3d((vector1.x + vector2.x), (vector1.y + vector2.y), (vector1.z + vector2.z));
}
public static dif(vector1: IVector3D, vector2: IVector3D): Vector3d
{
if(!vector1 || !vector2) return null;
return new Vector3d((vector1.x - vector2.x), (vector1.y - vector2.y), (vector1.z - vector2.z));
}
public static product(vector: IVector3D, value: number): Vector3d
{
if(!vector) return null;
return new Vector3d((vector.x * value), (vector.y * value), (vector.z * value));
}
public static dotProduct(vector1: IVector3D, vector2: IVector3D): number
{
if(!vector1 || !vector2) return 0;
return (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z);
}
public static crossProduct(vector1: IVector3D, vector2: IVector3D): Vector3d
{
if(!vector1 || !vector2) return null;
const product = new Vector3d();
product.x = ((vector1.y * vector2.z) - (vector1.z * vector2.y));
product.y = ((vector1.z * vector2.x) - (vector1.x * vector2.z));
product.z = ((vector1.x * vector2.y) - (vector1.y * vector2.x));
return product;
}
public static scalarProjection(vector1: IVector3D, vector2: IVector3D): number
{
if(!vector1 || !vector2) return -1;
const length = vector2.length;
if(length > 0)
{
return ((vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z)) / length;
}
return -1;
}
public static cosAngle(vector1: IVector3D, vector2: IVector3D): number
{
if(!vector1 || !vector2) return 0;
const totalLength = (vector1.length * vector2.length);
if(!totalLength) return 0;
return (Vector3d.dotProduct(vector1, vector2) / totalLength);
}
public static isEqual(vector1: IVector3D, vector2: IVector3D): boolean
{
if(!vector1 || !vector2) return false;
if((vector1.x !== vector2.x) || (vector1.y !== vector2.y) || (vector1.z !== vector2.z)) return false;
return true;
}
public assign(vector: IVector3D): void
{
if(!vector) return;
this._x = vector.x;
this._y = vector.y;
this._z = vector.z;
this._length = NaN;
}
public add(vector: IVector3D): void
{
if(!vector) return;
this._x += vector.x;
this._y += vector.y;
this._z += vector.z;
this._length = NaN;
}
public subtract(vector: IVector3D): void
{
if(!vector) return;
this._x -= vector.x;
this._y -= vector.y;
this._z -= vector.z;
this._length = NaN;
}
public multiply(amount: number): void
{
this._x *= amount;
this._y *= amount;
this._z *= amount;
this._length = NaN;
}
public divide(amount: number): void
{
if(!amount) return;
this._x /= amount;
this._y /= amount;
this._z /= amount;
this._length = NaN;
}
public negate(): void
{
this._x = -(this._x);
this._y = -(this._y);
this._z = -(this._z);
}
public dotProduct(vector: IVector3D): number
{
return ((this._x * vector.x) + (this._y * vector.y)) + (this._z * vector.z);
}
public crossProduct(vector: IVector3D): IVector3D
{
const newVector = new Vector3d();
newVector.x = ((this._y * vector.z) - (this._z * vector.y));
newVector.y = ((this._z * vector.x) - (this._x * vector.z));
newVector.z = ((this._x * vector.y) - (this._y * vector.x));
return newVector;
}
public normalize(): void
{
const k = (1 / this.length);
this._x = (this._x * k);
this._y = (this._y * k);
this._z = (this._z * k);
}
public get x(): number
{
return this._x;
}
public set x(k: number)
{
this._x = k;
this._length = NaN;
}
public get y(): number
{
return this._y;
}
public set y(k: number)
{
this._y = k;
this._length = NaN;
}
public get z(): number
{
return this._z;
}
public set z(k: number)
{
this._z = k;
this._length = NaN;
}
public get length(): number
{
if(isNaN(this._length))
{
this._length = Math.sqrt(((this._x * this._x) + (this._y * this._y)) + (this._z * this._z));
}
return this._length;
}
public toString(): string
{
return `[Vector3d: ${this._x}, ${this._y}, ${this._z}]`;
}
}