moon3D.frink

Download or view moon3D.frink in plain text format


/** This generates a model of the moon for 3-D printing.

    It requires data files from NASA:
    https://svs.gsfc.nasa.gov/4720

    Specifically the 1440x720 16-bit unsigned int TIFF displacement file
    renamed here to "moonhalfmeter.tif".

    Use the solver
https://frinklang.org/fsp/solve2.fsp?equations=%2F%2F+Globe+solver+for+3-D+printing%0D%0Ad+%3D+2+r%0D%0Ac+%3D+pi+d%0D%0Apixelsize+%3D+width+%2F+c%0D%0Apixelsize+%3D+res%0D%0A%0D%0Ascale+%3D+r+%2F+moonradius%0D%0A&solveFor=&ev=on&sel_c=S&val_c=299792458+m+s%5E-1&sel_d=S&val_d=86400+s&sel_moonradius=S&val_moonradius=1.738000e%2B6+m&sel_pi=L&val_pi=3.141592653589793238&sel_pixelsize=S&val_pixelsize=&sel_r=S&val_r=&sel_res=L&val_res=254+pixels%2Fin&sel_scale=S&val_scale=&sel_width=L&val_width=1440+pixels&resultAs=&showorig=on

*/


res = 254 / in

img = new image["file:moonhalfmeter.tif"]
[width, height] = img.getSize[]

hmax = 0
hmin = 255

for x = 0 to width-1
   for y = 0 to height-1
   {
      h = img.getPixelGrayInt[x,y]
      if h < hmin
         hmin = h
      if h > hmax
         hmax = h
   }

println["hmin is $hmin, hmax is $hmax"]

// exaggeration factor of vertical scale
exaggeration = 10

// Wall thickness of model.
thickness = 1.19 mm   
   
/* According to the page, the unsigned int tiff files are in units of half-
   meters, relative to a radius of 1727400 m. */

filebaseradius = 1727400 m

moonMeanRadius = 1737.4 km   // LRO reference sphere

maxMoonRadius = filebaseradius + hmax * 1/2 m * (2^16 / 256) * exaggeration
minMoonRadius = filebaseradius + hmin * 1/2 m * (2^16 / 256) * exaggeration

r = width / (2 pi res)
println["r = $r"]

scale = r / maxMoonRadius
println["scale = $scale"]


v = callJava["frink.graphics.VoxelArray", "construct", [-r res, r res, -r res, r res, -r res, r res, false]]

// Make a 1-pixel tool   
tool = newJava["frink.graphics.VoxelArray", [1,1,1,true]]
   
for x = 0 to width-1
{
   long = (x circle / width)
   clong = cos[long]
   slong = sin[long]

   for y = 0 to height-1
   {
      lat = ((height - y) / height) 180 deg - 90 deg
      clat = cos[lat]
      slat = sin[lat]
      
      h = img.getPixelGrayInt[x,y]
      rh = (filebaseradius + h * 1/2 m * (2^16 / 256) * exaggeration) scale
      highX = rh clat clong
      highY = rh clat slong
      highZ = rh slat

      rl = rh - thickness
      lowX = rl clat clong
      lowY = rl clat slong
      lowZ = rl slat

      v.addAlongLine[tool, round[lowX res], round[lowY res], round[lowZ res],
                     round[highX res], round[highY res], round[highZ res],
                     0, 0, 0]
   }
}

v.projectX[undef].show["X"]
v.projectY[undef].show["Y"]
v.projectZ[undef].show["Z"]

filename = "moon3D.obj"
print["Writing $filename..."]
w = new Writer[filename]
w.println[v.toObjFormat["moon3d", 1/(res mm)]]
w.close[]
println["done."]


Download or view moon3D.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 20143 days, 10 hours, 2 minutes ago.