使用 np.outer 生成圆柱面
Generating a Cylindrical Surface with np.outer
我之前能够使用 np.outer:
生成和绘制球面
u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = R * np.outer(np.cos(u), np.sin(v))
y = R * np.outer(np.sin(u), np.sin(v))
z = R * np.outer(np.ones(np.size(u)), np.cos(v))
其中 x、y、z 的亮度为 100 x 100。
结果见图,忽略"particle traces"
我理解球体和圆柱体的数学和方向余弦,所以我认为混淆来自不理解 np.outer 到底在做什么。
我希望以下内容会生成一个圆柱体:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.cos(u)
y = R * np.sin(u)
z = np.linspace(0, h, np.size(u))
但是当我尝试绘制时,没有生成任何东西,我认为这是由于数组维度的差异:(100,)。
结果见图。
我尝试的另一件事是:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.outer(np.ones(np.size(u)), np.cos(u))
y = R * np.outer(np.ones(np.size(u)), np.sin(u))
z = np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
结果见图。
我不明白为什么我不能让它工作。
其他注意事项:
- 显然这仅适用于圆柱体的侧面,因此如果有任何方法可以在相同的 x、y、z 中生成 top/bottom 表面,那将是理想的
- 此代码必须独立于 matplotlib 工作,因为点本身也是必不可少的
- 如果用 np.outer 可以实现,这也是理想的
在此先感谢您的帮助。
编辑:
那么,如何生成顶面和底面?
不会吧?:
x = R * np.outer(np.ones(np.size(u)), np.cos(u))
y = R * np.outer(np.ones(np.size(u)), np.sin(u))
z = h * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
这没有像以前那样给我结果。
试试这个:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.outer(np.ones(np.size(u)), np.cos(u))
y = R * np.outer(np.ones(np.size(u)), np.sin(u))
z = np.outer(np.linspace(0, h, np.size(u)), np.ones(np.size(u)))
此外,如果您不确定它的作用,请检查 docs on np.outer
。它只是取两个向量的外积并生成一个矩阵。
给你一个例子,你可以用以下方式创建一个图:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
R = 2
u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = R * np.outer(np.cos(u), np.sin(v))
y = R * np.outer(np.sin(u), np.sin(v))
z = R * np.outer(np.ones(np.size(u)), np.cos(v))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x,y,z)
fig.show()
这将产生下图,与您在编辑中显示的基本相同:
代码的第二位和第三位实际上生成的似乎是圆柱体的最小表示。我将跳过代码,但两者都会产生以下内容:
然而,请务必注意,代码的第二位生成形状为 (100,)
的 x
、y
和 z
,而第三位生成形状(100,100)
,但是第二个维度上的条目都只是重复并且等于代码第二位的值。例如:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.cos(u)
y = R * np.sin(u)
z = np.linspace(0, h, np.size(u))
u2 = np.linspace(0, 2*np.pi, 100)
h2 = 5
x2 = R * np.outer(np.ones(np.size(u)), np.cos(u))
y2 = R * np.outer(np.ones(np.size(u)), np.sin(u))
z2 = np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
print(np.all(x2 == x))
True
print(np.all(y2 == y))
True
print(np.all(z2 == z))
True
所以看起来问题是你没有正确构建表面。当我构建一个曲面时,我会使用 numpy.meshgrid
。对于您的示例,我将执行以下操作:
u = np.linspace(0, 2*np.pi, 100)
h = 5
R = 2
z = np.linspace(0, h, np.size(u))
us, zs = np.meshgrid(u, z)
xs = R * np.cos(us)
ys = R * np.cos(us)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(xs,ys,zs)
你会得到下图:
两种方法的区别仅在于z
和zs
的值。你会发现 z
的转置等于 zs
所以要修复你的代码只需更改:
z = np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
至:
z = (np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))).T
一切都会好起来的。
我之前能够使用 np.outer:
生成和绘制球面u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = R * np.outer(np.cos(u), np.sin(v))
y = R * np.outer(np.sin(u), np.sin(v))
z = R * np.outer(np.ones(np.size(u)), np.cos(v))
其中 x、y、z 的亮度为 100 x 100。
结果见图,忽略"particle traces"
我理解球体和圆柱体的数学和方向余弦,所以我认为混淆来自不理解 np.outer 到底在做什么。
我希望以下内容会生成一个圆柱体:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.cos(u)
y = R * np.sin(u)
z = np.linspace(0, h, np.size(u))
但是当我尝试绘制时,没有生成任何东西,我认为这是由于数组维度的差异:(100,)。
结果见图。
我尝试的另一件事是:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.outer(np.ones(np.size(u)), np.cos(u))
y = R * np.outer(np.ones(np.size(u)), np.sin(u))
z = np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
结果见图。
我不明白为什么我不能让它工作。 其他注意事项: - 显然这仅适用于圆柱体的侧面,因此如果有任何方法可以在相同的 x、y、z 中生成 top/bottom 表面,那将是理想的 - 此代码必须独立于 matplotlib 工作,因为点本身也是必不可少的 - 如果用 np.outer 可以实现,这也是理想的
在此先感谢您的帮助。
编辑:
那么,如何生成顶面和底面? 不会吧?:
x = R * np.outer(np.ones(np.size(u)), np.cos(u))
y = R * np.outer(np.ones(np.size(u)), np.sin(u))
z = h * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
这没有像以前那样给我结果。
试试这个:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.outer(np.ones(np.size(u)), np.cos(u))
y = R * np.outer(np.ones(np.size(u)), np.sin(u))
z = np.outer(np.linspace(0, h, np.size(u)), np.ones(np.size(u)))
此外,如果您不确定它的作用,请检查 docs on np.outer
。它只是取两个向量的外积并生成一个矩阵。
给你一个例子,你可以用以下方式创建一个图:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
R = 2
u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = R * np.outer(np.cos(u), np.sin(v))
y = R * np.outer(np.sin(u), np.sin(v))
z = R * np.outer(np.ones(np.size(u)), np.cos(v))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x,y,z)
fig.show()
这将产生下图,与您在编辑中显示的基本相同:
代码的第二位和第三位实际上生成的似乎是圆柱体的最小表示。我将跳过代码,但两者都会产生以下内容:
然而,请务必注意,代码的第二位生成形状为 (100,)
的 x
、y
和 z
,而第三位生成形状(100,100)
,但是第二个维度上的条目都只是重复并且等于代码第二位的值。例如:
u = np.linspace(0, 2*np.pi, 100)
h = 5
x = R * np.cos(u)
y = R * np.sin(u)
z = np.linspace(0, h, np.size(u))
u2 = np.linspace(0, 2*np.pi, 100)
h2 = 5
x2 = R * np.outer(np.ones(np.size(u)), np.cos(u))
y2 = R * np.outer(np.ones(np.size(u)), np.sin(u))
z2 = np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
print(np.all(x2 == x))
True
print(np.all(y2 == y))
True
print(np.all(z2 == z))
True
所以看起来问题是你没有正确构建表面。当我构建一个曲面时,我会使用 numpy.meshgrid
。对于您的示例,我将执行以下操作:
u = np.linspace(0, 2*np.pi, 100)
h = 5
R = 2
z = np.linspace(0, h, np.size(u))
us, zs = np.meshgrid(u, z)
xs = R * np.cos(us)
ys = R * np.cos(us)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(xs,ys,zs)
你会得到下图:
两种方法的区别仅在于z
和zs
的值。你会发现 z
的转置等于 zs
所以要修复你的代码只需更改:
z = np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))
至:
z = (np.linspace(0, h, np.size(u)) * np.outer(np.ones(np.size(u)), np.ones(np.size(u)))).T
一切都会好起来的。