class Vector3 {

    constructor(x, y, z) { this.x = x; this.y = y; this.z = z }
    static Add(pos1, pos2) { return new Vector3(pos1.x + pos2.x, pos1.y + pos2.y, pos1.z + pos2.z) }
    static Subtract(pos1, pos2) { return new Vector3(pos1.x - pos2.x, pos1.y - pos2.y, pos1.z - pos2.z) }
    static Divide(pos1, pos2) { return new Vector3(pos1.x / pos2.x, pos1.y / pos2.y, pos1.z / pos2.z) }
    static Scale(pos1, num) { return new Vector3(pos1.x * num, pos1.y * num, pos1.z * num) }
    static Multiply(pos1, pos2) { return new Vector3(pos1.x * pos2.x, pos1.y * pos2.y, pos1.z * pos2.z) }
    static Equals(pos1, pos2, tolerance = 0) { return tolerance == 0 ? pos1.x == pos2.x && pos1.y == pos2.y && pos1.z == pos2.z : Math.abs(pos1.x - pos2.x) <= tolerance && Math.abs(pos1.y - pos2.y) <= tolerance && Math.abs(pos1.z - pos2.z) <= tolerance }
    static Zero() { return new Vector3(0, 0, 0) }
    static Up() { return new Vector3(0, 1, 0) }
    static Down() { return new Vector3(0, -1, 0) }
    static Forward() { return new Vector3(0, 0, 1) }
    static Back() { return new Vector3(0, 0, -1) }
    static Left() { return new Vector3(-1, 0, 0) }
    static Right() { return new Vector3(1, 0, 0) }
    static Distance(pos1, pos2) { return Math.sqrt((pos2.x - pos1.x) ** 2 + (pos2.y - pos1.y) ** 2 + (pos2.z - pos1.z) ** 2) }
    static Lerp(pos1, pos2, t) { return new Vector3(pos1.x + (pos2.x - pos1.x) * t, pos1.y + (pos2.y - pos1.y) * t, pos1.z + (pos2.z - pos1.z) * t) }
    static Dot(pos1, pos2) { return pos1.x * pos2.x + pos1.y * pos2.y + pos1.z * pos2.z }
    static Cross(pos1, pos2) { return new Vector3(pos1.y * pos2.z - pos1.z * pos2.y, pos1.z * pos2.x - pos1.x * pos2.z, pos1.x * pos2.y - pos1.y * pos2.x) }
    static Magnitude(pos) { return Math.sqrt(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z) }
    static SqrMagnitude(pos) { return pos.x * pos.x + pos.y * pos.y + pos.z * pos.z }
    static SqrDistance(pos1, pos2) { const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y, dz = pos2.z - pos1.z; return dx * dx + dy * dy + dz * dz }
    static Normalize(dir) { const mag = Vector3.Magnitude(dir); return mag !== 0 ? new Vector3(dir.x / mag, dir.y / mag, dir.z / mag) : new Vector3(0, 0, 0) }


}
class Vector2 {
    constructor(x, y) { this.x = x; this.y = y }
    static Add(pos1, pos2) { return new Vector2(pos1.x + pos2.x, pos1.y + pos2.y) }
    static Subtract(pos1, pos2) { return new Vector2(pos1.x - pos2.x, pos1.y - pos2.y) }
    static Divide(pos1, pos2) { return new Vector2(pos1.x / pos2.x, pos1.y / pos2.y) }
    static Scale(pos1, num) { return new Vector2(pos1.x * num, pos1.y * num) }
    static Multiply(pos1, pos2) { return new Vector2(pos1.x * pos2.x, pos1.y * pos2.y) }
    static Equals(pos1, pos2, tolerance = 0) { return tolerance == 0 ? pos1.x == pos2.x && pos1.y == pos2.y : Math.abs(pos1.x - pos2.x) <= tolerance && Math.abs(pos1.y - pos2.y) <= tolerance }
    static Zero() { return new Vector2(0, 0) }
    static One() { return new Vector2(1, 1) }
    static Up() { return new Vector2(0, 1) }
    static Down() { return new Vector2(0, -1) }
    static Left() { return new Vector2(-1, 0) }
    static Right() { return new Vector2(1, 0) }
    static Distance(pos1, pos2) { return Math.sqrt((pos2.x - pos1.x) ** 2 + (pos2.y - pos1.y) ** 2) }
    static Lerp(pos1, pos2, t) { return new Vector2(pos1.x + (pos2.x - pos1.x) * t, pos1.y + (pos2.y - pos1.y) * t) }
    static Dot(pos1, pos2) { return pos1.x * pos2.x + pos1.y * pos2.y }
    static Magnitude(pos) { return Math.sqrt(pos.x * pos.x + pos.y * pos.y) }
    static SqrMagnitude(pos) { return pos.x * pos.x + pos.y * pos.y }
    static SqrDistance(pos1, pos2) { const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y; return dx * dx + dy * dy }
    static Normalize(dir) { const mag = Vector2.Magnitude(dir); return mag !== 0 ? new Vector2(dir.x / mag, dir.y / mag) : new Vector2(0, 0) }

    
}
export { Vector3, Vector2 }

export class VPos {

    constructor(vector) {
  
      this.xPos = vector.x
      this.yPos = vector.y
      this.zPos = vector.z
  
  
    }
    adjust(dx = 0, dy = 0, dz = 0) {
  
      this.xPos += dx
      this.yPos += dy
      this.zPos += dz
      return this;
  
    }
    get() {
  
      return { x: this.xPos, y: this.yPos, z: this.zPos }
  
  
    }
    
    
  }
  
