简体   繁体   中英

Showing 3D data on a patch surface with Matlab

I want to show, with Matlab, a temperature distribution on an object surface.

I've got a 3D data in the form of (x, y, z, V) vectors. I would like to show this object in Matlab, with the colour representing the local total "value".

I can export the object as an STL file. It can be shown easily using the STL plotting (see stldemo ):

fv = stlread('file.stl');
patch(fv, 'EdgeColor', 'none', 'FaceLighting', 'gouraud', 'AmbientStrength', 0.15, 'FaceColor', [0.8 0.8 1.0]);
camlight('headlight');
material('dull');

To colour it according to (x,y,z,V), I need to attach each (x, y, z) point to a vertex in the patch (the nearest one would work). If there are many (x,y,z) points for which a single STL vertex is the nearest, I add up the corresponding V values for that vertex.

The number of vertices is thousands. The number of (x, y, z) points is also large. So doing a loop through (x, y, z) points and then an internal loop over vertices to find the nearest one (which involves calculating distances between points) is out of question. Is there any smart way to do it quickly?

Note: I cannot control the location of the data points, they are defined by an external program. The STL points are controlled by another external program. So I have to marry two different point sets.

Here is the code illustrating what I want to achieve, with 4 vertices and 3 data points:

% Create patch
figure;
p = patch;
colorbar

p.Vertices = [...
    0, 0, 0; ...
    1, 0, 0; ...
    1, 1, 0;
    0, 1, 0];
p.Faces = [ ...
    1, 2, 3; ...
    1, 3, 4];

% Data points
x = [0.1, 0.1, 0.25];
y = [0.01, 0.02, 0.75];
z = [0.01, 0.2, -0.01];
v = [1, 1, 1];

p.FaceVertexCData = zeros(size(p.Vertices, 1), 1);
% Point 1 (0.1, 0.01, 0.01) is closest to vertex 1 (0, 0, 0). Its value
% goes to vertex 1.
p.FaceVertexCData(1) = p.FaceVertexCData(1) + v(1);
% Point 2 (0.1, 0.02, 0.2) is also closest to vertex 1 (0, 0, 0). Its
% value also goes to vertex 1
p.FaceVertexCData(1) = p.FaceVertexCData(1) + v(2);
% Point 3 (0.25, 0.75, -0.01) is closest to vertex 4 (0, 1, 0). Its power
% goes to vertex 4.
p.FaceVertexCData(4) = p.FaceVertexCData(4) + v(3);
% Other vertices are left with 0.

p.FaceColor = 'interp';

Attaching a volume scalar value (of Temperature in your case) of a point to a neighbouring point is a tricky exercise, requires complex for loops and defining special case rules (in your case you wanted to attach the value of 2 different points to the same patch vertex, what if the 2 values to attach are different? Do you average? discard ?).

A safer approach is to re-interpolate your temperature field over your object surface. the function griddata can do that for you.

First I had to define a scalar field. Since I do not have your temperature data, I use the flow function from Matlab. I generated a scalar field the same ways than in this article: flow data .
This gave me a scalar field v (flow value but let's say it's your temperature) at for every coordinates x, y, z .

流

Then I created and introduced a 3D patch which will be your object. I chose a sphere but any 3D patch will work the same way. The code to get the sphere as a patch is borrowed from surf2patch
you will have to offset and inflate the sphere to get it exactly as in the figure below

简单领域

Now is the interesting bit. In the following code, v is the value of the scalar field (temperature for you) at the coordinates x, y, z .

%% // Extract patch vertices coordinates in separate variables
xp = fv.vertices(:,1) ;
yp = fv.vertices(:,2) ;
zp = fv.vertices(:,3) ;

%% // interpolate the temperature field over the patch coordinates
Tpv = griddata(x,y,z,v,xp,yp,zp) ;

%% // Set the patch color data to the new interpolated temperature
set(hp,'FaceVertexCData',Tpv) ;

And your object surface is now at the right interpolated temperature:
you can delete the slice plane if you want to observe the patch alone

最终的

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM