##############    Quick demo to show off position-verlet

import math, vector, pyg
from vector import *


class verletpoint:
        def __init__(self,p,size):           # the particle
                self.pos = p
                self.old = p#vector(101,101)  # <---- old position=0,0 donc pos-old = velocite initiale pour pitcher les nodes partout
                self.size = size
                
restitution = 0.85                       # the constants
friction = 0.08
gravity = 0.1
rigidity = 0.5

GLUE = 2        # <<<--------------try +2 to -2    #repulsion ou attraction capilaire



box=[0,0,pyg.width,pyg.height]          # the frame
                
l=[]                                    # the list
l.append(verletpoint(vector(100,101),30))
l.append(verletpoint(vector(200,101),50))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(100,101),60))
l.append(verletpoint(vector(200,101),50))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(600,101),30))
l.append(verletpoint(vector(100,101),80))         
l.append(verletpoint(vector(220,402),30))
l.append(verletpoint(vector(300,202),40))
l.append(verletpoint(vector(400,202),20))
l.append(verletpoint(vector(500,202),60))         
l.append(verletpoint(vector(620,402),15))
l.append(verletpoint(vector(100,203),60))
l.append(verletpoint(vector(200,203),50))
l.append(verletpoint(vector(300,203),30))         
l.append(verletpoint(vector(420,404),70))
l.append(verletpoint(vector(100,203),20))
l.append(verletpoint(vector(200,203),40))
l.append(verletpoint(vector(300,203),30))         
l.append(verletpoint(vector(420,404),50))
l.append(verletpoint(vector(100,203),30))
l.append(verletpoint(vector(200,203),20))
l.append(verletpoint(vector(300,203),30))         
l.append(verletpoint(vector(420,404),10))
l.append(verletpoint(vector(200,101),50))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(600,101),30))
l.append(verletpoint(vector(100,101),40))         
l.append(verletpoint(vector(220,402),30))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),10))
l.append(verletpoint(vector(500,101),25))
l.append(verletpoint(vector(300,101),20))         
l.append(verletpoint(vector(420,401),40))
l.append(verletpoint(vector(500,101),25))

while pyg.main():
##################### BEHOLD; the verlet
                #
                #newpos =                   (2*pos    -  old)   + grav
        for i in l:
                newpos = Vadd(Vsub(VmulScale(i.pos, 2), i.old), vector(0,gravity))
                i.old = i.pos
                i.pos = newpos


                
#####################collision ball to ball
        for i in l:
                for j in l:
                        if j != i:
                                dist = Vdist(j.pos, i.pos)
                                if dist < i.size+j.size+GLUE:
                                        direction=Vsub(j.pos,i.pos)
                                        push = 1                #preload force to separate divisions by zero ( same coord for 2 particle)
                                        if dist != 0:  
                                           push=(dist-(i.size+j.size)) / dist
                                        
                                        pushvec = VmulScale(direction, rigidity*push)
                                        i.pos = Vadd(i.pos, pushvec)
                                        j.pos = Vsub(j.pos, pushvec)

                                        
                                        
####################collision world                                    
                if i.pos.x-i.size < box[0]:                                       # if out of bounds:
                        impactvel = (i.old.x - i.pos.x)*restitution    # impact velocity adjusted with restitution coeeficient  
                        i.pos.x = box[0]+i.size                                   # new pos outside bounds to satisfy constraint.
                        i.old.x = i.pos.x - impactvel                        # old pos adjusted to penetration depth - adjusted impact velocity
                        i.old.y -= (i.old.y - i.pos.y)*friction    # some friction
                        
                if i.pos.y-i.size < box[1]:
                        impactvel = (i.old.y - i.pos.y)*restitution
                        i.pos.y = box[1]+i.size
                        i.old.y = i.pos.y - impactvel
                        i.old.x -= (i.old.x - i.pos.x)*friction
                        
                if i.pos.x+i.size > box[2]:
                        impactvel = (i.old.x - i.pos.x)*restitution
                        i.pos.x = box[2]-i.size
                        i.old.x = i.pos.x - impactvel
                        i.old.y -= (i.old.y - i.pos.y)*friction
                        
                if i.pos.y+i.size > box[3]:
                        impactvel = (i.old.y - i.pos.y)*restitution
                        i.pos.y = box[3]-i.size
                        i.old.y = i.pos.y - impactvel
                        i.old.x -= (i.old.x - i.pos.x)*friction

                pyg.circle(i.pos.x, i.pos.y, i.size)
