usingLinearAlgebrausingAbstractPlottingclip11(x)=max(-1.0,min(1.0,x))functionrepel(particles_node,N)particles=particles_node[]@inboundsforiin1:Nftot=Vec3f0(0)p1=particles[i]forjin1:Nifi!=jp2=particles[j]Δσ=acos(clip11(dot(p1,p2)))# great circle distanceftot+=(p1-p2)/max(1e-3,Δσ^2)endendparticles[i]=normalize(p1+0.001*ftot)endparticles_node[]=particlesendfunctionaddparticle!(particles,colors,nparticles)nparticles[]=nparticles[]+1particles[][nparticles[]]=normalize(randn(Point3f0))colors[][nparticles[]]=to_color(:green)particles[]=particles[]colors[]=colors[]ends=Scene(show_axis=false)mesh!(s,Sphere(Point3f0(0),1f0),color=:gray)max_particles=5000# Sadly, you currently can't resize 3D mesh particles, so we need to# implement resize on our own...particles=Node(fill(Point3f0(NaN),max_particles))colors=Node(fill(RGBAf0(0,0,0,0),max_particles))meshscatter!(s,particles,color=colors,markersize=0.05)nparticles=Node(0)fori=1:10addparticle!(particles,colors,nparticles)endupdate_cam!(s,FRect3D(Vec3f0(0),Vec3f0(1)))s.center=false# don't reset the camera by displayN=1000# N gets replaced by 100 for testingrecord(s,"output.mp4",1:N)doiterisodd(iter)&&addparticle!(particles,colors,nparticles)repel(particles,nparticles[])end