This uses the same motion updating in the previous post, but replaces the contraction step (i.e., boidLocations = 0.995 boidLocations) with a projection to the sphere. Because location is constrained, the step away from the “enemy” can be larger and things don’t fly away, making it too large destroys the flocking behavior.
A graphic to help with the visualization
In[]:=
sphereGraphic=;
SeedRandom[0];initialize[1000,"Initial Locations"->"Sphere"];friendMobility=0.02;enemyMobility=0.01;swtichFrequency=0.9;everyonesFriend=ConstantArray[randomBoid,numberBoids];everyonesFriendSwitchFrequency=.8;everyonesFriendMobility=0.0001;{nothing,frames}=ReapDoIf[RandomReal[]<(1-swtichFrequency),switchFriendsEnemies];If[RandomReal[]<(1-everyonesFriendSwitchFrequency),everyonesFriend=ConstantArray[randomBoid,numberBoids]];vLast=boidVelocity;boidVelocity=friendMobilityboidForceTerm[friend]-enemyMobilityboidForceTerm[enemy]+everyonesFriendMobilityboidForceTerm[everyonesFriend];vMean=0.5(vLast+boidVelocity);boidLocations=Normalize/@(boidLocations+vMean);SowShowGraphics3D[sphereGraphic],drawBoid[boidLocations,vMean,"Velocity Range"->{.0001,.025},PlotRange->1],,{t,0,2000};
It can be helpful to turn the graphics objects into images in parallel
In[]:=
LaunchKernels[];AbsoluteTiming[Block[{images},Echo[AbsoluteTiming[images=ParallelMap[Image,Rest@Flatten[frames]];]];Export[FileNameJoin[{NotebookDirectory[],"boidsOnSphere.mp4"}],images]];]
»
{41.1688,Null}
Out[]=
{49.601,Null}
(*boidsOnSphere=FrameListVideo[Flatten[frames]]*)
Out[]=
You can get the mp4 video here:
Import["http:pruffle.mit.edu/~ccarter/Videos/boidsOnSphere.mp4"]
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Boids 2: spherical projection with dynamic viewpoint tracking
by W. Craig Carter
Wolfram Community, STAFF PICKS, June 24, 2025
https://community.wolfram.com/groups/-/m/t/3485041
by W. Craig Carter
Wolfram Community, STAFF PICKS, June 24, 2025
https://community.wolfram.com/groups/-/m/t/3485041