Re:Mappatura luna

#54480

ValterVB
Partecipante
  • Blenderista
  • Post sul forum 185

Siccome mi sono stati chiesti dettagli su come ci sono riuscito, scrivo qua, nel caso possa servire a qualcuno, anche per mostrare il metodo per giungere al risultato anche non disponendo di sufficienti conoscenze Nel mio caso, a parte un po’ di Blender avevo conoscenza di VB, zero sul formato del file e zero su Phython.

Scusate la lunghezza…..

Nel caso fosse considerato off topic, si potrebbe spostare nella sezione OFF TOPIC appunto 😉

Ciao

ValterVB

Per scaricarsi i dati:

https://www.soac.selene.isas.jaxa.jp/ar … ex.html.en

Crei un account

Premi DataSearch, ti logghi con l’account appena creato. Premi Product selection, selezioni LALT, poi selezioni HighLevel poi selezioni GlobalTopographiMAP…, poi ADD, poi Determination, poi Search Determination, poi spunti la casella sotto Order e confirm. Dopo un po’ ti arriva sulla posta un Link a un sito FTP con il file da scaricare (in questo caso sono poco più di 60 mega), è un file con estensione SL2 ma in realtà  è un file compresso apribile con 7-ZIP. Il file più grande è quello con i dati dell’altimetria di tutta la luna. Se lo guardi con un Editor (per es. XVI32) , vedrai che all’inizio del file ci sono caratteri ASCII con tutte le informazioni sul contenuto del file. Semplificando i dati sono così composti:

Per ogni punto della luna su cui hanno fatto i rilievi nel file è registrata la distanza dal centro della luna, per semplificazione la luna è stat considerata una sfera perfetta. I punti sono stati rilevati a una distanza di 1895 m uno dall’altro (1/16 di grado). I dati sono registrati da Nord a sud e da ovest a est. (dettagli nell’intestazione del file). Tieni conto che ci sono 16588800 punti, quindi visualizzarli tutti contemporaneamente sia impossibile.

I punti sono divisi in 2880 linee (li puoi considerare i paralleli) e ogni linea è divisa in 5760 punti, praticamente ogni linea rappresenta una circonferenza a una data latitutdine. Con un piccolo programma in Visual Basic (se uno non avesse VB, si può usare tranquillamente il VBA presente in un prodotto Office, o probabilmete uno script in VBS che dovrebbe essere disponibile su qualsiasi installazione Windows) estraggo i dati di altezza (coordinata Z) e calcolo le coordinate X e Y sapendo che dovranno essere riportate su una sfera basta un minimo di geometria.

A questo punto ho un file di testo con indicato per ogni vertice le coordinate x,y,z.

