在matlab中绘制圆环体上的圆

在matlab中绘制圆环体上的圆,matlab,plot,matlab-figure,Matlab,Plot,Matlab Figure,使用找到的答案,我能够画出一个漂亮的圆环。我想在这个圆环上画两个“圆”,第一个是标准的。第二个应该是随机的,可能像梯子一样,理想情况下在第一个的对面。它可能有点参差不齐,但应该保持在晶格的边缘上,并且应该连接回自身。这是我到目前为止所拥有的 am = 1.; rm = 3.; t = linspace(-pi,pi,16); p = linspace(0.,2.*pi,16); [t,p] = meshgrid(p,t); x = (rm + am.*cos(p)).*cos(t); y = (

使用找到的答案,我能够画出一个漂亮的圆环。我想在这个圆环上画两个“圆”,第一个是标准的。第二个应该是随机的,可能像梯子一样,理想情况下在第一个的对面。它可能有点参差不齐,但应该保持在晶格的边缘上,并且应该连接回自身。这是我到目前为止所拥有的

am = 1.;
rm = 3.;
t = linspace(-pi,pi,16);
p = linspace(0.,2.*pi,16);
[t,p] = meshgrid(p,t);
x = (rm + am.*cos(p)).*cos(t);
y = (rm + am.*cos(p)).*sin(t);
z = am.*sin(p);
hsurf = surf(x,y,z);
axis equal;
set(hsurf, 'FaceColor','interp','FaceAlpha',0.5,'EdgeAlpha',0.25);
hold on
plot3((rm+am.*cos(p)).*cos(t(8)),(rm+am.*cos(p)).*sin(t(8)),am.*sin(p), 'b', 'LineWidth',2);
我有标准的线圈,但没有锯齿状的。我一直试图通过指定顶点来指定另一个循环,但它似乎不起作用。我可以通过指定其顶点来指定此网格上的曲线吗?如果没有,有什么建议吗?谢谢你能提供的帮助

编辑:很抱歉刚才说得不清楚。下面的图片显示了我想要的。请注意,上面的代码给出了右边的圆圈,而左边的“圆圈”是手工绘制的,这是我想要自动完成的


如果希望(锯齿状或非锯齿状)圆的顶点与曲面的点匹配,则无需重新计算任何点。您可以简单地重复使用曲面的某些点,选择定义所需形状的路径

我将使用您的代码定义初始tore,只需稍加修改:我将使用大写字母表示定义矩阵的变量(小写字母表示简单的1D向量的变量)。因此,您的初始存储将变成:

%% // define initial tore
am = 1.; rm = 3.;
t = linspace(-pi,pi,16);
p = linspace(0,2.*pi,16);
[T,P] = meshgrid(p,t);
X = (rm + am.*cos(P)).*cos(T);
Y = (rm + am.*cos(P)).*sin(T);
Z = am.*sin(P);
hsurf = surf(X,Y,Z,'FaceColor','interp','FaceAlpha',0.5,'EdgeAlpha',0.25);
axis equal ; hold on
这没什么大不了的,但是在你用等式定义圆的情况下,这只允许有1D向量坐标。它使您的变量和工作空间更整洁,并减少错误和维度错误的风险

对于简单的圆,您可以像以前一样通过方程重新定义坐标(为了清晰起见,在这里开发)

但我想让你们注意另一种方式,只使用已经定义的曲面的点。这(i)消除了对新计算的需要,并且(ii)确保圆的顶点将与圆的某些顶点完全匹配

%% // another simple circle - extracted from the tore vertices
colID = 8 ;
xs = X(:,colID) ;
ys = Y(:,colID) ;
zs = Z(:,colID) ;
hpc = plot3(xs,ys,zs, 'b', 'LineWidth',2);
同样,为了清晰起见,还有额外的行,但是一旦您理解了正在发生的事情,就可以压缩代码。这两种不同的圆生成方法产生下图:

为了便于演示,我高亮显示了撕裂的顶点(小黑点),以便您可以查看圆顶点是否匹配


现在对于锯齿形圆,最后一种方法将更有趣。正如您所观察到的,为了得到一个圆坐标,我们只需提取每个矩阵坐标的一列。我们为
colID
使用了一个固定值来检索。为了“jagg”你的圆,我们只需要在列数中引入一个小扰动,所以我们偶尔会检索相邻的顶点坐标

以下代码生成一个围绕起始列ID变化的列ID。您可以定义最大总排列以及最大单个增量:

%% // generate index of columns to be retrieved
idxcol = zeros(size(X,1),1) ;
maxDeviation = 5 ;      %// total maximum deviation to the initial center line
maxPerturbation = 2 ;   %// max deviation for 1 increment

deviation = cumsum(randi([-maxPerturbation maxPerturbation],size(X,1),1)) ;
%// bound deviations to maximum values
deviation(deviation>maxDeviation)  = maxDeviation ;
deviation(deviation<-maxDeviation) = -maxDeviation ;

startColID = 8 ;
colID = startColID + deviation ;
%// close the profile by repeating first point in the end if it's not closed already
if colID(end) ~= colID(1) ; colID(end) = colID(1) ; end

这是一个围绕撕裂旋转的闭合轮廓,但线条与绘制的示例中的曲面线条不匹配。这是因为每次更改
x
索引时都会发生从一个列ID到另一个列ID的转换


为了纠正这种情况,我们可以使用
楼梯
功能:

%% // create a stepped profile
[xd,yd] = stairs(colID) ;

%% // display rectified jagged circle
npt = size(yd,1) ;
xcj = zeros(npt) ; ycj = xcj ; zcj = xcj ;
for k=1:npt
    xcj(k) = X( xd(k) , yd(k) ) ;
    ycj(k) = Y( xd(k) , yd(k) ) ;
    zcj(k) = Z( xd(k) , yd(k) ) ;
end
hpc = plot3(xcj,ycj,zcj, 'b', 'LineWidth',2);
现在将生成以下配置文件:

好多了。。。但是,当列ID为相同的
x
移动多个索引时,我们仍然会丢失定位点,以保持锯齿形圆轮廓与撕裂轮廓匹配。如果您的基本列偏差增量不止一个,您甚至会有更多的这些人工制品


为了完全纠正这一点,我们需要添加缺失的锚定点。我找不到一个内置函数来实现这一点,所以我采用了传统的循环方式。如果你能找到一些方法,请随意优化

%% // recreate index vectors with all the necessary anchor points
colX(1,1) = xd(1) ;
colY(1,1) = yd(1) ;
k = 2 ;
for t=2:size(yd,1)
    inc = sign(yd(t)-yd(t-1)) ;         %// define increment of 1 with correct sign
    ids = yd(t-1):inc:yd(t)-inc ;       %// range of index to be covered
    if isempty(ids) ; ids = yd(t) ; end %// catch corner cases

    %// now add these points to the list
    n = length(ids) ;
    colX(k:k+n-1,1) = xd(t-1) ;
    colY(k:k+n-1,1) = ids ;
    k=k+n;
end
%// close profile (add last point in the cases where it is necessary)
if inc ~= 0
    colX(end+1,1) = xd(end) ;
    colY(end+1,1) = yd(end) ;
end

%% // display fully rectified jagged circle
npt = size(colX,1) ;
xcj = zeros(npt) ; ycj = xcj ; zcj = xcj ;
for k=1:npt
    xcj(k) = X( colX(k) , colY(k) ) ;
    ycj(k) = Y( colX(k) , colY(k) ) ;
    zcj(k) = Z( colX(k) , colY(k) ) ;
end
现在,两列ID之间不再有间隙,锯齿圆的所有点都匹配曲面轮廓的一点:


如果希望(锯齿状或非锯齿状)圆的顶点与曲面的点匹配,则无需重新计算任何点。您可以简单地重复使用曲面的某些点,选择定义所需形状的路径

我将使用您的代码定义初始tore,只需稍加修改:我将使用大写字母表示定义矩阵的变量(小写字母表示简单的1D向量的变量)。因此,您的初始存储将变成:

%% // define initial tore
am = 1.; rm = 3.;
t = linspace(-pi,pi,16);
p = linspace(0,2.*pi,16);
[T,P] = meshgrid(p,t);
X = (rm + am.*cos(P)).*cos(T);
Y = (rm + am.*cos(P)).*sin(T);
Z = am.*sin(P);
hsurf = surf(X,Y,Z,'FaceColor','interp','FaceAlpha',0.5,'EdgeAlpha',0.25);
axis equal ; hold on
这没什么大不了的,但是在你用等式定义圆的情况下,这只允许有1D向量坐标。它使您的变量和工作空间更整洁,并减少错误和维度错误的风险

对于简单的圆,您可以像以前一样通过方程重新定义坐标(为了清晰起见,在这里开发)

但我想让你们注意另一种方式,只使用已经定义的曲面的点。这(i)消除了对新计算的需要,并且(ii)确保圆的顶点将与圆的某些顶点完全匹配

%% // another simple circle - extracted from the tore vertices
colID = 8 ;
xs = X(:,colID) ;
ys = Y(:,colID) ;
zs = Z(:,colID) ;
hpc = plot3(xs,ys,zs, 'b', 'LineWidth',2);
同样,为了清晰起见,还有额外的行,但是一旦您理解了正在发生的事情,就可以压缩代码。这两种不同的圆生成方法产生下图:

为了便于演示,我高亮显示了撕裂的顶点(小黑点),以便您可以查看圆顶点是否匹配


现在对于锯齿形圆,最后一种方法将更有趣。正如您所观察到的,为了得到一个圆坐标,我们只需提取每个矩阵坐标的一列。我们为
colID
使用了一个固定值来检索。为了“jagg”你的圆,我们只需要在列数中引入一个小扰动,所以我们偶尔会检索相邻的顶点坐标

下面的代码生成一个