matlab - 使用 Patch 在 Matlab 中创建 3d Ring

标签 matlab

我正在尝试在 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') ;

渲染: your patch

然后我创建一个基本的横截面:

%% // 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)

呈现: the first cross section

现在我们只需要复制缠绕在主上的横截面:

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

现在您在 XYZ 中拥有了您定义的轮廓周围的点坐标,可以将其绘制成一个图形对象:

%% // Plot the final surface
hs = surf(X,Y,Z) ;
set(hs,'FaceColor',[.7 .7 .7],'FaceAlpha',0.5,'EdgeAlpha',0.2)
view(155,26)

呈现: the full surface


此方法的 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 : the doughnut

无论如何我都包含了它,因为那是我的第一个答案,直到我从评论中意识到您想要一个圆柱体!

关于matlab - 使用 Patch 在 Matlab 中创建 3d Ring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27668343/

相关文章:

python - 从 Matlab 到 Python - 求解函数

image - Matlab:找到轮廓并拉直近乎矩形的图像

python - Matlab 中的稀疏矩阵向量乘法比 Python 更快吗?

user-interface - 你能限制哪些字符可以输入到 MATLAB GUI 编辑框中吗?

matlab - 如何标准化矩阵设置 0 为最小值,1 为最大值?

matlab - 我在 MATLAB 中有一些 GUI,我需要在不同的选项卡中查看它们

matlab:当 `hold off` 不是默认值时, 'add' 语句会永久更改 FigureNextplot 属性

matlab - 尝试基于现有函数创建符号函数时出现"Unable to prove literally"错误

matlab - 在对同一数据集进行训练后,您对两个完全相同的神经网络有何评价?

matlab - 在数据集中查找特定特征的算法