Construct volumetric mesh grid by interpolating scattered point cloud.

9 次查看(过去 30 天)
I have a set of data that can be viewed as a scattered point cloud, each data point has an x,y,z, coordinate and a value(power).
These data points are evenly spaced along a range (r) from an origin and are distributed angularly (azimuth and elevation). That is x = r*sind(az).*cosd(el); y = r*cosd(az).*cosd(el); z = r*sind(el).
Using TriScatteredInterp() I can plot nice looking mesh grids at each range bin. These are "flat" surfaces that use color to show the power from each data point. The problem is the power is only interpolated using data from a single range bin, and nothing above or below. So I would like to plot/construct a "volumetric mesh" for multiple range bins. That is, I would like to use an interpolation method to form a solid mesh, where the points and values are interpolated not just at each range bin (each surface), but from higher and lower ranges.
I thought that I could use TriScatteredInterp() to accomplish this but I dont think it works the way I thought/wanted it to.
Here is a code snippet I used to create the surface.
for ii =1:spc:range
F = TriScatteredInterp(xx,yy,zz, 'natural');
max_x = max(xx); min_x = min(xx);
max_y = max(yy); min_y = min(yy);
max_z = max(zz); min_z = min(zz);
stepSize = (abs(min_x)-abs(max_x))*.05;
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);
% Interpolate power at the data points to create color overlay for mesh
F = TriScatteredInterp(xx,yy,power, 'natural');
C = F(qx,qy);
surf(qx,qy,qz,C);
alpha(.5);
shading interp
end
This made nice surfaces separated by some user defined spacing. So I thought I could naturally extend this to 3 dimensions, that is to construct a solid mesh.
power = ones(length(xx),1);
F = TriScatteredInterp(xx,yy,zz, power, 'natural');
max_x = max(xx); min_x = min(xx);
max_y = max(yy); min_y = min(yy);
max_z = max(zz); min_z = min(zz);
stepSize = (abs(min_x)-abs(max_x))*.01;
xi = min_x:abs(stepSize):max_x;
yi = min_y:abs(stepSize):max_y;
zi = min_z:abs(stepSize):max_z;
[qx,qy,qz] = meshgrid(xi,yi,zi);
qV = F(qx,qy,qz);
p2 = patch(isosurface(qx,qy,qz,qV,1),'FaceColor','blue',...
'EdgeColor','none');
axis tight
camlight
lighting gouraud
Note: the line power = ones(length(xx), 1) is just there so that when I plot the isosurface, everything is plotted. (using isosurfaces may be part of the problem).
This did kinda made a solid, but not quite what I had in mind. It actually made many little solids, various tetrahedrons , that where interspersed with blank space, and lots of NaNs. So the whole object was more of a cloud, a collection of small tetrahedrons. It was kind of in the shape that I had envisioned, but not what I wanted at all.
And yes, I checked to see if the interpolate was being evaluated within the convexhull of the data points, and it is. Many of the blank spaces (NaNs) are within the convexhull.
So I then tried a test case of a cube.
a = [0 0 0; 0 0 1; 0 1 0; 1 0 0; 1 1 0; 1 0 1; 0 1 1; 1 1 1];
x = a(:,1); y = a(:,2); z = a(:,3);
c = ones(length(x),1);
F = TriScatteredInterp(x,y,z,c);
[qx qy qz] = meshgrid([0:.01:1], [0:.01:1], [0:.01:1]);
qV = F(qx, qy, qz);
p2 = patch(isosurface(qx,qy,qz,qV,1),'FaceColor','blue',...
'EdgeColor','red');
axis tight
camlight
lighting gouraud
I thought that this would give me a solid volume in the shape of a cube, where the points were interpolated using the data points x,y,z ie the corners of a cube. If you run this you will see that this is decidedly not the case.
So, either a) TriScatteredInterpt() does not do what i thought it and I have no idea what I am doing, or b) My data is not well formed for using TriScatteredInterpt() in this manner.
So I if anybody is still reading this and has any idea what i am actually trying to do, any help, hints, or tips would be appreciated. Thanks for your patience.
tl;dr I would like to use an interpolation method to construct a "solid mesh" from data points scattered in x,y,z coordinates.

回答(1 个)

Patrick Kalita
Patrick Kalita 2011-4-18
I'll hazard a guess at what's going on with your test case. I think TriScatteredInterp is doing the right thing, but you've set up sort of a degenerate case for isosurface to handle.
TriScatteredInterp is given vertices where c = 1 for each vertex, and gives you back a larger 3D array ( qV ) where each element is 1. I don't think there's any surprise there.
But now isosurface is going to try to form a surface by connecting the elements of qV that equal 1. So theoretically isosurface needs to try to connect every element of qV into a single surface -- which doesn't really make a lot of sense geometrically. In practice, however, not every element of qV is exactly equal to 1. There is some inevitable numerical noise:
>> max(qV(:)) - min(qV(:))
ans =
4.4409e-016
So the irregular "blobby" surfaces that isosurface creates are, I believe, just showing the places where the elements of qV transition between being slightly below 1 to slightly above 1 due to numerical noise.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by