Prime righe del file (notate le dimensioni, i punti si trovano anche a più di 1600 unità  dal centro di Blender:

620.967154243645 61.5431592549666 –1620.31566305881

622.717418005197 61.5414933581678 -1619.59348752146

624.466845183452 61.5398274655943 -1618.86942169753

Con lo script indicato qua sotto (trovato cercando su GOOGLE: import+point+blender) posso importare i vertici. I commenti, quelli scritti dopo il simbolo # sono una mia interpretazione, ma credo abbastanza reale, di quello che dovrebbe fare quella linea.

Code:
import Blender
from Blender import Scene, Mesh
filename=’C:Mappa LunaMappaLALT_GGT_MAP.txt’ #Apre il file con i dati
data=[] #Creo una matrice che conterrà  tutti i vertici
for line in open(filename): #Per ogni linea del file memorizzo i 3 dati (x,y,z)
line=line.rstrip(“n”) #Queste 2 righe indicano il carattere di new line e di separazione del dato.
line=line.rstrip(“r”)
temp=line.split()
data.append((float(temp[0]),
float(temp[1]),
float(temp[2])))
me = Mesh.New(‘point cloud’) #Creo una mesh con nome Point cloudob
me.verts.extend(data)
Scene.GetCurrent().objects.new(me,”pointcloudob”)
Blender.Redraw()

Eseguito lo script hai tutti i vertici disegnati , quello che ti serve è collegarli per creare delle mesh. Per capire come fare ho cercato su Google, quello che per me era il comando chiave dello script precedente: erts.extend, da li sono risalito a altri comadi e ne ho cercato uno simile per i lati, ed ecco saltar fuori faces.extend. Da un esempio si vede che per disegnare una mesh devi indicare i vertici che fanno parte della mesh in un certo ordine. Siccome questo ordine non era spiegato, ho esportato in formato PLY un mesh semplice (2 piani affiancati e guardando il file generato (basta NotePad), ho visto che i vertici sono indicati seguendo un percorso antiorario. A questo punto ho fatto una piccola modifica al programma in VB per aggiungere le sequenze di vertici su un file separato, (sicuramente si può fare tutto in un unico file, ma non ho avuto tempo per cercare come fare).

Prime righe del secondo file:

1 0 66 67

2 1 67 68

3 2 68 69

poi ho modificato lo script precedente aggiungendo le linee che servivano per importare i dati delle mesh:

Code:
import Blender
from Blender import Scene, Mesh

filename=’C:Mappa LunaMappaPoint.txt’
filename1=’C:Mappa LunaMappaMesh.txt’
data=[]
data1=[]
for line in open(filename):
line=line.rstrip(“n”)
line=line.rstrip(“r”)
temp=line.split()
data.append((float(temp[0]),
float(temp[1]),
float(temp[2])))

me = Mesh.New(‘point cloud’)
me.verts.extend(data)
for line in open(filename1):
line=line.rstrip(“n”)
line=line.rstrip(“r”)
temp=line.split()
data1.append((int(temp[0]),
int(temp[1]),
int(temp[2]),
int(temp[3])))
me.faces.extend(data1)

Scene.GetCurrent().objects.new(me,”pointcloudob”)
Blender.Redraw()

et voilà , ecco la mappa lunare. Naturalmente il file di qua sopra si può sicuramente migliorare, ma sembra funzionare.

Ultime considerazioni:

Il dettaglio in questo caso non è elevato, quindi si potrebbe utilizzare solo per un rendering della luna intera, esistono sul sito della NASA delle fotografie della luna intera che arrivano a 4000×2000 pixel e sono tutte liberamente utilizzabili, (come tutto il materiale prodotto dalla NASA). Chiaramente per un rendering simile bisogna ridurre i numeri di vertici, per esempio scrivendo un dato ogni 5 o ogni dieci, o renderizzando solo la metà  della luna che interessa.

Per fare quello che volevo fare io, servono delle mappe più dettagliate. Sul sito della jaxa esistono delle mappe parziali con una griglia di meno di 10X10 m ma devo ancora capire il formato perchè è diverso da quello del file precedente, e sulla NASA stanno iniziando a pubblicare i rilievi effettuati con il LOLA che dovrebbe arrivare a una risoluzione di 1×50 m ma anche di questi devo capire il formato. Questi dovrebbero permettere di applicare le foto della LRO che come detto hanno una risoluzione di 0,5 m a pixel (ogni “strisciata” ha una misura superiore ai 5000×50000 pixel)

Questo è il listato in VB2005, buttato giù brutalmente, senza ottimizzazioni o finezze stilistiche…. 😀

Per renderlo flessibile bisognerebbe fare una finestra di scelta della coordinata che interessa e dell’ampiezza della mappa

Code:
—————————-
Public Class Form1
Sub Leggi()
Const FILE_NAME As String = “C:Mappa LunaMappaLALT_GGT_MAP.IMG”
Const FILE_SCRIVI As String = “C:Mappa LunaMappaPoint.txt”
Const FILE_SCRIVI_MESH As String = “C:Mappa LunaMappaMesh.txt”

Dim fs As New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read)
Dim i As Integer : Dim j As Integer : Dim h As Double
Dim x As Double : Dim y As Double : Dim z As Double
Dim xs As String : Dim ys As String : Dim zs As String
Dim r As New BinaryReader(fs)
Dim MoonRadius As Double = 1737.4 ‘Raggio della luna
Dim Risoluzione As Double = 0.0625 ‘Risoluzione della mappa in radianti=1/16 di grado
Dim Righe As Integer = 2880
Dim Campioni As Integer = 5760
Dim GradiToRad As Double = 0.017453292519943295 ‘fattore di conversione da gradi sessadecimali a radianti
Dim PrimaLatitudine As Double = 89.96875 ‘Latitudine della prima riga
Dim PrimaLongitudine As Double = 0.03125 ‘Longitudine del primo punto
Dim Latitudine As Double : Dim Longitudine As Double
Dim DistanzaCentro As Double : Dim TempRad As Double
Dim cont As Long

‘Qua ho deciso di prendere solo una porzione della mappa di 66×66 punti
Dim Row As Long = 66 : Dim Col As Long = 66

Dim ContRow As Long : Dim ContCol As Long
‘I dati iniziano dal byte n° 9559
r.ReadBytes(9558) ‘Mi posiziono direttamente sul primo byte di dati
Using sw As StreamWriter = New StreamWriter(FILE_SCRIVI)
For i = 0 To Righe – 1
Latitudine = PrimaLatitudine – i * Risoluzione
For j = 0 To Campioni – 1
Longitudine = PrimaLongitudine + j * Risoluzione
h = r.ReadSingle
cont = cont + 1
DistanzaCentro = MoonRadius + CSng(h)
TempRad = DistanzaCentro * Math.Cos(Latitudine * GradiToRad)
x = TempRad * Math.Sin(Longitudine * GradiToRad)
y = DistanzaCentro * Math.Sin(Latitudine * GradiToRad)
z = -TempRad * Math.Cos(Longitudine * GradiToRad)
‘Il decimale deve essere un punto e non la virgola
xs = Replace(CStr(x), “,”, “.”)
ys = Replace(CStr(y), “,”, “.”)
zs = Replace(CStr(z), “,”, “.”)
‘Questo IF mi fa scrivere solo i dati della porzione che mi interessa
If i >= 837 And i < = 902 And j >= 0 And j < = 5759 Then
sw.Write(xs & vbTab & ys & vbTab & zs & vbCrLf) ‘Scrivi le coordinate del vertice
cont = cont + 1
End If
Next
Next
End Using
Using sw As StreamWriter = New StreamWriter(FILE_SCRIVI_MESH)
For ContRow = 1 To Row – 1
For ContCol = 2 To Col
‘Qua scrivo i dati per creare le Mesh. é possibile che ci sia un errore
‘Ma per porzioni della mappa funziona
sw.Write(ContCol + (ContRow – 1) * Col – 1 & vbTab & ContCol – 1 + (ContRow – 1) * Col – 1 & vbTab & ContCol – 1 + Col) + (ContRow – 1) * Col – 1 & vbTab & (ContCol + Col) + (ContRow – 1) * Col – 1 & vbCrLf)
Next
Next
End Using
r.Close()
fs.Close()