export class Vector2D { public readonly x: number; public readonly y: number; constructor(x = 0, y = 0) { this.x = x; this.y = y; } public plus(other: Vector2D): Vector2D { return new Vector2D(this.x + other.x, this.y + other.y); } public minus(other: Vector2D): Vector2D { return new Vector2D(this.x - other.x, this.y - other.y); } public scale(other: number): Vector2D { return new Vector2D(this.x * other, this.y * other); } } export class Rectangle { private readonly corner_1: Vector2D; private readonly corner_2: Vector2D; constructor(corner_1?: Vector2D, corner_2?: Vector2D) { this.corner_1 = corner_1 || new Vector2D(); this.corner_2 = corner_2 || new Vector2D(); } public get origin(): Vector2D { return new Vector2D( Math.min(this.corner_1.x, this.corner_2.x), Math.min(this.corner_1.y, this.corner_2.y), ) } public get left(): number { return this.origin.x; } public get top(): number { return this.origin.y; } public get corner(): Vector2D { return new Vector2D( Math.max(this.corner_1.x, this.corner_2.x), Math.max(this.corner_1.y, this.corner_2.y), ) } public get size(): Vector2D { return this.corner.minus(this.origin); } public get width(): number { return this.size.x; } public get height(): number { return this.size.y; } public get area(): number { return this.width * this.height; } public contains(point: Vector2D): boolean { return point.x >= this.origin.x && point.y >= this.origin.y && point.x <= this.corner.x && point.y <= this.corner.y; } public update(corner_1?: Vector2D, corner_2?: Vector2D): Rectangle { return new Rectangle( corner_1 || this.corner_1, corner_2 || this.corner_2, ); } public move(vector: Vector2D): Rectangle { return new Rectangle( this.corner_1.plus(vector), this.corner_2.plus(vector), ); } }