X

NV5 Geospatial Blog

Each month, NV5 Geospatial posts new blog content across a variety of categories. Browse our latest posts below to learn about important geospatial information or use the search bar to find a specific topic or author. Stay informed of the latest blog posts, events, and technologies by joining our email list!



Mapping Earthquake Deformation in Taiwan With ENVI

Mapping Earthquake Deformation in Taiwan With ENVI

12/15/2025

Unlocking Critical Insights With ENVI® Tools Taiwan sits at the junction of major tectonic plates and regularly experiences powerful earthquakes. Understanding how the ground moves during these events is essential for disaster preparedness, public safety, and building community resilience. But traditional approaches like field... Read More >

Comparing Amplitude and Coherence Time Series With ICEYE US GTR Data and ENVI SARscape

Comparing Amplitude and Coherence Time Series With ICEYE US GTR Data and ENVI SARscape

12/3/2025

Large commercial SAR satellite constellations have opened a new era for persistent Earth monitoring, giving analysts the ability to move beyond simple two-image comparisons into robust time series analysis. By acquiring SAR data with near-identical geometry every 24 hours, Ground Track Repeat (GTR) missions minimize geometric decorrelation,... Read More >

Empowering D&I Analysts to Maximize the Value of SAR

Empowering D&I Analysts to Maximize the Value of SAR

12/1/2025

Defense and intelligence (D&I) analysts rely on high-resolution imagery with frequent revisit times to effectively monitor operational areas. While optical imagery is valuable, it faces limitations from cloud cover, smoke, and in some cases, infrequent revisit times. These challenges can hinder timely and accurate data collection and... Read More >

Easily Share Workflows With the Analytics Repository

Easily Share Workflows With the Analytics Repository

10/27/2025

With the recent release of ENVI® 6.2 and the Analytics Repository, it’s now easier than ever to create and share image processing workflows across your organization. With that in mind, we wrote this blog to: Introduce the Analytics Repository Describe how you can use ENVI’s interactive workflows to... Read More >

Deploy, Share, Repeat: AI Meets the Analytics Repository

Deploy, Share, Repeat: AI Meets the Analytics Repository

10/13/2025

The upcoming release of ENVI® Deep Learning 4.0 makes it easier than ever to import, deploy, and share AI models, including industry-standard ONNX models, using the integrated Analytics Repository. Whether you're building deep learning models in PyTorch, TensorFlow, or using ENVI’s native model creation tools, ENVI... Read More >

1345678910Last
9140 Rate this article:
5.0

An N-body College Reunion

Jim Pendleton

A little over 30 years ago, the professor in my sophomore quantum mechanics class gave us a free range assignment. We could use a computer to solve any sort of physics problem. It need not be related to quantum in any way, which was just as well since I've never grokked the wave function in fullness.

This was back in the day when students training for careers in basic sciences were expected to know how to write their own analysis applications, and not mindlessly press buttons on spreadsheets or web pages. In no small part because the latter hadn't been invented yet.

I chose a problem in astrophysics. At the time there was academic research being performed on simplified galactic collisions, and the plots in the scientific journals were fascinating to me. N-body problems were well beyond my grasp, unless N was one or two.  

I had no access to supercomputers, and my classical mechanics training was only at the freshman level.  

But I liked pretty pictures.

It was challenging at the time to debug Fortran PLOT10 programs when one needed to plan for additional wait time in line at the campus computing center for the output and it took an hour for a Calcomp plotter to produce the (garbage) graph the (garbage) code was generating.

Unfortunately, my attempt burned down, fell over, and sank into the swamp. I vaguely recall I received an orange slice and a participant’s ribbon for the effort. Thanks for not failing me, Prof. Dutta.

But a decade later, and with access to IDL, I reattempted the feat during a competition to produce demos for IDL 5.0.

The results were more satisfying visually, if not more realistic physically.

I've left the code below more or less intact. It’s a main application.  Dig the DEVICE, DECOMPOSED=0 and parentheses instead of square brackets – 100% OG, and I don’t mean Object Graphics.

Essentially, two point masses represent galactic centers and 1000 mass-less test points (“stars”) are given initial circular paths around those centers. Both galactic centers then move relative to their center of mass with some initial conditions intended to provoke a visually appealing, if physically bogus, result.

I wrote a number of variants on this theme, color-coded the stars by speed relative to the center of mass, added other “galactic” masses, etc. If you find this interesting, try varying initial parameters such as the relative masses and velocities.

