2012-10-12 40 views
10

Tôi có một bộ dữ liệu mô tả một đám mây điểm của một xi lanh 3D (xx,yy,zz,C): 3D point cloudsuy bề mặt xi lanh 3D trong Matlab

và tôi muốn thực hiện một âm mưu bề mặt từ tập dữ liệu này, tương tự như này enter image description here

để làm được điều này, tôi nghĩ tôi có thể suy dữ liệu nằm rải rác của tôi sử dụng TriScatteredInterp vào lưới thông thường và sau đó âm mưu sử dụng nó 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 

Điều này hoạt động thực sự tốt cho các đối tượng lồi và lõm nhưng kết thúc trong hình trụ này: enter image description here

Có thể giúp tôi làm cách nào để đạt được âm mưu đẹp hơn không?

Trả lời

0

Một hình trụ là bộ sưu tập của tất cả các điểm cách nhau bằng một dòng. Vì vậy, bạn biết rằng dữ liệu xx, yyzz của bạn có một điểm chung và đó là tất cả chúng nên nằm ở khoảng cách tương đương với đường đối xứng. Bạn có thể sử dụng để tạo ra một xi lanh mới (dòng đối xứng đưa đến là trục z trong ví dụ này):

% 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

Tôi xin lỗi nhưng đó không hoàn toàn là những gì tôi đang làm. Thay vì lắp một hình trụ mới, tôi muốn vẽ một bề mặt dựa trên đám mây điểm được đo. Tôi đã thử với triangulation trước nhưng điều này không tạo ra kết quả đúng cho tôi hoặc là rất nhiều datapoints của tôi sau đó không còn tính năng trên bản đồ. –

0

TriScatteredInterp là tốt cho bề mặt 2D phù hợp có dạng z = f (x, y), trong đó f là hàm đơn giá trị. Nó sẽ không hoạt động để phù hợp với một đám mây điểm như bạn có.

Vì bạn đang xử lý một hình trụ, trên thực tế, bề mặt 2D, bạn vẫn có thể sử dụng TriScatterdInterp nếu bạn chuyển đổi sang tọa độ cực và bán kính phù hợp như một hàm của góc và chiều cao-- một cái gì đó như:

% 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

Tôi nghĩ rằng những gì bạn đang loking là chức năng Convex hull. Xem tài liệu của nó.

K = convhull (X, Y, Z) trả về thân lồi 3-D của điểm (X, Y, Z), trong đó X, Y, và Z là vectơ cột. K là một triangulation đại diện cho ranh giới của vỏ lồi. K có kích thước mtri-by-3, trong đó mtri là số các mặt hình tam giác. Tức là, mỗi hàng của K là một tam giác được xác định theo các chỉ số điểm.

Ví dụ trong 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

Sử dụng âm mưu mưu đầu ra của convhull trong 2D. Sử dụng trisurf hoặc trimesh để vẽ đầu ra của convhull trong 3-D.