import math

class vector:
    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)

def Vadd(a,b):
    return vector(a.x+b.x, a.y+b.y)

def Vsub(a,b):
    return vector(a.x-b.x, a.y-b.y)

def VmulScale(a,scalaire):
    return vector(a.x*scalaire, a.y*scalaire)

def Vmul(a,b):
    return vector(a.x*b.x, a.y*b.y)

def Vdiv(a,div):
    if div != 0:
        return VmulScale(a,1.0/div)
    return vector(0,0)
    
def VmagnitudeSQ(a):
    return ((a.x**2) + (a.y**2))

def Vmagnitude(a):
    return ((a.x**2) + (a.y**2))**0.5

def Vnormalize(a):
    return Vdiv(a,Vmagnitude(a))

def VnormalizeApprox(a):
    if a.x < a.y:
        return Vdiv(a,a.y)
    return Vdiv(a,a.x)

def Vdot(a,b):
    return (a.x * b.x) + (a.y * b.y)

def Vdist(a,b):
    dist = Vmagnitude(Vsub(a,b))
    return dist

def Vdistsq(a,b):
    return ((a.x - b.x)**2 + (a.y - b.y)**2)

def VfromRadian(r):
    return vector(math.sin(r),math.cos(r))

def VtoRadian(a):
    return math.atan2(a.y, a.x)

#b is another vector
#use it with VfromRadian -> Vrotate(a, VfromRadian(r))
def Vrotate(a,b):
    return vector(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y)
    
#2d crossproduct
def Vscalar(a, b):
    return a.x*b.y - b.x*a.y

#return the closest point on a line from pos TESTES TESTES RETESTED OPTIMIZED 100% work
def VclosestPoint(pos, p1, p2):
    p = Vsub(p2,p1)
    u = Vdot(Vsub(pos,p1),p)/VmagnitudeSQ(p)
    return Vadd(p1,VmulScale(p,u))

def VlineDist(pos,p1,p2):
    return Vdist(VclosestPoint(pos,p1,p2), pos)

def VlineDistSQ(pos,p1,p2):
    return Vdistsq(VclosestPoint(pos,p1,p2), pos)

def VLineNotParallel(p1,p2,p3,p4):
    #return ((p1.x-p2.x)*(p3.y-p4.y))-((p1.y-p2.y)*(p3.x-p4.y))
    pda = Vsub(p1,p2)
    pdb = Vsub(p3,p4)
    return Vscalar(pda,pdb)    #cross product of line vector return 0 if they are paralell

def VLineIntersect(p1,p2,p3,p4):
    a = vector(Vscalar(p1,p2), Vscalar(p3,p4))
    bx = vector(p1.x-p2.x, p3.x-p4.x)
    by = vector(p1.y-p2.y, p3.y-p4.y)
    d = VLineNotParallel(p1,p2,p3,p4)
    if d == 0:
        return vector(0,0)
    return vector(Vscalar(a,bx)/d, Vscalar(a,by)/d)



#test code
##################################

if __name__ == "__main__":
    a = vector(4,5)
    b = vector(3,2)
    c = Vadd(a,b)
    print a.x, a.y
    print b.x, b.y
    print c.x, c.y
    
    p1 = vector(10,10)
    p2 = vector(30,30)
    p3 = vector(10,30)
    p4 = vector(30,10)
    print VLineNotParallel(p1,p2,p3,p4), VLineIntersect(p1,p2,p3,p4).x,  VLineIntersect(p1,p2,p3,p4).y 
    p5 = vector(10,20)
    p6 = vector(30,40)
    print VLineNotParallel(p1,p2,p5,p6), VLineIntersect(p1,p2,p5,p6).x,  VLineIntersect(p1,p2,p5,p6).y 
    p7 = vector(10,20)
    p8 = vector(30,50)
    print VLineNotParallel(p1,p2,p7,p8), VLineIntersect(p1,p2,p7,p8).x,  VLineIntersect(p1,p2,p7,p8).y 

     