; initialization section
G = 4.4999e-12 ; pc^3 y^-2 Msol^-1
epsilon = 1.e5 ; yr
snapshot = 16.e6 ;yr
nsnapshots = 16
maxradius = 15d3 ; pc
initialsep = 2.*maxradius
Ngalaxies = 2
GalaxyColors = [150, 200]
Nsuns = 1000
vx = dblarr(Ngalaxies*(Nsuns + 1)) & vy = vx & vz = vx & x = vx & y = vx
z = vx & m = vx & rdist=  vx & thetadist = vx & ax = vx & ay = vx & az = vx
m(0) = 10.d9 ; Msol
x(0) = initialsep/2.*cos(!pi/4.)
y(0) = initialsep/2.*sin(!pi/4.)
m(1) = 9.d9 ;Msol
x(1) = -x(0)
y(1) = -y(0)
speed = 2*sqrt(G*m(1)/initialsep)
vx(0) = -speed*sin(!pi/4.)/2.
vy(0) = speed*cos(!pi/4.)/2.
vx(1) = -vx(0)*sqrt(m(0)/m(1))/3.
vy(1) = -vy(0)*sqrt(m(0)/m(1))/3.
; execution section
device, decomposed = 0
iseed = 138987
for i = Ngalaxies, Ngalaxies*(Nsuns + 1) - 1 do begin
rdist(i) = randomu(iseed) * maxradius
thetadist(i) = randomu(iseed)*2*!pi
m(i) = 1.
endfor
for j = 0, ngalaxies - 1 do begin
for i = ngalaxies + j*nsuns, ngalaxies + (j + 1)*nsuns - 1 do begin
x(i) = rdist(i)*cos(thetadist(i)) + x(j)
y(i) = rdist(i)*sin(thetadist(i)) + y(j)
z(i) = 0.
speed = sqrt(G*m(j)/max([Abs(rdist(i)),1.e-30]))
vx(i) = -speed*sin(thetadist(i)) + vx(j)
vy(i) = speed*cos(thetadist(i)) + vy(j)
vz(i) = 0.
endfor
endfor
loadct,15
!ignore = -1
!x.style = 2
!y.style = 2
window, 1, xsize=700, ysize=700, xpos = 0, ypos = 0
wset, 1
for t = -epsilon, snapshot*(nsnapshots - 1), epsilon do begin
ax(*) = 0 & ay = ax & az = ax
for j = 0, NGalaxies - 1 do begin
r = sqrt((x - x(j))^2 + (y - y(j))^2 + (z - z(j))^2)
r3 = r^3 > 1.e-20
Gprod = -G*m(j)/r3
ax = Gprod*(x-x(j)) + ax
ay = Gprod*(y-y(j)) + ay
az = Gprod*(z-z(j)) + az
endfor
vx = vx + epsilon*ax
vy = vy + epsilon*ay
vz = vz + epsilon*az
x = x + epsilon*vx
y = y + epsilon*vy
z = z + epsilon*vz
if (t eq -epsilon) then begin
rs = 1.5*initialsep
plot, [rs, -rs], [rs, -rs], color = 0
closedcircles,sym=1
for i = 0, NGalaxies - 1 Do Begin
oplot,[x(i),x(i)],[y(i),y(i)],color=galaxycolors(i)
endfor
!psym = 3
for i = 0, NGalaxies - 1 Do Begin
indices = indgen(nsuns) + (i*nsuns) + Ngalaxies
oplot, x(indices), y(indices), color=galaxycolors(i)
endfor
oldx = x
oldy = y
endif else begin
;
;	Erase the previous frame
;
closedcircles,sym=1
oplot,oldx(0:NGalaxies-1),oldy(0:NGalaxies-1), color = 0
!psym = 3
oplot, oldx, oldy, color = 0
;
;	Draw the galaxy centers
;
closedcircles,sym=1
for i = 0, NGalaxies - 1 Do Begin
oplot,[x(i),x(i)],[y(i),y(i)],color=galaxycolors(i)
endfor
;
;	Draw the stars
;
!psym = 3
for i = 0, NGalaxies - 1 Do Begin
indices = indgen(nsuns) + (i*nsuns) + Ngalaxies
oplot, x(indices), y(indices), color=galaxycolors(i)
endfor
;
;	Save the coordinates
;
oldx = x
oldy = y
empty
endelse
endfor
end

You will also need the following support routine.

Pro ClosedCircles, Symbol_Radius = Symbol_Radius, Color = Color
On_Error, 2
Ang = (360./47.*Findgen(48))/!RaDeg
X = Cos(Ang)
Y = Sin(Ang)
If (N_Elements(Symbol_Radius) ne 0) then Begin
	X = X * Symbol_Radius
	Y = Y * Symbol_Radius
EndIf
If (N_Elements(Color) eq 0) then Begin
	UserSym, X, Y, /Fill
EndIf Else Begin
	UserSym, X, Y, /Fill, Color = Color
EndElse
!P.PSym = 8
Return
End
Please login or register to post comments.