在使用补丁的Matlab的3d圆环

Umz*_*Umz 2 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);
Run Code Online (Sandbox Code Playgroud)

现在,我想将其扩展到3d案例.我想给这个戒指增加高度.但是,当我尝试添加一个载体[z1,z2],其中

z1=0.5*ones(size(xin));
z2=z1;
Run Code Online (Sandbox Code Playgroud)

我尝试过不同的Z1和Z2组合仍然无法找到解决方案.

Hok*_*oki 5

我倾向于保持patch对象的2D表面的使用,如果你需要控制每个面的属性,那么对于你想要的卷来说,这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') ;
Run Code Online (Sandbox Code Playgroud)

呈现: 你的补丁

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

%% // 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] ;
Run Code Online (Sandbox Code Playgroud)

这定义了一个悬挂在原点周围空间的基本方形,我将第一个放置在原位,只是为了说明:

%% // plot (optional, just for intermediate visualisation)
hp0 = patch(csX+ring.X(1),csY0+ring.Y(1),csZ,'r','FaceAlpha',0.5) ;
view(164,38)
Run Code Online (Sandbox Code Playgroud)

哪个呈现: 第一个横截面

现在我们只需要复制包裹在master下的横截面ring:

%% 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
Run Code Online (Sandbox Code Playgroud)

现在,你有X,YZ点的坐标周围的轮廓您定义,准备在一个图形对象绘制:

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

哪个呈现: 整个表面


关于这种方法的两点好处是:

  • 只有一个图形对象可以处理(虽然仍然多功能,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 ;
Run Code Online (Sandbox Code Playgroud)

剩下的代码是一样的,你会得到你的甜甜圈: 甜甜圈

无论如何,我把它包括在内,因为那是我的第一个答案,直到我从评论中意识到你想要一个圆柱体!