用Matlab在贴片曲面上显示三维数据

用Matlab在贴片曲面上显示三维数据,matlab,plot,3d,Matlab,Plot,3d,我想用Matlab展示物体表面的温度分布 我得到了(x,y,z,V)向量形式的三维数据。我想在Matlab中展示这个对象,用颜色表示局部总“值” 我可以将对象导出为STL文件。可以使用STL绘图轻松显示(请参阅): 要根据(x,y,z,V)给它上色,我需要将每个(x,y,z)点附加到面片中的一个顶点上(最近的一个可以)。如果有多个(x、y、z)点的单个STL顶点最接近,我将该顶点对应的V值相加 顶点的数量是数千。(x,y,z)点的数量也很大。因此,通过(x,y,z)点进行循环,然后在顶点上进行内

我想用Matlab展示物体表面的温度分布

我得到了(x,y,z,V)向量形式的三维数据。我想在Matlab中展示这个对象,用颜色表示局部总“值”

我可以将对象导出为STL文件。可以使用STL绘图轻松显示(请参阅):

要根据(x,y,z,V)给它上色,我需要将每个(x,y,z)点附加到面片中的一个顶点上(最近的一个可以)。如果有多个(x、y、z)点的单个STL顶点最接近,我将该顶点对应的V值相加

顶点的数量是数千。(x,y,z)点的数量也很大。因此,通过(x,y,z)点进行循环,然后在顶点上进行内部循环,以找到最近的一个(这涉及计算点之间的距离),这是毫无疑问的。有什么聪明的方法可以快速完成吗

注:我无法控制数据点的位置,它们由外部程序定义。STL点由另一个外部程序控制。所以我必须嫁给两个不同的点集

以下代码说明了我想要实现的目标,其中包含4个顶点和3个数据点:

% 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';

将一个点的体积标量值(在您的情况下是温度)附加到相邻点是一个棘手的练习,需要复杂的
for
循环和定义特殊的案例规则(在您的情况下,您希望将两个不同点的值附加到同一面片顶点,如果要附加的两个值不同怎么办?是否平均?放弃?)

一个更安全的方法是在物体表面重新插值温度场。这个函数可以帮你做到这一点

首先,我必须定义一个标量场。由于我没有您的温度数据,我使用Matlab中的
flow
函数。我以与本文相同的方式生成标量场:。
这给了我一个标量场
v
(流量值,但假设是你的温度),在每个坐标
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) ;

然后我创建并引入了一个3D面片,它将成为你的对象。我选择了一个球体,但任何3D面片都会以同样的方式工作。 从
您必须偏移球体并使其膨胀,以使其完全如下图所示

现在是有趣的一点。在下面的代码中,
v
是坐标
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) ;
对象曲面现在处于正确的插值温度:
如果要单独观察面片,可以删除切片平面


在这种情况下,an会有很大帮助。尽量提供人们可以使用的最小数据子集,否则他们将不得不生成样本数据,而不是每个人都会这样做……还有,温度数据是如何计算的?您能将补丁点提供给计算温度分布的函数吗贡献?这将使整个练习变得更简单(只需在
CData
colormap
上进行一些设置)@Hoki,我添加了一个示例,希望能够解释我试图实现的目标。我无法计算温度和预定义的点(x,y,z)点由外部建模软件以自己的方式定义。你的解决方案很好,但由于问题陈述不正确,它对我不起作用。我在没有注意到它改变含义的情况下对其进行了过度简化。我的场不是温度,而是“热辐射源”。我需要计算(并显示)表面上的负载。因此,基本上,原始(x,y,z,V)集中的每个点都可以被视为辐射源。这就是为什么可以将多个值添加到单个STL顶点。当然,我正在移动源位置,但这在这里是可以接受的(我也可以轻松优化STL网格)。我已经编辑了这个问题。但它将完全取决于STL网格的网格大小(大网格->两个源
A
B
分配给同一点,细网格->
A
B
分配给不同的点(甚至可能由它们之间的许多点分隔).根据辐射源的位置和强度计算体积中的辐射场,然后在物体表面上插值,不是更好吗?在这两种情况下,大小都是数千个点…读了你的答案后,我实际上是朝着同一个方向思考的。但我恐怕有一个问题。想象一下,我有一个问题STL网格的高辐射点和高密度。如果我直接将负载应用于STL网格,它将正确显示热点。如果我首先创建一个场网格,而该网格局部密度不够,我将引入一个可能严重的错误。我将检查它。当然,插值网格越粗糙,越平滑/场的平均值为。这适用于任何插值过程,但我仍然希望控制该网格大小(因为它是模型的一部分),而不是控制来自STL文件(引入模型的外部对象)的网格大小。