diff --git a/src/Vec2.ts b/src/Vec2.ts index 52bd055..1c0c33a 100644 --- a/src/Vec2.ts +++ b/src/Vec2.ts @@ -1,7 +1,8 @@ import { Vector2, Direction, VectorXZ } from "@minecraft/server"; import { Logger } from "./Logging"; +import Vec3 from "./Vec3"; -type VectorLike = VectorXZ | Vector2 | Vec2 | Direction | number[] | number +type VectorLike = VectorXZ | Vector2 | Vec2 | Vec3 | Direction | number[] | number export default class Vec2 implements Vector2 { private static readonly log = Logger.getLogger("vec2", "vec2", "bedrock-boost"); @@ -15,6 +16,7 @@ export default class Vec2 implements Vector2 { readonly y: number; constructor(x: number, y: number); constructor(x: Vec2); + constructor(x: Vec3); constructor(x: Vector2); constructor(x: Direction); constructor(x: number[]); @@ -43,6 +45,9 @@ export default class Vec2 implements Vector2 { } else if (x instanceof Vec2) { this.x = x.x; this.y = x.y; + } else if (x instanceof Vec3) { + this.x = x.x; + this.y = x.y; } else { const anyX = x as any; if (!anyX || (!anyX.x && anyX.x !== 0) || ((!anyX.y && anyX.y !== 0) && (!anyX.z && anyX.z !== 0))) { @@ -66,12 +71,14 @@ export default class Vec2 implements Vector2 { */ static from(x: number, y: number): Vec2; static from(x: Vec2): Vec2; + static from(x: Vec3): Vec2; static from(x: Vector2): Vec2; static from(x: VectorXZ): Vec2; static from(x: Direction): Vec2; static from(x: number[]): Vec2; static from(x: VectorLike, y?: number): Vec2 { if (x instanceof Vec2) return x; + if (x instanceof Vec3) return if (typeof x === 'number' && y !== undefined) { return new Vec2(x, y); } @@ -401,6 +408,45 @@ export default class Vec2 implements Vector2 { const proj = this.projectOnto(normal); return this.subtract(proj.multiply(2)); } + /** + * Rotates the current normalized vector by a given angle around a given axis. + * + * @param axis - The axis of rotation. + * @param angle - The angle of rotation in degrees. + * @returns The rotated vector. + */ + rotate(axis: Vector2, angle: number): Vec2 { + // Convert angle from degrees to radians + const radians = angle * (Math.PI / 180); + + // Translate the vector to the origin relative to the pivot (axis) + let translatedX = this.x - axis.x; + let translatedY = this.y - axis.y; + + // Use complex number rotation (Euler's formula) + // New x = x * cos(radians) - y * sin(radians) + // New y = x * sin(radians) + y * cos(radians) + const cos = Math.cos(radians); + const sin = Math.sin(radians); + + const rotatedX = translatedX * cos - translatedY * sin; + const rotatedY = translatedX * sin + translatedY * cos; + + // Translate the rotated vector back relative to the pivot (axis) and return it + return new Vec2( + rotatedX + axis.x, + rotatedY + axis.y + ); + } + /** + * Converts the current vector to a 3d vetor with the given y-value. + * + * @param z - The optional z value for the 3d vetor. + * @returns The converted vector. + */ + toVec3(z?: number): Vec3 { + return new Vec3(this.x, this.y, z || 0); + } /** * Sets the X component of the vector. * diff --git a/src/Vec3.ts b/src/Vec3.ts index a2b36e6..5092464 100644 --- a/src/Vec3.ts +++ b/src/Vec3.ts @@ -1,7 +1,8 @@ import { Vector3, Direction, Vector2 } from "@minecraft/server"; import { Logger } from "./Logging"; +import Vec2 from "./Vec2"; -type VectorLike = Vector3 | Vec3 | Direction | number[] | number +type VectorLike = Vector3 | Vec3 | Vec2 | Direction | number[] | number export default class Vec3 implements Vector3 { private static readonly log = Logger.getLogger("vec3", "vec3", "bedrock-boost"); @@ -18,6 +19,7 @@ export default class Vec3 implements Vector3 { readonly z: number; constructor(x: number, y: number, z: number); constructor(x: Vec3); + constructor(x: Vec2, z?: number); constructor(x: Vector3); constructor(x: Direction); constructor(x: number[]); @@ -58,7 +60,11 @@ export default class Vec3 implements Vector3 { this.x = x.x; this.y = x.y; this.z = x.z; - } else { + } else if (x instanceof Vec2) { + this.x = x.x; + this.y = x.y; + this.z = z || 0; + }else { if (!x || (!x.x && x.x !== 0) || (!x.y && x.y !== 0) || (!x.z && x.z !== 0)) { Vec3.log.error(new Error("Invalid vector"), x); throw new Error("Invalid vector"); @@ -74,11 +80,13 @@ export default class Vec3 implements Vector3 { */ static from(x: number, y: number, z: number): Vec3; static from(x: Vec3): Vec3; + static from(x: Vec2, z?: number): Vec3; static from(x: Vector3): Vec3; static from(x: Direction): Vec3; static from(x: number[]): Vec3; static from(x: VectorLike, y?: number, z?: number): Vec3 { if (x instanceof Vec3) return x; + if (x instanceof Vec2) return x.toVec3(z || 0); if (typeof x === 'number' && y !== undefined && z !== undefined) { return new Vec3(x, y, z); } @@ -125,6 +133,14 @@ export default class Vec3 implements Vector3 { copy(): Vec3 { return new Vec3(this.x, this.y, this.z); } + /** + * Converts the current vector to a 2d vetor. + * + * @returns The converted vector. + */ + toVec2(): Vec2 { + return new Vec2(this.x, this.z); + } /** * Creates a new direction vector from yaw and pitch values. *