Memorizziazione dati su Matlab

di il
1 risposte

Memorizziazione dati su Matlab

Salve ragazzi. Io non ho molta dimestichezza con Matlab e devo fare un progetto che mi hanno affibbiato.

Il problema è questo:
io ho un file contenente dei dati (di cui dopo vi descriverò la struttura) e devo opportunamente salvare questi dati in delle strutture. Il file è il risultato di un altro programma che effettua una triangolazione casuale di un cubo.

Il file è così strutturato (un esempio):

Punti
00B5BCD0 - 0.000000 4.000000 2.000000
00B5BCA0 - 4.000000 4.000000 2.000000
(per n punti. Il codice esadecimale è un puntatore al punto e i numeri sono le coordinate.
Il numero dei punti non è specificato perché la triangolazione è casuale)
.
.

Segmenti
00B5C710 - 00B5BBE0 -> 00B5BBB0 facce: 00B5CA30 00B5AF58 00B5C870
00B5C668 - 00B5BBE0 -> 00B5BC10 facce: 00B5CA70 00B5CA30 0043EC80 00B5C830
(Il primo codice punta al segmento. Il secondo e il terzo specificano i punti uniti dai segmenti. Gli altri puntano alle facce a cui può appartenere lo specifico segmento)


Il file è così strutturato. Mi hanno consigliato di salvare i dati in dei vettori/matrici e non in strutture più complesse. Inoltre mi è stato fatto notare che il numero, ad esempio, di facce a cui può appartenere il segmento, non è noto a priori, quindi mi hanno consigliato di acquisire riga per riga e poi leggerla e salvarla pezzo per pezzo. Quello che mi serve alla fine sono due array contenenti uno le coordinate dei punti ed un altro i segmenti.

Cosa mi consigliate? Per favore aiutatemi, sono in grande difficoltà e sto smattando dietro Matlab senza arrivare ad una soluzione.

GRAZIE MILLE!

