[英]How to plot 3D contours on a 3D surface (built by patch) in MATLAB?
[英]Showing 3D data on a patch surface with Matlab
我想用Matlab顯示物體表面的溫度分布。
我有(x,y,z,V)向量形式的3D數據。 我想在Matlab中顯示該對象,其顏色代表本地總的“值”。
我可以將對象導出為STL文件。 使用STL繪圖可以很容易地顯示它(請參閱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');
要根據(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';
將點的體積標量值(在您的情況下為Temperature)附加到相鄰點是一項棘手的練習,需要復雜的for
循環並定義特殊情況規則(在您的情況下,您希望將2個不同的點的值附加到同一點補丁頂點,如果要附加的兩個值不同怎么辦?您平均嗎?丟棄?)。
一種更安全的方法是在物體表面上重新插入溫度場。 函數griddata
可以為您完成此任務。
首先,我必須定義一個標量字段。 由於我沒有溫度數據,因此使用Matlab的flow
函數。 我生成了與本文相同的標量字段: 流數據 。
這給了我每個坐標x, y, z
的標量場v
(流量值,但可以說是你的溫度)。
然后,我創建並介紹了一個3D補丁,它將成為您的對象。 我選擇了一個球體,但是任何3D補丁都將以相同的方式工作。 從surf2patch
借來獲取作為補丁的球體的代碼
您將必須對球體進行偏移和膨脹才能使其完全如下圖所示
現在是有趣的一點。 在以下代碼中, v
是在坐標x, y, z
處的標量場(對您而言的溫度)的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) ;
現在,您的對象表面處於正確的插值溫度:
如果您想單獨觀察面片,則可以刪除切片平面
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.