我有一系列的椭圆,知道它们的中心的尺寸和位置。我想绘制它们并通过它们中的每一个来创建一个3d管道。
在MATLAB中或在Python中的3D库中是否存在放样功能(如果是,哪个库)?另外,我想实时添加这些省略号,因此留在MATLAB中会更好。但是,如果有一个Python解决方案,我将如何实现它以在MATLAB和Python文件之间进行通信以维持实时链接。
我认为除了空洞之外它看起来像这样:
如果您能在MATLAB或Python中为此提供解决方案,那就太棒了。
答案 0 :(得分:2)
对于那些对以上答案的Python实现感兴趣的人:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
from matplotlib import cm
#Create the profile
Radii = [1, 1.5, 1, 0.8, 1.3, 0.6, 0.5]
Zradii = [0, 1, 5, 10, 12, 14, 16]
radius = CubicSpline(Zradii, Radii, bc_type=((1, 0.5), (1, 0.0)))
# Make data
thetarange = np.linspace(0, 2 * np.pi, 100)
zrange = np.linspace(min(Zradii), max(Zradii),100)
X = [radius(z)*np.cos(thetarange) for z in zrange]
Y = [radius(z)*np.sin(thetarange) for z in zrange]
Z = np.array([[z] for z in zrange])
# Plot the surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim3d(-2, 2)
ax.set_ylim3d(-2, 2)
ax.set_zlim3d(0, 20)
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
#Plot the circles
for zz in Zradii:
XX = radius(zz)*np.cos(thetarange)
YY = radius(zz)*np.sin(thetarange)
ax.plot(XX,YY,zz, lw=1, color='k')
plt.show();
对于椭圆:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
from matplotlib import cm
#Create the profile
Zradii = [0, 1, 5, 10, 12, 14, 16]
ARadii = [1, 1.5, 1, 0.8, 1.3, 0.6, 0.5] #Major axis
BRadii = [0.5, 1, 1.2, 1, 0.5, 0.7, 0.5] # Minor Axis
XOFFSET = [1, 1, 1, 1, 2, 2, 2] # X Offset of each ellipse
YOFFSET = [1, 1, 1, 1, 2, 2, 2] # Y Offset of each ellipse
aradius = CubicSpline(Zradii, ARadii, bc_type=((1, 0.5), (1, 0.0)))
bradius = CubicSpline(Zradii, BRadii, bc_type=((1, 0.5), (1, 0.0)))
xoffset = CubicSpline(Zradii, XOFFSET)
yoffset = CubicSpline(Zradii, YOFFSET)
# Make data
npoints=100
thetarange = np.linspace(0, 2 * np.pi, npoints)
zrange = np.linspace(min(Zradii), max(Zradii), npoints)
X = [xoffset(z) + aradius(z)*np.cos(thetarange) for z in zrange]
Y = [yoffset(z) + bradius(z)*np.sin(thetarange) for z in zrange]
Z = np.array([[z] for z in zrange])
# Plot the surface
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim3d(-2, 5)
ax.set_ylim3d(-2, 5)
ax.set_zlim3d(0, 20)
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
#Plot the ellipses
for zz in Zradii:
XX = xoffset(zz) + aradius(zz)*np.cos(thetarange)
YY = yoffset(zz) + bradius(zz)*np.sin(thetarange)
ax.plot(XX,YY,zz, lw=1, color='k')
plt.show();
答案 1 :(得分:1)
您可以通过两个步骤完成此操作。
首先,通过将曲线拟合到所需的半径来创建所需的轮廓,如:
% Create the profile
Zradii = [0 1 5 10 12 14 16];
Rradii = [1 1.5 1 0.8 1.3 0.6 0.5];
pp = spline(Zradii,[0.5 Rradii 0]);
在这里,我在Zradii
中给出的高度定义了环,并在Rradii
中给出了相应的半径。
接下来,通过使用fsurf
绘制该配置文件来创建放样曲面:
% Loft
r = @(u,v) ppval(pp,v);
funx = @(u,v) r(u,v).*cos(u);
funy = @(u,v) r(u,v).*sin(u);
funz = @(u,v) v;
fsurf(funx,funy,funz,[0 2*pi min(Zradii) max(Zradii)])
camlight
axis square;
view(70,10);
<强>扩展强>
以前的方法可以扩展到其他任意形状。例如,我们使用等式从圆圈变为椭圆:
然后可以将之前的代码修改为如下所示:
%% Create the profile
Z = [0 1 5 10 12 14 16];
A = [1 1.5 1 0.8 1.3 0.6 0.5]; % Major Axis
B = [0.5 1 1.2 1 0.5 0.7 0.5]; % Minor Axis
X = [1 1 1 1 2 2 2]; % X Offset of each ellipse
Y = [1 1 1 1 2 2 2]; % Y Offset of each ellipse
ppA = spline(Z,[0.5 A 0]);
ppB = spline(Z,[0.5 B 0]);
ppX = spline(Z,X);
ppY = spline(Z,Y);
%% Loft
ellipse = @(t,a,b) a.*b./sqrt((a.*cos(t)).^2 + (b.*sin(t)).^2);
r = @(u,v) ellipse(u, ppval(ppA,v), ppval(ppB,v));
funx = @(u,v) r(u,v).*cos(u) + ppval(ppX,v);
funy = @(u,v) r(u,v).*sin(u) + ppval(ppY,v);
funz = @(u,v) v;
fsurf(funx,funy,funz,[0 2*pi min(Z) max(Z)],'linestyle','none')
camlight
axis square;
view(80,5);
%% Add the ellipses in black
hold on
t=linspace(0,2*pi);
arrayfun(@(z)plot3(funx(t,z),funy(t,z),z*ones(size(t)),'k','Linewidth',2),Z)
hold off
生成下图,其中生成放样的椭圆以黑色显示: