为什么3D箭头图的箭头指向错误方向?

3

我一直在为研究建模磁场而努力。下面的代码允许我计算任何给定点(x,y,z)的正确场值; 但是,当我将一个np.meshgrid对象传递到代码中时,结果开始变得奇怪。

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d


def normal_vector(u):
    return u/np.linalg.norm(u)
class Path:
    """
    This defines the Path class which allows for the calculations of the magnetic field.
    """

    def __init__(self, xs, ys, zs):
        self.points = zip(*[xs, ys, zs])  # defines the points
        self.x = xs
        self.y = ys
        self.z = zs
        self.path_vectors = [(self.points[i + 1][0] - self.points[i][0],
                              self.points[i + 1][1] - self.points[i][1],
                              self.points[i + 1][2] - self.points[i][2]) for i in range(len(self.x) - 1)]
    def get_length(self):
        """
        Calculates the path length
        :return: returns float length
        """
        return sum([np.sqrt(((self.x[i + 1] - self.x[i]) ** 2) + ((self.y[i + 1] - self.y[i]) ** 2) + (
                (self.z[i + 1] - self.z[i]) ** 2)) for i in
                    range(len(self.x) - 1)])

    def get_magnetlic_function(self,axes,current=1.0,magnetic_constant = 1.25663706212e-6):
        magnetic_parameter = (current*magnetic_constant)/(4*np.pi)
        field_function = lambda x,y,z: sum([magnetic_parameter*np.cross(self.path_vectors[j],normal_vector(np.stack([x-self.x[j],y-self.y[j],z-self.z[j]],axis=-1)))/(np.linalg.norm(np.stack([x-self.x[j],y-self.y[j],z-self.z[j]],axis=-1))**2) for j in range(len(self.x)-1)]).swapaxes(0,-1)
        return field_function

n = 200
r = 1
h = 5
grid_x,grid_y,grid_z = np.meshgrid(np.linspace(-10,10,5),
                    np.linspace(-10,10,5),
                    np.linspace(-10,10,5))
c = h / (2 * n * np.pi)
t = np.linspace(0,2*np.pi, 5000)
xp = 3*np.cos(t)
yp = 3*np.sin(t)
zp = 0*t
p = Path(list(xp), list(yp), list(zp))
func = p.get_magnetlic_function([grid_x,grid_y,grid_z])
u,v,w = func(grid_x,grid_y,grid_z)
r = np.sqrt(u**2+v**2+w**2)
print func(-10.0,00.0,0.0)
ax1 = plt.subplot(111,projection='3d')
ax1.plot(xp,yp,zp,'r-')
ax1.plot([-10],[0],[0],'ro')
ax1.quiver(grid_x,grid_y,grid_z,u/r,v/r,w/r,length=1)
plt.show()


很明显,在底部附近表明,如果运行代码,则-10.0,00.0,0.0处的向量方向与打印出来的值不同。为什么?从代码中,我收到了这里的箭头图:My code. 它应该看起来像:enter image description here

我的回答是否更符合您的需求?如果我包含一个如何正确使用np.meshgridlambda函数的演示,会不会更好? - William Miller
答案很棒!感谢您的帮助!结果发现在lambda函数中,numpy数组会变得相当奇怪。如果您有时间,我也很想看看您使用lambda的实现方式! - BooleanDesigns
1个回答

1

在尝试查找由电流分布引起的磁场时,考虑成对相互作用通常更加清晰(尽管lambda函数更具有Python风格)。考虑这种方法。

class Path:
    # ...
    def mag_func(self, x, y, z, current = 1.0, mag_const = 1.25663706212e-6):
        mag_param = current * mag_const / (4 * np.pi)
        s = x.shape
        res = np.zeros((s[0],s[1],s[2],3))
        for i in range(s[0]):
            for j in range(s[1]):
                for k in range(s[2]):
                    for idx, (xc, yc, zc) in enumerate(zip(self.x, self.y, self.z)):
                        res[i,j,k,:] += mag_param * \
                                np.cross(self.path_vectors[idx], [x[i,j,k] - xc,
                                         y[i,j,k] - yc, z[i,j,k] - zc]) / \
                                np.linalg.norm([x[i,j,k] - xc, y[i,j,k] - yc, 
                                              z[i,j,k] - zc])**2
        return res[:,:,:,0], res[:,:,:,1], res[:,:,:,2]
#...
u, v, w = p.mag_func(grid_x, grid_y, grid_z)
r = np.sqrt(u**2+v**2+w**2)
ax1 = plt.subplot(111,projection='3d')
ax1.plot(xp, yp, zp, 'r-')
ax1.quiver(grid_x, grid_y, grid_z, u/r, v/r, w/r,length=1)
plt.show()

这将会给出:

enter image description here

如何正确表示绕着电流导线周围的磁场。

至于为什么lambda一开始不起作用,我认为这是由于通过np.meshgrid创建网格,使得外部的sum对应的点数比它应该有的要多。以上述方式进行迭代可以解决这个问题。虽然可能可以使用那个lambda函数,但我认为你仍然需要按照所示的方式迭代grid_xgrid_ygrid_z


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接