"""Original geometry/scattering figure. Tested Python 3.14/numpy 2.3/matplotlib 3.10. Outputs its opaque PNG basename in caller CWD and preserves supplied MPLCONFIGDIR. """ import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import Polygon, Arc fig,axes=plt.subplots(1,2,figsize=(10,4.4),layout='constrained',facecolor='white') a=axes[0];theta=np.pi/4;d=3/8 O=np.array([0.,1.]);P=np.array([0.,0.]);n=np.array([np.sin(theta),-np.cos(theta)]);G=O+d*n phi=np.linspace(theta-np.pi,theta,250) arc=O+np.column_stack([np.cos(phi),np.sin(phi)]) a.add_patch(Polygon(arc,closed=True,facecolor='#ddeaf3',edgecolor='#196080',lw=1.7)) a.axhline(0,color='black',lw=1.5) a.plot([O[0],P[0]],[O[1],P[1]],'k:',lw=1.4) a.plot([O[0],G[0]],[O[1],G[1]],color='#a72b1f',lw=2) a.plot([P[0],G[0]],[P[1],G[1]],color='#8b6e12',lw=2) for pt,label,offset in [(O,'O',(-.16,.07)),(G,'G',(.08,.01)),(P,'P',(-.15,-.13))]: a.plot(*pt,'ko',ms=4) a.text(pt[0]+offset[0],pt[1]+offset[1],label) a.text(-.17,.48,'a');a.text(.18,.98,r'$d=3a/8$',color='#a72b1f');a.text(.28,.39,'b',color='#8b6e12') start=arc[0];a.plot([start[0],start[0]+.45],[start[1],start[1]],'k:',lw=1) a.add_patch(Arc(start,.5,.5,theta1=0,theta2=45,color='black')) a.text(start[0]+.26,start[1]+.09,r'$\theta$') a.set(xlim=(-1,1.15),ylim=(-.22,1.95),aspect='equal',title='Rounded-contact rolling geometry') a.axis('off') a=axes[1];beta=np.sqrt(2.);limit=np.arccos(.25)/beta t=np.linspace(-limit,limit,500);r=1/np.cos(beta*t) x=r*np.cos(t);y=r*np.sin(t) a.plot(x,y,color='#17659a',lw=2,label=r'$r=\sec(\sqrt{2}\theta)$') for sign in [-1,1]: ang=sign*np.pi/(2*beta);direction=np.array([np.cos(ang),np.sin(ang)]);normal=np.array([-np.sin(ang),np.cos(ang)]) offset=-sign*normal/beta pts=offset+np.linspace(.2,4.5,150)[:,None]*direction a.plot(pts[:,0],pts[:,1],color='gray',ls='--',lw=1) for j,forward in [(75,1),(400,1)]: a.annotate('',xy=(x[j+10],y[j+10]),xytext=(x[j-10],y[j-10]),arrowprops={'arrowstyle':'->','color':'#17659a','lw':2}) a.plot(0,0,'ko',ms=4);a.text(.05,-.40,'Force centre',ha='center',fontsize=9) a.plot(1,0,'o',color='#a72b1f');a.text(1.1,.12,'Closest approach',fontsize=9) a.set(xlim=(-.7,3.3),ylim=(-3.6,3.6),aspect='equal',xlabel=r'$x/r_{\min}$',ylabel=r'$y/r_{\min}$',title='Repulsive inverse-cube force') a.legend(fontsize=9,loc='upper right') fig.savefig('paper-4-rolling-and-orbit.png',dpi=120,facecolor='white',transparent=False)