Now that Artemis II has successfully launched and has left Earth orbit on its way to the Moon, the new goal is to fly around the Moon. I covered the expected orbital trajectory in a previous post (https://community.wolfram.com/groups/-/m/t/3672762). Now I want to explore what the crew will see as they approach the Moon and then return home.
As before, we need to query JPL Horizons for the latest trajectory data for the mission. First we need to define the date/time window, in this case the bounds of the data JPL provides and a 10 minute sampling increment:
In[]:=
date0=;date1=;dt=;
Now JPL Horizons can be queried:
In[]:=
horizonsEarth="State","@-1024",<|"Frame"->"EclipticJ2000","Center"->,"Dates"->{date0,date1,dt}|>,"Position","Dataset";
Next a TimeSeries can be constructed from the queried data:
In[]:=
artemisEarthTS=TimeSeries@QuantityMagnitude[Normal@horizonsEarth,"AstronomicalUnit"];
Next, some convenience functions are created to get the positions of the various elements of the final scene, using the "EclipticICRS" frame (which is identical to NASA's "EclipticJ2000") centered at the center of the Earth:
In[]:=
artemisPos[d_]:=Values[artemisEarthTS[d]]moonPos[d_]:=AstroPosition,"EclipticICRS",d,,"Cartesian"["Data"]earthPos[d_]:={0,0,0};sunPos[d_]:=AstroPosition,"EclipticICRS",d,,"Cartesian"["Data"]
As before, some undocumented functions are used to get the proper time-dependent rotations of the 3D elements. The "EclipticICRS" frame is time-independent so we don't need to give it a date:
In[]:=
moonRot[d_]:=Astronomy`AstroOrientationMatrix[{"IAU_MOON",d},"EclipticICRS"]earthRot[d_]:=Astronomy`AstroOrientationMatrix[{"ITRS",d},"EclipticICRS"]
Physicals sizes of the bodies are needed:
In[]:=
moonRad=QuantityMagnitude["EquatorialRadius"],"AstronomicalUnit";earthRad=QuantityMagnitude["EquatorialRadius"],"AstronomicalUnit";sunRad=QuantityMagnitude["EquatorialRadius"],"AstronomicalUnit";
Textures and styles are needed for the solar system bodies:
In[]:=
moon0={Texture[GeoImage[GeoModel->"Moon",GeoCenter->-90,GeoProjection->"Equirectangular",GeoZoomLevel->2]],Sphere[]};earth0=["TexturedSurface"][[1]];sun0={ColorData["BlackBodySpectrum"][5770],Sphere[]};
Next we rotate, scale, and translate each of the solar system bodies to their appropriate positions:
In[]:=
moon[d_]:=Translate[Scale[GeometricTransformation[moon0,moonRot[d]],moonRad,{0,0,0}],moonPos[d]]earth[d_]:=Scale[GeometricTransformation[earth0,earthRot[d]],earthRad,{0,0,0}]sun[d_]:=Translate[Scale[sun0,sunRad,{0,0,0}],sunPos[d]]
Some styling for date stamp is useful as well:
In[]:=
label[d_]:=Style[DateString[d,{"DayShort"," ","MonthNameShort"," ","Year"," ","Hour24",":","Minute",":","Second"," ","GMT"}],GrayLevel[.75],Bold,22]
To make things more interesting, its useful to “slow down the clock” when the view is near the Moon so more attention to detail is possible. To do this, the date range is sampled at 1 minute increments when far from the Moon, but at 1 second increments when close to the Moon.
In[]:=
movingAverage[dates_List,n_Integer]:=Mean/@Partition[dates,n,1];
In[]:=
IntervalSampling[intsamps_List]:=With[{all=Union@@Map[IntervalSampling,intsamps]},{n=Round[Length[all]/100,2]},{res=movingAverage[all,n+1]},Union[Take[all,n/2],res,Take[all,-n/2]]];
In[]:=
IntervalSampling[Rule[{tmin_,tmax_},dt_]]:=Range[tmin,tmax,dt]
In[]:=
dates=IntervalSampling,->,,->;
Finally, the scene can be assembled. The key functionality here is the use of the ViewVector option. This allows the camera to be placed at the location of the spacecraft and the target to be pointed at the Moon. The result is a simulated view of what the Artemis II crew would see if they looked at the Moon during the entire mission.
In[]:=
crewViewFrames=Graphics3D{AmbientLight[GrayLevel[.2]],{Specularity[White,1],PointLight[White,sunPos[#]],AmbientLight[GrayLevel[.2]],moon[#],earth[#]},{DirectionalLight[White,ImageScaled[{0,0,1}]],sun[#]}},&/@dates;
In[]:=
crewViewVideo=SlideShowVideo[crewViewFrames,DefaultDuration->45,RasterSize->{720,720}]
Out[]=
Revisiting the previous orbital view
Revisiting the previous orbital view
This is mainly an abbreviated version of the content from my previous post with code changes to make it consistent with this new post. Reconstructing this can be useful if you want to combine both videos so they are in sync with each other.
In[]:=
datesFromData=Keys[Normal[horizonsEarth]];
In[]:=
xyzArtemisEarth=QuantityMagnitude[Values/@Values@Normal[horizonsEarth[[All,{"X","Y","Z"}]]],"AstronomicalUnit"];
In[]:=
artemisEarthTimeSeries=TimeSeries[Transpose[{datesFromData,xyzArtemisEarth}]]
Out[]=
TimeSeries
In[]:=
artemisDataFromEarth[d_]:={StandardRed,AbsolutePointSize[10],Point[artemisEarthTimeSeries[d]],Opacity[.75],AbsoluteThickness[2],Line[xyzArtemisEarth]}
In[]:=
moonPath=LineAstroPosition,"EclipticICRS",#,,"Cartesian"["Data"]&/@datesFromData;
In[]:=
moonDataFromEarth[d_]:=White,SphereAstroPosition,"EclipticICRS",d,,"Cartesian"["Data"],moonRad,Opacity[.5],AbsoluteThickness[2],moonPath
flybyDate=;
In[]:=
moonFlybyPos=AstroPosition,"EclipticICRS",flybyDate,,"Cartesian"["Data"];
optionsFromEarth=;
In[]:=
orbitViewFrames=Graphics3D[{{White,Translate[Scale[Sphere[],moonRad,{0,0,0}],moonPos[#]],Opacity[.5],AbsoluteThickness[2],moonPath},earth[#],{StandardRed,AbsolutePointSize[10],Point[artemisEarthTimeSeries[#]],Opacity[.75],AbsoluteThickness[2],Line[xyzArtemisEarth]}},optionsFromEarth]&/@dates;
In[]:=
orbitViewVideo=SlideShowVideo[orbitViewFrames,DefaultDuration->45,RasterSize->{720,720}]
Out[]=
Combining the videos is mostly left as an exercise for the reader, but functions like GridVideo can be an easy way to combine them in a simple way.
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
View of the Moon from Artemis II
by Jeffrey Bryant
Wolfram Community, STAFF PICKS, April 3, 2026
https://community.wolfram.com/groups/-/m/t/3673962
by Jeffrey Bryant
Wolfram Community, STAFF PICKS, April 3, 2026
https://community.wolfram.com/groups/-/m/t/3673962