import math
import matplotlib.pyplot as plt

C = 1.0
ALPHA = 0.5
TOL = 1.e-6

def solve(g, tmin, tmax, t, r):		# bisection solver: g(z) = 0
    while abs(tmax-tmin) > TOL:
        tt = 0.5*(tmin+tmax)
        if g(tt, t, r)*g(tmin, t, r) > 0:
            tmin = tt
        else:
            tmax = tt
    return 0.5*(tmin+tmax)

def R(t):				# position of the moving charge
    r = [0.0, 0.0, 0.0]
    if t < 0:
        r[0] = ALPHA*math.exp(t)
    else:
        r[0] = ALPHA*math.cos(t)
        r[1] = ALPHA*math.sin(t)
    return r

def dist(a, b):				# distance between vectors a and b
    d2 = 0.0
    for k in range(3): d2 += (a[k]-b[k])**2
    return math.sqrt(d2)

def gg(z, t, r):			# objective function for solve
    return z - t + dist(r, R(z))/C

def tret(t, r):				# retarded time
    z1 = t - 2*dist(r, [0,0,0])/C
    z2 = t
    return solve(gg, z1, z2, t, r)

r = [5.0, 5.0, 0.0]			# field point

T = 20.
N = 500
dt = T/N

t = []
tr = []
for i in range(N+1):
    ti = dt*i
    t.append(ti)
    tr.append(tret(ti, r))

plt.plot(t, tr)
plt.xlabel('t')
plt.ylabel('tret')
plt.title('ALPHA = '+str(ALPHA))
plt.show()
