def drawDipole(position, moment, angle, axis, SYSSIZE, ax): """ Draw a dipole moment arrow. Parameters ---------- position : vec3 position of the dipole moment : vec3 orientation vector of the dipole SYSSIZE : float size of the display pyplot : pyplot canvas to draw on """ from magpylib._lib.mathLib import angleAxisRotation P = angleAxisRotation(position, angle, axis) M = angleAxisRotation(moment, angle, axis) ax.quiver( P[0], P[1], P[2], # X,Y,Z position M[0], M[1], M[2], # Components of the Vector normalize=True, length=SYSSIZE / 12, color='k')
def drawSensor(sensor, SYSSIZE, ax): """Draw the sensor coordinates Parameters ---------- sensor: Sensor Sensor to draw SYSSIZE : float Size of the display system ax : [pyplot] pyplot canvas to draw on """ from magpylib._lib.mathLib import angleAxisRotation M = angleAxisRotation([1, 0, 0], sensor.angle, sensor.axis) P = sensor.position ax.quiver( P[0], P[1], P[2], # X position M[0], M[1], M[2], # Components of the Vector normalize=True, length=SYSSIZE / 4, color='r') ax.text(M[0] + P[0], M[1] + P[1], M[2] + P[2], "x", None) M = angleAxisRotation([0, 1, 0], sensor.angle, sensor.axis) ax.quiver( P[0], P[1], P[2], # Y position M[0], M[1], M[2], # Components of the Vector normalize=True, length=SYSSIZE / 4, color='g') ax.text(M[0] + P[0], M[1] + P[1], M[2] + P[2], "y", None) M = angleAxisRotation([0, 0, 1], sensor.angle, sensor.axis) ax.quiver( P[0], P[1], P[2], # Z position M[0], M[1], M[2], # Components of the Vector normalize=True, length=SYSSIZE / 4, color='b') ax.text(M[0] + P[0], M[1] + P[1], M[2] + P[2], "z", None)
def makeLine(curr=0.0, vertices=[(-1.0, 0.0, 0.0), (1.0, 0.0, 0.0)], pos=(0.0, 0.0, 0.0), N=12, angle=0.0, axis=(0.0, 0.0, 1.0), sizeref=None, color=None, showlegend=True, **kwargs): vert = np.array(vertices) Nv = len(vertices) points = [] moments = [] for i in range(Nv - 1): pts = np.linspace(vert[i], vert[i + 1], N) moms = np.tile((vert[i + 1] - vert[i]) * np.sign(curr), (N, 1)) points += [*pts] moments += [*moms] x, y, z = points = (np.array(points) + np.array(pos)).T u, v, w = moments = np.array(moments).T if color is None: color = 'rgb(33,33,33)' if sizeref is None: sizeref = np.sqrt(np.power(np.diff(vert, axis=0), 2).sum(axis=1)).sum() if angle != 0: x, y, z = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T u, v, w = np.array([ angleAxisRotation(p, angle, axis, anchor=(0, 0, 0)) for p in moments.T ]).T lineCurrent = go.Cone(x=x, y=y, z=z, u=u, v=v, w=w, sizeref=sizeref, sizemode='absolute', showscale=False, showlegend=showlegend, colorscale=[[0, color], [1, color]], name=f'line current ({curr:.2f}A)') lineCurrent.update(**kwargs) return lineCurrent
def makeDipole(moment=(0.0, 0.0, 1), pos=(0.0, 0.0, 0.0), angle=0.0, axis=(0.0, 0.0, 1.0), color=None, sizeref=2, showlegend=True, **kwargs): x, y, z = np.array([[p] for p in pos]) mom_mag = np.linalg.norm(moment) mom = np.array(moment) / mom_mag if color is None: color = 'rgb(33,33,33)' if angle != 0: mom = angleAxisRotation(mom, angle, axis, anchor=pos) u, v, w = [[m] for m in moment] dipole = go.Cone(x=x, y=y, z=z, u=u, v=v, w=w, colorscale=[[0, color], [1, color]], sizeref=sizeref, sizemode='absolute', showscale=False, showlegend=showlegend, name=f'''dipole ({mom_mag:.2f}T/m³)''') dipole.update(**kwargs) return dipole
def makeBox(mag=(0, 0, 1), dim=(10, 10, 10), pos=(0, 0, 0), angle=0, axis=(0, 0, 1), cst=0.1, showlegend=True, **kwargs): box = go.Mesh3d(i=np.array([7, 0, 0, 0, 4, 4, 2, 6, 4, 0, 3, 7]), j=np.array([3, 4, 1, 2, 5, 6, 5, 5, 0, 1, 2, 2]), k=np.array([0, 7, 2, 3, 6, 7, 1, 2, 5, 5, 7, 6]), showscale=False, showlegend=showlegend, name=f'''box ({dim[0]:.1f}x{dim[1]:.1f}x{dim[2]:.1f}mm)''') x = np.array([-1, -1, 1, 1, -1, -1, 1, 1]) * 0.5 * dim[0] + pos[0] y = np.array([-1, 1, 1, -1, -1, 1, 1, -1]) * 0.5 * dim[1] + pos[1] z = np.array([-1, -1, -1, -1, 1, 1, 1, 1]) * 0.5 * dim[2] + pos[2] points = np.array([x, y, z]) if cst is not False: box.colorscale = _getColorscale(cst) box.intensity = _getIntensity(points=(x, y, z), mag=mag, pos=pos) if angle != 0: points = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T box.x, box.y, box.z = points box.update(**kwargs) return box
def makeDiscreteBox(data, pos=(0, 0, 0), angle=0, axis=(0, 0, 1), showlegend=True, **kwargs): dmin = np.min(data, axis=0) dmax = np.max(data, axis=0) dim = (dmax - dmin)[:-1] box = go.Mesh3d( i=np.array([7, 0, 0, 0, 4, 4, 2, 6, 4, 0, 3, 7]), j=np.array([3, 4, 1, 2, 5, 6, 5, 5, 0, 1, 2, 2]), k=np.array([0, 7, 2, 3, 6, 7, 1, 2, 5, 5, 7, 6]), showscale=False, showlegend=showlegend, name=f'''discrete data (Bmin={dmin[-1]:.2f}, Bmax={dmax[-1]:.2f}mT)''') x = np.array([-1, -1, 1, 1, -1, -1, 1, 1 ]) * 0.5 * dim[0] + pos[0] + 0.5 * (dmin[0] + dmax[0]) y = np.array([-1, 1, 1, -1, -1, 1, 1, -1 ]) * 0.5 * dim[1] + pos[1] + 0.5 * (dmin[1] + dmax[1]) z = np.array([-1, -1, -1, -1, 1, 1, 1, 1 ]) * 0.5 * dim[2] + pos[2] + 0.5 * (dmin[2] + dmax[2]) points = np.array([x, y, z]) if angle != 0: points = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T box.x, box.y, box.z = points box.update(**kwargs) return box
def make_RotationAxis(rotAxis, name='Rotation Axis', **kwargs): pos = rotAxis.position dim = rotAxis.dimension angle = rotAxis.angle axis = rotAxis.axis try: kwargs.pop('color') except: pass x = [pos[0], pos[0]] y = [pos[1], pos[1]] z = [pos[2] - dim / 2, pos[2] + dim / 2] points = np.array([x, y, z]) if angle != 0: x, y, z = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T scatter = go.Scatter3d(x=x, y=y, z=z, name=name, mode='lines+text', text=['(-)', '(+)'], textposition="top right") scatter.update(**kwargs) return scatter
def makeSensor( pos=(0, 0, 0), angle=0, axis=(0, 0, 1), dim=1, showlegend=True, **kwargs): box = go.Mesh3d(i=np.array([7, 0, 0, 0, 4, 4, 2, 6, 4, 0, 3, 7]), j=np.array([3, 4, 1, 2, 5, 6, 5, 5, 0, 1, 2, 2]), k=np.array([0, 7, 2, 3, 6, 7, 1, 2, 5, 5, 7, 6]), showscale=False, showlegend=showlegend, name='3d sensor') try: if len(dim) == 2: dim = np.array([dim[0], dim[1], np.mean(dim) / 5]) else: dim = np.array(dim[:3]) except: dim = np.array([dim, dim, dim]) dd = 0.8 # shape modifier x = np.array([-1, -1, 1, 1, -dd * 1, -dd * 1, dd * 1, dd * 1 ]) * 0.5 * dim[0] + pos[0] y = np.array([-1, 1, 1, -1, -dd * 1, dd * 1, dd * 1, -dd * 1 ]) * 0.5 * dim[1] + pos[1] z = np.array([-1, -1, -1, -1, 1, 1, 1, 1]) * 0.5 * dim[2] + pos[2] points = np.array([x, y, z]) if angle != 0: points = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T box.x, box.y, box.z = points box.update(**kwargs) return box
def makeCircular(curr=0.0, dim=1.0, pos=(0.0, 0.0, 0.0), angle=0.0, axis=(0.0, 0.0, 1.0), color=None, N=40, sizeref=1, showlegend=True, **kwargs): t = np.linspace(0, 2 * np.pi, N) x = dim / 2 * np.cos(t) + pos[0] y = dim / 2 * np.sin(t) + pos[1] z = np.ones(N) * pos[2] points = np.array([x, y, z]) u = -np.ones(N) * np.sin(t) * np.sign(curr) v = np.ones(N) * np.cos(t) * np.sign(curr) w = np.ones(N) * 0 if color is None: color = 'rgb(33,33,33)' if angle != 0: x, y, z = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T moments = np.array([u, v, w]) u, v, w = np.array([ angleAxisRotation(p, angle, axis, anchor=(0, 0, 0)) for p in moments.T ]).T circularCurrent = go.Cone(x=x, y=y, z=z, u=u, v=v, w=w, sizeref=sizeref, sizemode='absolute', showscale=False, showlegend=showlegend, colorscale=[[0, color], [1, color]], name=f'circular current ({curr:.2f}A)') circularCurrent.update(**kwargs) return circularCurrent
def makeCylinder(mag=(0, 0, 1), dim=(10, 10, 0), pos=(0, 0, 0), angle=0, axis=(0, 0, 1), cst=0.1, color=None, N=40, showlegend=True, **kwargs): dim = np.array(dim) if len(dim) == 2: dim = np.array(list(dim[0:2]) + [0]) elif len(dim) == 3 and dim[2] == 0: dim[2] = 1e-5 ri = min(dim[0] / 2, dim[2] / 2) ro = max(dim[0] / 2, dim[2] / 2) hmin, hmax = -dim[1] / 2, dim[1] / 2 h = [hmin, hmin, hmax, hmax, hmin] s = np.linspace(0, 2 * np.pi, N) sa, ha = np.meshgrid(s, h) ro = dim[0] / 2 ri = dim[2] / 2 x = ro * np.cos(sa) y = ro * np.sin(sa) z = ha x[0] = x[-2] = x[-1] = ri * np.cos(s) y[0] = y[-2] = y[-1] = ri * np.sin(s) x, y, z = x + pos[0], y + pos[1], z + pos[2] def_name = f'''cylinder (d={dim[0]:.1f}, h={dim[1]:.1f}mm)''' cylinder = go.Surface(x=x, y=y, z=z, showscale=False, name=def_name, showlegend=showlegend) if cst is not False: cylinder.colorscale = _getColorscale(cst) cylinder.surfacecolor = _getIntensity(points=(x, y, z), mag=mag, pos=pos) elif color is not None: cylinder.colorscale = [[0, color], [1, color]] if angle != 0: points = np.array([x.flatten(), y.flatten(), z.flatten()]) xr, yr, zr = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T cylinder.update(x=xr.reshape(x.shape), y=yr.reshape(y.shape), z=zr.reshape(z.shape)) cylinder.update(**kwargs) return cylinder
def test_angleAxisRotationV(): POS = np.array([[.1, .2, .3], [0, 1, 0], [0, 0, 1]]) ANG = np.array([22, 233, -123]) AXIS = np.array([[3, 4, 5], [-7, -8, -9], [1, 0, 0]]) ANCHOR = np.array([[.1, 3, .3], [5, 5, 5], [2, -3, 1.23]]) SOL = angleAxisRotationV(POS, ANG, AXIS, ANCHOR) for pos, ang, ax, anch, sol in zip(POS, ANG, AXIS, ANCHOR, SOL): assert np.amax(np.abs(angleAxisRotation(pos, ang, ax, anch) - sol)) < 1e-10, "bad angleAxisRotationV"
def make_Streamlines(surfsens, density='auto', arrow_scale=0.1, sensorsources=None, color=None, **kwargs): ''' sensorsources: iterable of magpylib sources in order to make the streamlines plot the Bfield values need to be retrieved for the corresponding sources ''' if sensorsources is None: sensorsources = [] angle = surfsens.angle pos = surfsens.position axis = surfsens.axis density = surfsens.Nelem[0] / 4 if density == 'auto' else density B = surfsens.getBarray(*sensorsources).reshape(*surfsens.Nelem, 3) surfsens.position = np.array([0, 0, 0]) surfsens.angle = 0 x, y, z = surfsens.positions.T.reshape(3, *surfsens.Nelem) xs, ys = x[:, 0], y.T[:, 0] surfsens.angle = angle surfsens.position = pos surfsens.axis = axis Bx, By = B[:, :, 0], B[:, :, 1] streamline = create_streamline(x=xs, y=ys, u=Bx.T, v=By.T, arrow_scale=arrow_scale, density=density) sl = streamline.data[0] points = np.array([sl.x, sl.y, np.zeros(len(sl.x))]) if angle != 0: x, y, z = np.array([ angleAxisRotation(p, angle, axis, anchor=[0, 0, 0]) for p in points.T ]).T else: x, y, z = points trace = go.Scatter3d(x=repnan(x) + pos[0], y=repnan(y) + pos[1], z=repnan(z) + pos[2], mode='lines', name=f'streamlines ({len(sensorsources)} sources)') trace.update(**kwargs) return trace
def getB(self, *sources, dupWarning=True): """Extract the magnetic field based on the Sensor orientation Parameters ---------- dupWarning : Check if there are any duplicate sources, optional. This will prevent duplicates and throw a warning, by default True. Returns ------- [vec3] B-Field as perceived by the sensor Example ------- >>> from magpylib import source, Sensor >>> sensor = Sensor([0,0,0],90,(0,0,1)) # This sensor is rotated in respect to space >>> cyl = source.magnet.Cylinder([1,2,300],[1,2]) >>> absoluteReading = cyl.getB([0,0,0]) >>> print(absoluteReading) [ 0.552 1.105 268.328 ] >>> relativeReading = sensor.getB(cyl) >>> print(relativeReading) [ 1.105 -0.552 268.328 ] """ # Check input, add Collection list sourcesList = [] for s in sources: try: addListToCollection(sourcesList, s.sources, dupWarning) except AttributeError: if isinstance(s, list) or isinstance(s, tuple): addListToCollection(sourcesList, s, dupWarning) else: assert isSource(s), "Argument " + str(s) + \ " in addSource is not a valid source for Collection" if dupWarning is True: addUniqueSource(s, sourcesList) else: sourcesList += [s] # Read the field from all nominated sources Btotal = sum([s.getB(self.position) for s in sources]) return angleAxisRotation( Btotal, -self.angle, # Rotate in the opposite direction self.axis, [0, 0, 0])
def makeSphere(mag=(0, 0, 1), dim=10, pos=(0, 0, 0), angle=0, axis=(0, 0, 1), cst=0.1, color=None, N=40, showlegend=True, **kwargs): r = min(dim / 2, dim / 2) s = np.linspace(0, 2 * np.pi, 2 * N) t = np.linspace(0, np.pi, N) tGrid, sGrid = np.meshgrid(s, t) x = r * np.cos(sGrid) * np.sin(tGrid) y = r * np.sin(sGrid) * np.sin(tGrid) z = r * np.cos(tGrid) x, y, z = x + pos[0], y + pos[1], z + pos[2] def_name = f'''sphere (d={dim:.1f}mm)''' sphere = go.Surface(x=x, y=y, z=z, showscale=False, name=def_name, showlegend=showlegend) if cst is not False: sphere.colorscale = _getColorscale(cst) sphere.surfacecolor = _getIntensity(points=(x, y, z), mag=mag, pos=pos) elif color is not None: sphere.colorscale = [[0, color], [1, color]] if angle != 0: points = np.array([x.flatten(), y.flatten(), z.flatten()]) xr, yr, zr = np.array([ angleAxisRotation(p, angle, axis, anchor=pos) for p in points.T ]).T sphere.update(x=xr.reshape(x.shape), y=yr.reshape(y.shape), z=zr.reshape(z.shape)) sphere.update(**kwargs) return sphere
def drawMagnetizationVector(position, magnetization, angle, axis, color, SYSSIZE, ax): """Draw the magnetization vector of a magnet. Parameters ---------- position : vec3 position of the magnet magnetization : vec3 magnetization vector angle : float angle of rotation axis : vec3 Axis of rotation color : matplotlib color Color of the axis. No default value specified SYSSIZE : float Size of the display syste ax : [pyploy] pyplot canvas to draw on """ from magpylib._lib.mathLib import angleAxisRotation M = angleAxisRotation(magnetization, angle, axis) P = position # Get a lil different but unique tone c = [color[0] / 2, color[1] / 2, color[2] / 2, color[3]] ax.quiver( P[0], P[1], P[2], # X,Y,Z position M[0], M[1], M[2], # Components of the Vector normalize=True, length=SYSSIZE, color=c)
def displaySystem(sources, markers=listOfPos, subplotAx=None, sensors=listOfSensors, suppress=False, direc=False, figsize=(8, 8)): """ Shows the collection system in an interactive pyplot and returns a matplotlib figure identifier. WARNING ------- As a result of an inherent problem in matplotlib the Poly3DCollections z-ordering fails when bounding boxes intersect. Parameters ---------- markers : list[scalar,scalar,scalar,[label]] List of position vectors to add visual markers to the display, optional label. Default: [[0,0,0]] Example ------- >>> from magpylib import Collection, source >>> c=source.current.Circular(3,7) >>> x = Collection(c) >>> marker0 = [0,0,0,"Neutral Position"] >>> marker1 = [10,10,10] >>> x.displaySystem(markers=[ marker0, ... marker1]) Parameters ---------- sensors : list[sensor] List of :class:`~magpylib.Sensor` objects to add the display. Default: None Example ------- >>> from magpylib import Collection, source >>> c=source.current.Circular(3,7) >>> x = Collection(c) >>> sensor0 = Sensor() >>> sensor1 = Sensor(pos=[1,2,3], angle=180) >>> x.displaySystem(sensors=[ sensor0, ... sensor1]) Parameters ---------- suppress : bool If True, only return Figure information, do not show. Interactive mode must be off. Default: False. Example ------- >>> ## Suppress matplotlib.pyplot.show() >>> ## and returning figure from showing up >>> from matplotlib import pyplot >>> pyplot.ioff() >>> figureData = Collection.displayFigure(suppress=True) Parameters ---------- direc : bool Set to True to show current directions and magnetization vectors. Default: False Return ------ matplotlib Figure object graphics object is displayed through plt.show() Example ------- >>> from magpylib import source, Collection >>> pm1 = source.magnet.Box(mag=[0,0,1000],dim=[1,1,1],pos=[-1,-1,-1],angle=45,axis=[0,0,1]) >>> pm2 = source.magnet.Cylinder(mag=[0,0,1000],dim=[2,2],pos=[0,-1,1],angle=45,axis=[1,0,0]) >>> pm3 = source.magnet.Sphere(mag=[0,0,1000],dim=3,pos=[-2,1,2],angle=45,axis=[1,0,0]) >>> C1 = source.current.Circular(curr=100,dim=6) >>> col = Collection(pm1,pm2,pm3,C1) >>> col.displaySystem() Parameters ---------- subplotAx : matplotlib subplot axe instance Use an existing matplotlib subplot instance to draw the 3D system plot into. Default: None Example ------- >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from magpylib.source.magnet import Box >>> from magpylib import Collection >>> #create collection of one magnet >>> s1 = Box(mag=[ 500,0, 500], dim=[3,3,3], pos=[ 0,0, 3], angle=45, axis=[0,1,0]) >>> c = Collection(s1) >>> #create positions >>> xs = np.linspace(-8,8,100) >>> zs = np.linspace(-6,6,100) >>> posis = [[x,0,z] for z in zs for x in xs] >>> #calculate fields >>> Bs = c.getBsweep(posis) >>> #reshape array and calculate amplitude >>> Bs = np.array(Bs).reshape([100,100,3]) >>> Bamp = np.linalg.norm(Bs,axis=2) >>> X,Z = np.meshgrid(xs,zs) >>> # Define figure >>> fig = plt.figure() >>> ## Define ax for 2D >>> ax1 = fig.add_subplot(1, 2, 1, axisbelow=True) >>> ## Define ax for 3D displaySystem >>> ax2 = fig.add_subplot(1, 2, 2, axisbelow=True,projection='3d') >>> ## field plot 2D >>> ax1.contourf(X,Z,Bamp,100,cmap='rainbow') >>> U,V = Bs[:,:,0], Bs[:,:,2] >>> ax1.streamplot(X, Z, U, V, color='k', density=2) >>> ## plot Collection system in 3D ax subplot >>> c.displaySystem(subplotAx=ax2) Raises ------ AssertionError If Marker position list is poorly defined. i.e. listOfPos=(x,y,z) instead of lisOfPos=[(x,y,z)] """ collection = Collection(sources) if subplotAx is None: fig = plt.figure(dpi=80, figsize=figsize) ax = fig.gca(projection='3d') else: ax = subplotAx # count magnets Nm = 0 for s in collection.sources: if type(s) is Box or type(s) is Cylinder or type(s) is Sphere: Nm += 1 cm = plt.cm.hsv # Linter complains about this but it is working pylint: disable=no-member # select colors colors = [cm(x) for x in linspace(0, 1, Nm + 1)] ii = -1 SYSSIZE = finfo(float).eps # Machine Epsilon for moment dipolesList = [] magnetsList = [] sensorsList = [] currentsList = [] markersList = [] # Check input and Add markers to the Markers list before plotting for m in markers: assert isDisplayMarker( m), "Invalid marker definition in displaySystem:" + str( m) + ". Needs to be [vec3] or [vec3,string]" markersList += [m] for s in sensors: if s == sensor1: continue else: assert isSensor( s), "Invalid sensor definition in displaySystem:" + str(s) sensorsList.append(s) for s in collection.sources: if type(s) is Box: ii += 1 # increase color counter P = s.position D = s.dimension / 2 # create vertices in canonical basis v0 = array([ D, D * array([1, 1, -1]), D * array([1, -1, -1]), D * array([1, -1, 1]), D * array([-1, 1, 1]), D * array([-1, 1, -1]), -D, D * array([-1, -1, 1]) ]) # rotate vertices + displace v = array( [angleAxisRotation_priv(s.angle, s.axis, d) + P for d in v0]) # create faces faces = [[v[0], v[1], v[2], v[3]], [v[0], v[1], v[5], v[4]], [v[4], v[5], v[6], v[7]], [v[2], v[3], v[7], v[6]], [v[0], v[3], v[7], v[4]], [v[1], v[2], v[6], v[5]]] # plot boxf = Poly3DCollection(faces, facecolors=colors[ii], linewidths=0.5, edgecolors='k', alpha=1) ax.add_collection3d(boxf) # check system size maxSize = amax(abs(v)) if maxSize > SYSSIZE: SYSSIZE = maxSize if direc is True: s.color = colors[ii] magnetsList.append(s) elif type(s) is Cylinder: ii += 1 # increase color counter P = s.position R, H = s.dimension / 2 resolution = 20 # vertices phis = linspace(0, 2 * pi, resolution) vertB0 = array([[R * cos(p), R * sin(p), -H] for p in phis]) vertT0 = array([[R * cos(p), R * sin(p), H] for p in phis]) # rotate vertices+displacement vB = array([ angleAxisRotation_priv(s.angle, s.axis, d) + P for d in vertB0 ]) vT = array([ angleAxisRotation_priv(s.angle, s.axis, d) + P for d in vertT0 ]) # faces faces = [[vT[i], vB[i], vB[i + 1], vT[i + 1]] for i in range(resolution - 1)] faces += [vT, vB] # plot coll = Poly3DCollection(faces, facecolors=colors[ii], linewidths=0.5, edgecolors='k', alpha=1) ax.add_collection3d(coll) # check system size maxSize = max([amax(abs(vB)), amax(abs(vT))]) if maxSize > SYSSIZE: SYSSIZE = maxSize if direc is True: s.color = colors[ii] magnetsList.append(s) elif type(s) is Sphere: ii += 1 # increase color counter P = s.position R = s.dimension / 2 resolution = 12 # vertices phis = linspace(0, 2 * pi, resolution) thetas = linspace(0, pi, resolution) vs0 = [[[ R * cos(phi) * sin(th), R * sin(phi) * sin(th), R * cos(th) ] for phi in phis] for th in thetas] # rotate vertices + displacement vs = array( [[angleAxisRotation_priv(s.angle, s.axis, v) + P for v in vss] for vss in vs0]) # faces faces = [] for j in range(resolution - 1): faces += [[ vs[i, j], vs[i + 1, j], vs[i + 1, j + 1], vs[i, j + 1] ] for i in range(resolution - 1)] # plot boxf = Poly3DCollection(faces, facecolors=colors[ii], linewidths=0.5, edgecolors='k', alpha=1) ax.add_collection3d(boxf) # check system size maxSize = amax(abs(vs)) if maxSize > SYSSIZE: SYSSIZE = maxSize if direc is True: s.color = colors[ii] magnetsList.append(s) elif type(s) is Line: P = s.position vs0 = s.vertices # rotate vertices + displacement vs = array( [angleAxisRotation_priv(s.angle, s.axis, v) + P for v in vs0]) # plot ax.plot(vs[:, 0], vs[:, 1], vs[:, 2], lw=1, color='k') # check system size maxSize = amax(abs(vs)) if maxSize > SYSSIZE: SYSSIZE = maxSize if direc is True: # These don't move in the original object, sCopyWithVertices = deepcopy(s) sCopyWithVertices.vertices = vs # We just draw the frame rotation, discard changes currentsList.append(sCopyWithVertices) elif type(s) is Circular: P = s.position R = s.dimension / 2 resolution = 20 # vertices phis = linspace(0, 2 * pi, resolution) vs0 = array([[R * cos(p), R * sin(p), 0] for p in phis]) # rotate vertices + displacement vs = array( [angleAxisRotation_priv(s.angle, s.axis, v) + P for v in vs0]) # plot ax.plot(vs[:, 0], vs[:, 1], vs[:, 2], lw=1, color='k') # check system size maxSize = amax(abs(vs)) if maxSize > SYSSIZE: SYSSIZE = maxSize if direc is True: # Send the Circular vertice information sCopyWithVertices = deepcopy(s) sCopyWithVertices.vertices = vs # to the object drawing list currentsList.append(sCopyWithVertices) elif type(s) is Dipole: P = angleAxisRotation(s.position, s.angle, s.axis) maxSize = amax(abs(P)) if maxSize > SYSSIZE: SYSSIZE = maxSize dipolesList.append(s) for m in markersList: # Draw Markers ax.scatter(m[0], m[1], m[2], s=20, marker='x') if (len(m) > 3): zdir = None ax.text(m[0], m[1], m[2], m[3], zdir) # Goes up to 3rd Position maxSize = max([abs(pos) for pos in m[:3]]) if maxSize > SYSSIZE: SYSSIZE = maxSize for s in sensorsList: # Draw Sensors maxSize = max([abs(pos) for pos in s.position]) if maxSize > SYSSIZE: SYSSIZE = maxSize drawSensor(s, SYSSIZE, ax) for d in dipolesList: drawDipole(d.position, d.moment, d.angle, d.axis, SYSSIZE, ax) if direc is True: # Draw the Magnetization axes and current directions drawCurrentArrows(currentsList, SYSSIZE, ax) drawMagAxis(magnetsList, SYSSIZE, ax) #for tick in ax.xaxis.get_ticklabels()+ax.yaxis.get_ticklabels()+ax.zaxis.get_ticklabels(): # tick.set_fontsize(12) ax.set_xlabel('x[mm]') #, fontsize=12) ax.set_ylabel( 'y[mm]') #, fontsize=12) #change font size through rc parameters ax.set_zlabel('z[mm]') #, fontsize=12) ax.set( xlim=(-SYSSIZE, SYSSIZE), ylim=(-SYSSIZE, SYSSIZE), zlim=(-SYSSIZE, SYSSIZE), ) plt.tight_layout() if suppress == True: return plt.gcf() else: plt.show()
def test_angleAxisRotation(): sol = [-0.26138058, 0.59373138, 3.28125372] result = angleAxisRotation([1, 2, 3], 234.5, (0, 0.2, 1), anchor=[0, 1, 0]) for r, s in zip(result, sol): assert round(r, 4) == round(s, 4), "bad angleAxisRotation"