2012-10-12 23 views
10

Ho un set di dati che descrive una nuvola di punti di un cilindro 3D (xx,yy,zz,C): 3D point cloudInterpola superficie del cilindro 3D in Matlab

e vorrei fare una trama superficiale da questo set di dati, simile a questo enter image description here

per fare questo ho pensato che avrei potuto interpolare i miei dati sparsi utilizzando TriScatteredInterp su una griglia regolare e poi tracciare utilizzando surf:

F = TriScatteredInterp(xx,yy,zz); 
max_x = max(xx); min_x = min(xx); 
max_y = max(yy); min_y = min(yy); 
max_z = max(zz); min_z = min(zz); 
xi = min_x:abs(stepSize):max_x; 
yi = min_y:abs(stepSize):max_y; 
zi = min_z:abs(stepSize):max_z; 
[qx,qy] = meshgrid(xi,yi); 
qz = F(qx,qy); 
F = TriScatteredInterp(xx,yy,C); 
qc = F(qx,qy); 

figure 
surf(qx,qy,qz,qc); 
axis image 

questo funziona molto bene per gli oggetti concave e convesse, ma finisce in questo per il cilindro: enter image description here

Qualcuno può aiutarmi su come ottenere una trama più bello?

risposta

0

Un cilindro è la raccolta di tutti i punti equidistanti da una linea. Quindi sai che i tuoi dati xx, yy e zz hanno una cosa in comune, e cioè che dovrebbero trovarsi tutti alla stessa distanza dalla linea di simmetria. È possibile utilizzare che per generare un nuovo cilindro (linea di simmetria assunto come asse z in questo esempio):

% best-fitting radius 
% NOTE: only works if z-axis is cylinder's line of symmetry 
R = mean(sqrt(xx.^2+yy.^2)); 

% generate some cylinder 
[x y z] = cylinder(ones(numel(xx),1)); 

% adjust z-range and set best-fitting radius 
z = z * (max(zz(:))-min(zz(:))) + min(zz(:)); 
x=x*R; 
y=y*R; 

% plot cylinder 
surf(x,y,z) 
+0

Mi dispiace ma non è proprio quello che sto cercando. Piuttosto che montare un nuovo cilindro, vorrei tracciare una superficie basata sulla nuvola di punti misurata. Ho provato prima con la triangolazione, ma questo non produce i risultati giusti per me, visto che molti dei miei punti di riferimento non sono più presenti sulla mappa. –

0

TriScatteredInterp è buono per superfici accoppiate 2D della forma z = f (x, y), dove f è una funzione a valore singolo. Non funzionerà per adattarsi a una nuvola di punti come hai fatto tu.

Poiché si ha a che fare con un cilindro, che in sostanza è una superficie 2D, è ancora possibile utilizzare TriScatterdInterp se si converte in coordinate polari e, ad esempio, si adattano al raggio in funzione di angolo e altezza-- qualcosa come:

% convert to polar coordinates: 
theta = atan2(yy,xx); 
h = zz; 
r = sqrt(xx.^2+yy.^2); 

% fit radius as a function of theta and h 
RFit = TriScatteredInterp(theta(:),h(:),r(:)); 

% define interpolation points 
stepSize = 0.1; 
ti = min(theta):abs(stepSize):max(theta); 
hi = min(h):abs(stepSize):max(h); 
[qx,qy] = meshgrid(ti,hi); 
% find r values at points: 
rfit = reshape(RFit(qx(:),qy(:)),size(qx)); 
% plot 
surf(rfit.*cos(qx),rfit.*sin(qx),qy) 
1

Penso che quello che stai cercando è la funzione Convex hull. Vedi la sua documentazione.

K = convhull (X, Y, Z) restituisce convesso 3-D dei punti (X, Y, Z), dove X, Y, e Z sono vettori colonna. K è una triangolazione che rappresenta il limite dello scafo convesso. K è di dimensione mtri-by-3, dove mtri è il numero di faccette triangolari. Cioè, ogni riga di K è un triangolo definito in termini di indici di punti.

Esempio in 2D

xx = -1:.05:1; yy = abs(sqrt(xx)); 
[x,y] = pol2cart(xx,yy); 
k = convhull(x,y); 
plot(x(k),y(k),'r-',x,y,'b+') 

enter image description here

Usa complotto per tracciare l'output di convhull in 2D. Usa trisurf o trimesh per tracciare l'output di convhull in 3-D.

Problemi correlati