1 Risposte

  • Re: Memorizziazione dati su Matlab

    Qualche considerazione prima della risposta:

    [*] il nocciolo del problema sembra essere la lettura del file di input: assumo che si tratti di un solo file nel quale sono presenti sia i dati relativi ai punti sia quelli relativi ai segmenti
    [*] nella descrizione del file di input manca la quella relativa alle facce, le sole informazioni sono quelle relative ai loro puntatori
    [*] assumo che i valori dei puntatori siano stati memorizzati come "indice di riferimento" per identificare i vari punti / segmenti; diversamente non avrebbe senso caricarli nel workspace.
    MatLab gestisce i valori esadecimali come stringhe di caratteri
    [*] la scelta del tipo di variabile nel quale caricare i dati in input dovrebbe essere effettuata in funzione della tipologia di dato (numero, stringa, ...) e dell'utilizzo che se ne vuole fare; non voglio discutere il suggerimento che hai avuto (Mi hanno consigliato di salvare i dati in dei vettori/matrici e non in strutture più complesse), ma la tipologia di dati presenti nel file di input suggerisce,invece, di usare "strutture più complesse", nella fattispecie proprio della variabili di tipo "struct"
    [*] con riferimento alla considerazione precedente, nella domanda non è specificato quale sarà l'utilizzo dell e informazioni lette dal file di input; questo influisce sulla scelta del tipo di variabile da usare nel caricare i dati nel workspace

    Lettura del file di input

    Considerando che il numero di campi di ogni riga non è costante, si può utilizzare la funzione "fgetl" per leggere una riga alla volta, quindi, usare le funzioni "textscan" e "strtok" per estrarre il contenuto dei vari campi.
    La funzione "textscan" ritorna un cellarray, per cui, in alcuni casi può essere utile convertirne il contenuto in stringhe o array con rispettivamente, la funzione "char" o l'operatore "[]".
    Per convertire le stringhe con i valori esadecimali in nemeri interi si può usare la funzione "hex2dec".

    Assegnazione dei valori letti alle variabili
    Come detto in precedenza, la scelta del tipo di variabile dipende dal tipo di dati e dall'uso che se vuole fare nello script.
    I dati presenti nel file di input sono di "tipo" diverso (stringhe - puntatori; numeri - coordinate dei punti) per cui i tipi di variabili più convenienti sembrano essere "struct" e / o cellarray.
    E' tuttavia possibile utilizzare vettori e / o matrici.

    Le procedure sopra descritte sono state implementate nello script che segue; allo scopo di testare il script, è stato creato un file di testo contenente i dati di input inseriti nella domanda; a questi sono stati aggiunte due ulteriori righe nella sezione "Segmenti".
    Per ogni campo contenente "puntatori", i valori esadecimali sono stati anche convertiti i numeri decimali per facilitarne l'uso (ad esempio con la funzione "find")

    Lo script genera le seguenti strutture dati:
    struct point_data
       point_data.ptr ==> puntatore (stringa di caratteri)
       point_data.val ==> valore decimale del puntatore
       point_data.coord ==> array (1x3) con le coordinate del punto
    
    struct segment_data
          segment_data.seg_ptr ==> puntatore (stringa di caratteri)
          segment_data.seg_val ==> valore decimale del puntatore
          segment_data.start_point_ptr ==> puntatore (stringa di caratteri)  punto iniziale del segmento
          segment_data.start_point_val ==> valore decimale del puntatore al punto iniziale del segmento
          segment_data.end_point_ptr ==> puntatore (stringa di caratteri) punto finale del segmento
          segment_data.end_point_val ==> valore decimale del puntatore al punto finale del segmento
          segment_data.faces_ptr ==> matrice dei puntatori alle facce (matrice di stringhe)
          segment_data.faces_ ==> matrice valori decimale dei puntatori alle facce (matrice di stringhe)
          segment_data.n_faces ==> numero facce per il singolo segmento
    
    point_ptr           ==> matrice contenente i valori decimali dei puntatori
    point_coord       ==> matrice contenente coordinate dei punti (per righe)
    segment_points ==> matrice contenente i valori decimali dei puntatori dei segmenti
    
    A titolo di esempio e test, nello script sono stati inseriti due esempi di utilizzo delle strutture dati generate:

    Esempio 1:
    utilizzo delle strutture dati: Ricerca delle coordinate dei punti iniziali e finali di un segmento

    Esempio 2:
    utilizzo delle strutture dati: Ricerca dei segmenti dei quali i punti sono "punto iniziale" o "punto finale"

    Si riporta, di seguito, il file di input generato:

    File di input "punti_segmenti.txt"
    
    Punti
    00B5BCD0 - 0.000000 4.000000 2.000000 
    00B5BCA0 - 4.000000 4.000000 2.000000
    Segmenti
    00B5C668 - 00B5BCA0 -> 00B5BCD0 facce: 00B5CA70 00B5CA30 0043EC80 00B5C830
    00B5C668 - 00B5BCA0 -> 00B5BCD0 facce: 00B5CA70 00B5CA30 0043EC80 00B5C830
    00B5C710 - 00B5BBE0 -> 00B5BBB0 facce: 00B5CA30 00B5AF58 00B5C870 
    00B5C668 - 00B5BCD0 -> 00B5BCA0 facce: 00B5CA70 00B5CA30 0043EC80 00B5C830
    
    Script "leggi_punti_segmenti.m"
    
    % 
    % Apertura del file di input "punti.txt'
    % 
    fp=fopen('punti_segmenti.txt','rt');
    % 
    % Inizializzazione contatore punti
    % 
    cnt=0;
    % 
    % Loop lettura (riga pe riga) file di input
    % 
    read_punti=0;
    read_segmenti=0;
    while(1)
       tline=fgetl(fp);
       if(~ischar(tline))
          break
       end
       if(strcmp(tline,'Punti'))
          read_punti=1;
          read_segmenti=0;
          cnt=0;
          continue
       end
       if(strcmp(tline,'Segmenti'))
          read_punti=0;
          read_segmenti=1;
          cnt=0;
          continue
       end
       if(read_punti)
       cnt=cnt+1;
    %    
    %    Scansione della riga per l'estrazione delle informazioni
    %    
       C=textscan(tline,'%s%c%f%f%f');
    %    
    %    Creazione della struttura dati "point_data":
    %       point_data.ptr ==> puntatore (stringa di caratteri)
    %       point_data.val ==> valore decimale del puntatore
    %       point_data.coord ==> array (1x3) con le coordinate del punto
    %    
       point_data(cnt).ptr=char(C{1});
       point_data(cnt).val=hex2dec(char(C{1}));
       point_data(cnt).coord=[C{3:end}];
       elseif(read_segmenti)
       cnt=cnt+1;
    %    
    %    Scansione della riga per l'estrazione delle informazioni e creazione
    %    della struttura dati "segment_data"
    %       segment_data.seg_ptr ==> puntatore (stringa di caratteri)
    %       segment_data.seg_val ==> valore decimale del puntatore
    %       segment_data.start_point_ptr ==> puntatore (stringa di caratteri)
    %                                        punt iniziale del segmento
    %       segment_data.start_point_val ==> valore decimale del puntatore al
    %                                        punto iniziale del segmento
    %       segment_data.end_point_ptr ==> puntatore (stringa di caratteri)
    %                                        punto finale del segmento
    %       segment_data.end_point_val ==> valore decimale del puntatore al
    %                                        punto finale del segmento
    %       segment_data.faces_ptr ==> matrice dei puntatori alle facce
    %                                  (matrice di stringhe)
    %       segment_data.faces_ ==> matrice valori decimalei dei puntatori
    %                               alle facce (matrice di stringhe)
    %       segment_data.n_faces ==> numere facce per il singolo segmento
    %
       [segment_data(cnt).seg_ptr,rim]=strtok(tline);
       segment_data(cnt).seg_val=hex2dec(segment_data(cnt).seg_ptr);
       [tmp,rim]=strtok(rim);
       [segment_data(cnt).start_point_ptr,rim]=strtok(rim);
       segment_data(cnt).start_point_val=hex2dec(segment_data(cnt).start_point_ptr);
       [tmp,rim]=strtok(rim);
       [segment_data(cnt).end_point_ptr,rim]=strtok(rim);
       segment_data(cnt).end_point_val=hex2dec(segment_data(cnt).end_point_ptr);
       [tmp,rim]=strtok(rim);
       f_cnt=0;
       C=textscan(rim,'%s');
       segment_data(cnt).faces_ptr=char(C{:});
       segment_data(cnt).faces_val=hex2dec(segment_data(cnt).faces_ptr)';
       segment_data(cnt).n_faces=length(segment_data(cnt).faces_val);
       end
    end
    % 
    % Creazione della matrice che contiene i valori decimali dei puntatori
    % 
    point_ptr=[point_data(:).val];
    % 
    % Creazione della matrice che contiene le coordinate dei punti (per righe)
    % 
    point_coord=reshape([point_data(:).coord],3,length(point_data))';
    disp(['Numero punti letti: ' num2str(length(point_data))])
    % 
    % Creazione della matrice con i valori decimali dei puntatori dei segmenti
    % 
    segment_points=[segment_data(:).start_point_val;segment_data(:).end_point_val]';
    disp(['Numero segmenti letti: ' num2str(length(segment_data))])
    % 
    % Chiusura del file "segmenti.txt"
    % 
    fclose(fp);
    % 
    % Esempio di utilizzo delle strutture dati: Ricerca delle coordinate dei
    % punti iniziali e final di un segmento
    %    
    for i=1:length(segment_data)
       seg_start_point=segment_data(i).start_point_val;
       seg_end_point=segment_data(i).end_point_val;
       start_point_idx=find(point_ptr == seg_start_point);
       if(isempty(start_point_idx))
          disp(['Punto iniziale segmento ' segment_data(i).seg_ptr ' non trovato'])
          disp(' ')
       else
          disp(['Puntatore punto iniziale segmento ' segment_data(i).seg_ptr ...
             ' = ' point_data(start_point_idx).ptr])
          disp(['Coordinate punto iniziale segmento ' segment_data(i).seg_ptr ' = '])
          point_data(start_point_idx).coord
       end
       end_point_idx=find(point_ptr == seg_end_point);
       if(isempty(end_point_idx))
          disp(['Punto finale segmento ' segment_data(i).seg_ptr  ' non trovato'])
          disp(' ')
       else
          disp(['Puntatore punto finale segmento ' segment_data(i).seg_ptr ...
             ' = ' point_data(end_point_idx).ptr])
          disp(['Coordinate punto finale segmento ' segment_data(i).seg_ptr ' = '])
          point_data(end_point_idx).coord
       end
    end
    % 
    % Esempio di utilizzo delle strutture dati: Ricerca dei segmenti dei quali
    % i punti sono "punto iniziale" o "punto finale"
    %    
    for i=1:length(point_data)
       point_idx=point_data(i).val;
       segment_idx=find(segment_points(:,1) == point_idx)
       if(isempty(segment_idx))
          disp(['Punto ' point_data(i).ptr ': non punto iniziale di un segmento'])
       else
          disp(['Punto ' point_data(i).ptr ': punto finale di ' ...
             num2str(length(segment_idx)) ' segmenti'])
          str=sprintf('%s ',segment_data(segment_idx).seg_ptr)
       end
       segment_idx=find(segment_points(:,2) == point_idx)
       if(isempty(segment_idx))
          disp(['Punto ' point_data(i).ptr ': non punto iniziale di un segmento'])
       else
          disp(['Punto ' point_data(i).ptr ': punto finale di ' ...
             num2str(length(segment_idx)) ' segmenti'])
          str=sprintf('%s ',segment_data(segment_idx).seg_ptr)
       end
    end
    
    Hope this helps.
Devi accedere o registrarti per scrivere nel forum
1 risposte