""" Author: Piotr A. Zolnierczuk (zolnierczukp at ornl dot gov) Based on a paper by: Drawing an elephant with four complex parameters Jurgen Mayer, Khaled Khairy, and Jonathon Howard, Am. J. Phys. 78, 648 (2010), DOI:10.1119/1.3254017 """ import numpy as np # elephant parameters p1, p2, p3, p4 = (50 - 30j, 18 + 8j, 12 - 10j, -14 - 60j ) p5 = 40 + 20j # wiggle factor and eyepiece def fourier(t, C): f = np.zeros(t.shape) A, B = C.real, C.imag for k in range(len(C)): f = f + A[k]*np.cos(k*t) + B[k]*np.sin(k*t) return f def elephant(t, p1, p2, p3, p4, p5): npar = 6 Cx = np.zeros((npar,), dtype='complex') Cy = np.zeros((npar,), dtype='complex') Cx[1] = p1.real*1j Cx[2] = p2.real*1j Cx[3] = p3.real Cx[5] = p4.real Cy[1] = p4.imag + p1.imag*1j Cy[2] = p2.imag*1j Cy[3] = p3.imag*1j x = np.append(fourier(t,Cx), [-p5.imag]) y = np.append(fourier(t,Cy), [p5.imag]) # wiggle the trunk ( trunk_i = y>40 x_trunk = x[trunk_i] N_trunk = len(x_trunk) # x[trunk_i] = x_trunk * concatenate([linspace(1,p5.real,floor(N_trunk/2.0)), # linspace(p5.real,1,ceil(N_trunk/2.0))]) x[trunk_i] = x_trunk + concatenate([linspace(0,p5.real,floor(N_trunk/2.0)), linspace(p5.real,0,ceil(N_trunk/2.0))]) return x,y def plot_elephant(wiggle=40, p4_real=14, t_p=1.0): p1, p2, p3, p4 = (50 - 30j, 18 + 8j, 12 - 10j, - p4_real - 60j ) p5 = wiggle + 20j t = np.linspace(0,2*np.pi,1000) x, y = elephant(t, p1, p2, p3, p4, p5) fig, ax = plt.subplots(figsize=(10, 7)) ax.plot(y,-x,'.') #x_p, y_p = elephant(array(t_p/1000.0*2*pi), p1, p2, p3, p4, p5) #ax.plot(y_p,-x_p,'ro') ax.set_xlim(-80, 100) ax.set_ylim(-80, 100) fig.suptitle('elephant with wiggle parameter = ' + str(wiggle)) return fig #fig = plot_elephant(wiggle=0.5) #plot_elephant(wiggle=10, p4_real=10) from ipywidgets import StaticInteract, RangeWidget, RadioWidget StaticInteract(plot_elephant, wiggle=RangeWidget(0,40,5))