Delayed Newton Force (DNF)

runs in python 3 after

pip3 install vpython


# from math import *
# from visual import *
# from visual.graph import * 
from vpython import *
# import vpython

scene.fullscreen = True

G = 10
c = 100


spheres = [
sphere(pos=vector(0,0,0),radius =6,color=color.red,charge=1000,mass=7200,velocity=vector(0,0,0),a = vector(0,0,0),trail=curve(color=color.red,ratain=1000)),
sphere(pos=vector(0,100,-1),radius=2,color=color.blue,charge=-1,mass=1,velocity=vector(10,0,0),a=vector(0,0,0),trail=curve(color=color.blue,retain=1000)),
#sphere(pos=vector(0,12,0),radius=.08,color=color.green,mass=sqrt(4),velocity=vector(1.2,0,0.6),a=vector(0,0,0),trail=curve(color=color.green)),
sphere(pos=vector(0,100,1),radius=2,color=color.white,charge=-1,mass=1,velocity=vector(-10,0,0),a=vector(0,0,0),trail=curve(color=color.white, retain=1000)),
#sphere(pos=vector(0,28,0),radius=.4,color=color.orange,mass=sqrt(80),velocity=vector(0.7,0,0.4),a=vector(0,0,0),trail=curve(color=color.orange)),
#sphere(pos=vector(0,32,0),radius=0.2,color=color.white,mass=-sqrt(10),velocity=vector(1.5,0,0.4),a=vector(0,0,0),trail=curve(color=color.white))
]

#print(spheres[0].a)

#print(len(spheres))


# undelayed flying start
def acceleration1on2(sphere2,sphere1):
    r = sphere2.pos - sphere1.pos
    return ((G*sphere1.charge*sphere2.charge)/pow(mag(r),2))/sphere2.mass*norm(r)
    
    
t = 0
dt = .01


for index in range(1,1001):
    rate(2500)

    for i in spheres:
        i.a = vector(0,0,0)
        for j in spheres:
            if i!=j:
                i.a = i.a + acceleration1on2(i,j)
            
          
                
                
    for i in spheres:
        i.velocity = i.velocity + i.a *dt
        i.pos = i.pos+i.velocity*dt
        i.trail.append(pos=i.pos)
        



def acceleration1on2(sphere2,sphere1):
    npoints= sphere1.trail.npoints
    should_be_zero = 100000000
    should_be_zero_previous = 10000000000000
    for n in range(npoints):
        r = sphere2.pos - sphere1.trail.point(npoints-n-1)["pos"]
        r_mag = mag(r)  
        should_be_zero = abs( r_mag - c*n*dt )
        if ( should_be_zero > should_be_zero_previous ):
            normal_r = norm(r)
            break

        should_be_zero_previous = should_be_zero

    return ( (G*sphere1.charge*sphere2.charge) /pow(r_mag,2) ) /sphere2.mass * normal_r
    



while 1:
    rate(250)
    
                

    for i in spheres:
        i.a = vector(0,0,0)
        for j in spheres:
            if i!=j:
                i.a = i.a + acceleration1on2(i,j)
            
          
                
                
    for i in spheres:
        i.velocity = i.velocity + i.a *dt
        i.pos = i.pos+i.velocity*dt 
        i.trail.append(pos=i.pos)