2012-10-12 111 views
10

I tiene un conjunto de datos que describe una nube de puntos de un cilindro 3D (xx,yy,zz,C): 3D point cloudInterpolar superficie del cilindro 3D en Matlab

y me gustaría hacer una gráfica de superficie a partir de este conjunto de datos, similar a esta enter image description here

con el fin de hacer esto pensé que podría interpolar mis datos dispersos que utilizan TriScatteredInterp sobre una rejilla regular y luego trazar usando 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 

Esto funciona muy bien para los objetos convexos y cóncavos, pero termina en esto para el cilindro: enter image description here

¿Puede alguien ayudarme en cuanto a cómo lograr una parcela más agradable?

Respuesta

0

Un cilindro es la colección de todos los puntos equidistantes de una línea. Entonces, usted sabe que sus datos xx, yy y zz tienen algo en común, y es que todos deben estar a la misma distancia de la línea de simetría. Puede utilizar que para generar un nuevo cilindro (línea de simetría tomado para ser el eje z en este ejemplo):

% 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

Lo siento, pero eso no es lo que busco. En lugar de instalar un cilindro nuevo, me gustaría trazar una superficie basada en la nube de puntos medida. Intenté con la triangulación antes, pero esto no me produce los resultados correctos, ya que muchos de mis puntos de datos ya no aparecen en el mapa. –

0

TriScatteredInterp es bueno para superficies 2D de ajuste de la forma z = f (x, y), donde f es una función de un solo valor. No funcionará para adaptarse a una nube de puntos como la que tiene.

Dado que se trata de un cilindro, que es, en esencia, una superficie 2D, aún puede usar TriScatterdInterp si convierte a coordenadas polares y, por ejemplo, ajusta el radio en función del ángulo y la altura-- algo como:

% 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

Creo que lo que está buscando es la función Convex hull. Vea su documentación.

K = convhull (X, Y, Z) devuelve el casco convexo 3-D de los puntos (X, Y, Z), donde X, Y, y Z son vectores de columna. K es una triangulación que representa el límite del casco convexo. K es de tamaño mtri-by-3, donde mtri es el número de facetas triangulares. Es decir, cada fila de K es un triángulo definido en términos de los índices de puntos.

Ejemplo en 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

Uso parcela para trazar la salida de convhull en 2D. Usa trisurf o trimesh para trazar la salida de convhull en 3-D.

Cuestiones relacionadas