我有一个椭球体的一般公式:
A*x**2 + C*y**2 + D*x + E*y + B*x*y + F + G*z**2 = 0
其中A、B、C、D、E、F、G是常数因子。你知道吗
如何在matplotlib中将此公式绘制为3D绘图?(最好是线框。)
我看到了example,但它是参数形式的,我不知道如何在代码中放置z坐标。有没有一种方法可以保持通用的形式,而不使用参数形式来绘制它?你知道吗
我开始把它放进这样的代码里:
from mpl_toolkits import mplot3d
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
def f(x, y):
return ((A*x**2 + C*y**2 + D*x + E*y + B*x*y + F))
def f(z):
return G*z**2
x = np.linspace(-2200, 1850, 30)
y = np.linspace(-100, 60, 30)
z = np.linspace(-100, 60, 30)
X, Y, Z = np.meshgrid(x, y, z)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z');
我有个错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-1-95b1296ae6a4> in <module>()
18 fig = plt.figure()
19 ax = fig.add_subplot(111, projection='3d')
---> 20 ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
21 ax.set_xlabel('x')
22 ax.set_ylabel('y')
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Anaconda3_64\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py in plot_wireframe(self, X, Y, Z, *args, **kwargs)
1847 had_data = self.has_data()
1848 if Z.ndim != 2:
-> 1849 raise ValueError("Argument Z must be 2-dimensional.")
1850 # FIXME: Support masked arrays
1851 X, Y, Z = np.broadcast_arrays(X, Y, Z)
ValueError: Argument Z must be 2-dimensional.
旁注,但你所得到的不是一个三维椭球体最一般的方程。你的方程式可以改写为
这意味着对于
z
的每个值,实际上得到了一个不同级别的2d椭圆,切片相对于z = 0
平面是对称的。这表明你的椭球不是一般的,它有助于检查结果,以确保我们得到的是有意义的。你知道吗假设我们取一个一般点
r0 = [x0, y0, z0]
,那么在哪里
其中^{} stands for matrix-vector or vector-vector product 。你知道吗
你可以使用你的函数和plot its isosurface,但那是次优的:你需要一个网格化的函数近似值,这对于足够的分辨率是非常昂贵的,而且你必须明智地选择这个采样的域。你知道吗
相反,您可以对数据执行principal axis transformation,以泛化您自己链接的parametric plot of a canonical ellipsoid。你知道吗
第一步是将
M
对角化为M = V @ D @ V.T
,其中D
是diagonal。因为它是实对称矩阵,所以这总是可能的,而且V
就是orthogonal。那我们有我们可以重组为
它激发了辅助坐标
r1 = V.T @ r0
和向量b1 = b0 @ V
的定义,我们得到因为
D
是一个对称矩阵,特征值d1, d2, d3
在它的对角线上,上面是方程其中
r1 = [x1, x2, x3]
和b1 = [b11, b12, b13]
。你知道吗剩下的就是从
r1
切换到r2
,这样我们就去掉了线性项:所以我们定义
为了这些我们终于有了
这是二阶曲面的标准形式。为了使它有意义地对应于椭球体,我们必须确保
d1
、d2
、d3
和c2
都是严格正的。如果保证了这一点,则标准形式的半长轴是sqrt(c2/d1)
、sqrt(c2/d2)
和sqrt(c2/d3)
。你知道吗我们要做的是:
[x2, y2, z2]
r2 - r1
)得到[x1, y1, z1]
V
得到r0
,即我们感兴趣的实际[x, y, z]
坐标。你知道吗下面是我如何实现这一点:
下面是一个椭球的例子,证明了它的有效性:
从这里开始的实际策划是微不足道的。使用3d scaling hack from this answer保持轴相等:
结果如下:
把它旋转一圈就可以很好地看到,表面确实是反射对称的,相对于
z = 0
平面,这从方程中可以明显看出。你知道吗您可以更改函数的
n_theta
和n_phi
关键字参数,以生成具有不同网格的网格。有趣的是,你可以把单位球上的任何散乱点插入到函数get_ellipsoid_coordinates
中的r2
的定义中(只要这个数组的第一个维度是3),输出的坐标将具有相同的形状,但它们将被转换成实际的椭球体。你知道吗您还可以使用其他库来可视化曲面,例如mayavi,您可以在其中绘制我们刚刚计算的曲面,或者compare it with an isosurface,它内置在那里。你知道吗
相关问题 更多 >
编程相关推荐