
# Vector.py

import math, random
from point import Point

# acceptable uncertainty
EPS = 1e-8


class Vector:
  def __init__(self, x=0, y=0):
    self.x = x
    self.y = y

  def __str__(self):
    return f"<{self.x}, {self.y}>"

  def scale(self, s):
    return Vector((s * self.x), (s * self.y))


  @staticmethod
  def translate(pt, v):
    return point((pt.x + v.x), (pt.y + v.y))

  @staticmethod
  def toVec(pt1, pt2):
    return Vector((pt2.x - pt1.x), (pt2.y - pt1.y))

  @staticmethod
  def segToVec(seg):
    return Vector((seg.p2.x - seg.p1.x), (seg.p2.y - seg.p1.y))

  @staticmethod
  def dot(u, v):
    return ((u.x * v.x) + (u.y * v.y))

  @staticmethod
  def cross(u, v):
    # returns the length of cross product Vector
    return ((u.x * v.y) - (u.y * v.x))

  @staticmethod
  def squareNorm(v):
    return ((v.x * v.x) + (v.y * v.y))

  @staticmethod
  def angleOrig(a, b, deg=False):
    return angle(a, point(0,0), b, deg)

  @staticmethod
  def angle(a, origin, b, deg=False):
    oa = Vector.toVec(origin, a)
    ob = Vector.toVec(origin, b)
    theta = math.acos(Vector.dot(oa, ob) / 
            math.sqrt(Vector.squareNorm(oa) * 
                      Vector.squareNorm(ob)))
    f = 1.0
    if deg == True:
      f = (180.0 / math.pi)
    return theta * f


  @staticmethod
  def ccw(p, q, r):
    '''
     returns 0, 1, or -1
      0 if p-->r and p-->q are collinear
      1 if p--> r is left (counter-clockwise) of p-->q
     -1 if p--> r is right (clockwise) of p-->q
    '''
    pq = Vector.toVec(p, q)
    pr = Vector.toVec(p, r)
    cross = Vector.cross(pq, pr)
    if abs(cross) < EPS:
      return 0
    elif cross > 0:
      return 1
    else:
      return -1

  @staticmethod
  def areCollinear(p, q, r):
    pq = Vector.toVec(p, q)
    pr = Vector.toVec(p, r)
    return (abs(Vector.cross(pq, pr)) < EPS)


# -------------------------------------

