我正在尝试在 matlab 中制作一个 3d 环。以下是类似于我所做的事情:
t = linspace(0,2*pi);
rin = 0.1;
rout = 0.25;
xin = 0.5 + rin*cos(t);% 0.5 is the center of the ring
xout = 0.5 + rout*cos(t);
yin = 0.5 + rin*sin(t);
yout = 0.5 + rout*sin(t);
% Make patch
hp = patch([xout,xin],[yout,yin],'g','linestyle','none','facealpha',0.25);
现在,我想将其扩展到 3d 案例。我想给这枚戒指增加高度。但是当我尝试添加一个向量 [z1,z2]
where
z1=0.5*ones(size(xin));
z2=z1;
我尝试了 Z1 和 Z2 的不同组合,但我仍然无法找到解决方案。
最佳答案
如果您需要控制每个面的属性,我倾向于将 patch
用于对象的二维表面,如果您需要控制每个面的属性,否则对于您想要的体积 surf
是一个更容易处理的对象。
下面的示例展示了如何使用一个surface
完成此操作,但如果您真的需要使用patch
,也可以很容易地进行调整。
为了逐步解释,我从您创建的补丁开始。我计算中心线的坐标(在代码中称为ring
),然后显示它(突出显示起点)
%% // Ring properties
ring.x0 = 0.5 ; %// Center of ring
ring.y0 = 0.5 ; %// Center of ring
ring.radius = (0.25+0.1)/2 ; %// Radius of core circle profile
ring.nDiv = 37 ; %// number of divisions for the core circle profile
ring.theta = linspace(0,2*pi,ring.nDiv) ;
ring.X = cos(ring.theta) * ring.radius + ring.x0 ;
ring.Y = sin(ring.theta) * ring.radius + ring.y0 ;
%// plot (optional, just for intermediate visualisation)
hold on ; plot(ring.X,ring.Y) ; plot(ring.X(1),ring.Y(1),'ok')
view(18,72) ; xlabel('X') ; ylabel('Y') ; zlabel('Z') ;
渲染:
然后我创建一个基本的横截面:
%% // Create a base SQUARE cross section
Npts = 4 ;
cs.width = 0.25-0.1 ; %// width of each cross section square
cs.height = 0.25 ; %// height of each cross section square
%// first cross section is the the XZ plane
csY0 = zeros(1,Npts) ; %// will be used as base for rotating cross sections
csX = [-cs.width/2 cs.width/2 cs.width/2 -cs.width/2 ] ;
csZ = [-cs.height/2 -cs.height/2 cs.height/2 cs.height/2] ;
这定义了一个基本的正方形悬卡在原点周围的空间中,我将第一个放在适当的位置只是为了说明:
%% // plot (optional, just for intermediate visualisation)
hp0 = patch(csX+ring.X(1),csY0+ring.Y(1),csZ,'r','FaceAlpha',0.5) ;
view(164,38)
呈现:
现在我们只需要复制缠绕在主环
上的横截面:
%% Generate coordinates for each cross section and merge them
nCS = length(ring.X) ; %// number of cross sections composing the surface
%// pre-allocation is always good
X = zeros( nCS , Npts ) ;
Y = zeros( nCS , Npts ) ;
Z = zeros( nCS , Npts ) ;
for ip = 1:nCS
%// rotate the cross section (around Z axis, around origin)
Rmat = [ cos(ring.theta(ip)) -sin(ring.theta(ip)) ; ...
sin(ring.theta(ip)) cos(ring.theta(ip)) ] ;
csTemp = Rmat * [csX ; csY0] ;
%// translate the coordinates of cross section to final position and store with others
X(ip,:) = csTemp(1,:) + ring.X(ip) ;
Y(ip,:) = csTemp(2,:) + ring.Y(ip) ;
Z(ip,:) = csZ ;
end
现在您在 X
、Y
和 Z
中拥有了您定义的轮廓周围的点坐标,可以将其绘制成一个图形对象:
%% // Plot the final surface
hs = surf(X,Y,Z) ;
set(hs,'FaceColor',[.7 .7 .7],'FaceAlpha',0.5,'EdgeAlpha',0.2)
view(155,26)
呈现:
此方法的 2 个优点是:
- 只需处理一个图形对象(尽管仍然是通用的,CData 允许多种可能性)
- 横截面可以是任何,只需定义一次,然后重复该方法。
为了说明上面的第 2 点,只需将代码段 %%//Create a base square cross section
替换为这个圆形横截面:
%% // Create a base CIRCULAR cross section
cs.Ndiv = 13 ; %
cs.radius = (0.25-0.1)/2 ; %// Radius of each cross section circle
cs.rout = 0.25;
cs.theta = linspace(0,2*pi,cs.Ndiv) ;
Npts = length(cs.theta) ;
%// first cross section is the the XZ plane
csY0 = zeros(1,Npts) ; %// will be used as base for rotating cross sections
csX = sin(cs.theta) * cs.radius ;
csZ = cos(cs.theta) * cs.radius ;
其余代码相同,您将获得 donut :
无论如何我都包含了它,因为那是我的第一个答案,直到我从评论中意识到您想要一个圆柱体!
关于matlab - 使用 Patch 在 Matlab 中创建 3d Ring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27668343/