Ejemplo n.º 1
0
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')
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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"
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
    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])
Ejemplo n.º 14
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
Ejemplo n.º 15
0
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)
Ejemplo n.º 16
0
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()
Ejemplo n.º 17
0
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"