2012-10-12 6 views
10

J'ai un ensemble de données qui décrit un nuage de points d'un cylindre 3D (xx,yy,zz,C): 3D point cloudsurface Interpolate du cylindre 3D dans Matlab

et je voudrais faire une parcelle de surface de cet ensemble de données, similaire à ce enter image description here

pour ce faire, je pensais que je pouvais interpoler mes données dispersées à l'aide TriScatteredInterp sur une grille régulière puis tracer à l'aide 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 

Cela fonctionne très bien pour les objets convexes et concaves, mais se termine dans ce pour le cylindre: enter image description here

Quelqu'un peut-il me aider à la façon d'atteindre une plus belle parcelle?

Répondre

0

Un cylindre est la collection de tous les points équidistants d'une ligne. Donc, vous savez que vos données xx, yy et zz ont une chose en commun, et c'est qu'ils doivent tous se trouver à égale distance de la ligne de symétrie. Vous pouvez l'utiliser pour générer un nouveau cylindre (ligne de symétrie pris comme axe z dans cet exemple):

% 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

Je suis désolé mais ce n'est pas tout à fait ce que je suis après. Plutôt que d'installer un nouveau cylindre, je voudrais tracer une surface basée sur le nuage de points mesuré. J'ai essayé avec la triangulation auparavant mais cela ne produit pas tout à fait les bons résultats pour moi car beaucoup de mes points de données ne sont plus présents sur la carte. –

0

TriScatteredInterp est bon pour les surfaces en 2D de montage de la forme z = f (x, y), où f est une fonction à valeur unique. Cela ne fonctionnera pas pour s'adapter à un nuage de points comme vous l'avez fait. Comme vous avez affaire à un cylindre, qui est essentiellement une surface 2D, vous pouvez toujours utiliser TriScatterdInterp si vous convertissez en coordonnées polaires, et, par exemple, adapter le rayon en fonction de l'angle et de la hauteur-- quelque chose comme:

% 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

Je pense que ce que vous cherchez est la fonction Convex hull. Voir sa documentation.

K = convhull (X, Y, Z) retourne l'enveloppe convexe 3-D des points (X, Y, Z), où X, Y et Z sont des vecteurs de colonne. K est une triangulation représentant la limite de la coque convexe. K est de taille mtri-par-3, où mtri est le nombre de facettes triangulaires. C'est-à-dire que chaque ligne de K est un triangle défini en termes d'indices de points.

Exemple 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

Utiliser une parcelle à la sortie du convhull en 2D. Utilisez trisurf ou trimesh pour tracer la sortie de convhull en 3-D.