Ejemplo n.º 1
0
    def iproject(xy: np.ndarray) -> Vector3d:
        """Convert from 2D Gnomonic coordinates (x_g, y_g) to 3D
        cartesian coordiantes (x, y, z).

        Parameters
        ----------
        xy
            2D coordinates on the form
            [[x_g0, y_g0], [x_g1, y_g1], ...].

        Returns
        -------
        cartesian_coordinates
            Cartesian coordinates (x, y, z) on the form
            [[x0, y0, z0], [x1, y1, z1], ...].

        Examples
        --------
        >>> import numpy as np
        >>> from kikuchipy.projections.gnomonic_projection import (
        ...     GnomonicProjection
        ... )
        >>> xy_g = np.random.random_sample(20).reshape((10, 2))
        >>> xyz = GnomonicProjection.iproject(xy_g)
        """
        x, y = xy[..., 0], xy[..., 1]
        theta = np.arctan(np.sqrt(x**2 + y**2))
        phi = np.arctan2(y, x)
        return Vector3d.from_polar(theta=theta, phi=phi)
Ejemplo n.º 2
0
    def get_plot_data(self):
        """
        Produces suitable Rotations for the construction of a wireframe for self
        """
        from orix.vector import Vector3d

        # gets a grid of vector directions
        theta = np.linspace(0, 2 * np.pi - EPSILON, 361)
        rho = np.linspace(0, np.pi - EPSILON, 181)
        theta, rho = np.meshgrid(theta, rho)
        g = Vector3d.from_polar(rho, theta)

        # get the cell vector normal norms
        n = Rodrigues.from_rotation(self).norm.data[:, np.newaxis, np.newaxis]
        if n.size == 0:
            return Rotation.from_neo_euler(AxAngle.from_axes_angles(g, np.pi))

        d = (-self.axis).dot_outer(g.unit).data
        x = n * d
        omega = 2 * np.arctan(np.where(x != 0, x**-1, np.pi))

        # keeps the smallest allowed angle
        omega[omega < 0] = np.pi
        omega = np.min(omega, axis=0)
        r = Rotation.from_neo_euler(AxAngle.from_axes_angles(g.unit, omega))
        return r
Ejemplo n.º 3
0
    def spherical2xy(self, azimuth, polar):
        r"""Return stereographic coordinates (X, Y) from 3D unit vectors
        created from spherical coordinates, azimuth :math:`\phi` and
        polar :math:`\theta`, defined as in the ISO 31-11 standard
        [SphericalWolfram]_.

        Parameters
        ----------
        azimuth : float or numpy.ndarray
            Spherical azimuth coordinate.
        polar : float or numpy.ndarray
            Spherical polar coordinate.

        Returns
        -------
        x : numpy.ndarray
            Stereographic coordinate X of shape same shape as the input
            vector shape. Only the vectors with :math:`z` coordinate
            positive (`pole` = -1) or negative (`pole` = 1) are
            returned.
        y : numpy.ndarray
            Stereographic coordinate Y of shape same shape as the input
            vector shape. Only the vectors with :math:`z` coordinate
            positive (`pole` = -1) or negative (`pole` = 1) are
            returned.

        See Also
        --------
        vector2xy
        """
        v = Vector3d.from_polar(azimuth=azimuth, polar=polar)
        return self.vector2xy(v)
Ejemplo n.º 4
0
    def spherical2xy_split(self, azimuth, polar):
        r"""Return two sets of stereographic coordinates (X, Y) from 3D
        unit vectors created from spherical coordinates, azimuth
        :math:`\phi` and polar :math:`\theta`, defined as in the
        ISO 31-11 standard [SphericalWolfram]_: one set for vectors in
        the upper hemisphere, and one for the lower.

        Parameters
        ----------
        azimuth : float or numpy.ndarray
            Spherical azimuth coordinate.
        polar : float or numpy.ndarray
            Spherical polar coordinate.

        Returns
        -------
        x_upper : numpy.ndarray
            Stereographic coordinate X of upper hemisphere vectors, of
            shape same shape as the input vector shape.
        y_upper : numpy.ndarray
            Stereographic coordinate Y of upper hemisphere vectors, of
            shape same shape as the input vector shape.
        x_lower : numpy.ndarray
            Stereographic coordinate X of lower hemisphere vectors, of
            shape same shape as the input vector shape.
        y_lower : numpy.ndarray
            Stereographic coordinate Y of lower hemisphere vectors, of
            shape same shape as the input vector shape.

        See Also
        --------
        vector2xy
        """
        v = Vector3d.from_polar(azimuth=azimuth, polar=polar)
        return self.vector2xy_split(v)
Ejemplo n.º 5
0
 def get_plot_data(self):
     from orix.vector import Vector3d
     theta = np.linspace(0, 2 * np.pi + 1e-9, 361)
     rho = np.linspace(0, np.pi, 181)
     theta, rho = np.meshgrid(theta, rho)
     g = Vector3d.from_polar(rho, theta)
     n = Rodrigues.from_rotation(self).norm.data[:, np.newaxis, np.newaxis]
     if n.size == 0:
         return Rotation.from_neo_euler(AxAngle.from_axes_angles(g, np.pi))
     d = (-self.axis).dot_outer(g.unit).data
     x = n * d
     x = 2 * np.arctan(x**-1)
     x[x < 0] = np.pi
     x = np.min(x, axis=0)
     r = Rotation.from_neo_euler(AxAngle.from_axes_angles(g.unit, x))
     return r
Ejemplo n.º 6
0
 def test_polar_loop(self, vector):
     theta, phi, r = vector.to_polar()
     vector2 = Vector3d.from_polar(theta=theta.data, phi=phi.data, r=r.data)
     assert np.allclose(vector.data, vector2.data)
Ejemplo n.º 7
0
def test_polar(theta, phi, r, expected):
    assert np.allclose(Vector3d.from_polar(theta, phi, r).data,
                       expected.data,
                       atol=1e-5)
Ejemplo n.º 8
0
    def draw_circle(self, *args, opening_angle=np.pi / 2, steps=100, **kwargs):
        r"""Draw great or small circles with a given `opening_angle` to
        one or multiple vectors.

        A vector must be present in the current hemisphere for its
        circle to be drawn.

        Parameters
        ----------
        args : Vector3d or tuple of float or numpy.ndarray
            Vector(s), or azimuth and polar angles defining vectors, the
            latter two passed as separate arguments (not keyword
            arguments). Circles are drawn perpendicular to these with a
            given `opening_angle`.
        opening_angle : float or numpy.ndarray, optional
            Opening angle(s) around the vector(s). Default is
            :math:`\pi/2`, giving a great circle. If an array is passed,
            its size must be equal to the number of circles to draw.
        steps : int, optional
            Number of vectors to describe each circle, default is 100.
        kwargs
            Keyword arguments passed to
            :meth:`matplotlib.axes.Axes.plot` to alter the circles'
            appearance.

        See Also
        --------
        orix.vector.Vector3d.get_circle
        """
        azimuth, polar = self._pretransform_input(args)

        # Exclude vectors not visible in this hemisphere before creating
        # circles
        visible = self._visible_in_hemisphere(polar)
        if np.count_nonzero(visible) == 0:  # No circles to draw
            return
        else:
            azimuth = azimuth[visible]
            polar = polar[visible]

        # Get set of `steps` vectors delineating a circle per vector
        v = Vector3d.from_polar(azimuth=azimuth, polar=polar)
        circles = v.get_circle(opening_angle=opening_angle, steps=steps).unit

        # Enable using one color per circle
        color = kwargs.pop("color", "C0")
        color2 = _get_array_of_values(value=color, visible=visible)

        # Set above which elements circles will appear (zorder)
        new_kwargs = dict(zorder=ZORDER["draw_circle"], clip_on=False)
        for k, v in new_kwargs.items():
            kwargs.setdefault(k, v)

        hemisphere = self.hemisphere
        polar_cap = self._polar_cap
        for i, c in enumerate(circles):
            a, p = _sort_coords_by_shifted_bools(
                hemisphere=hemisphere,
                polar_cap=polar_cap,
                azimuth=c.azimuth.data,
                polar=c.polar.data,
            )
            super().plot(a, p, color=color2[i], **kwargs)
Ejemplo n.º 9
0
 def test_polar_loop(self, vector):
     azimuth, polar, radial = vector.to_polar()
     vector2 = Vector3d.from_polar(azimuth=azimuth.data,
                                   polar=polar.data,
                                   radial=radial.data)
     assert np.allclose(vector.data, vector2.data)
Ejemplo n.º 10
0
def test_polar(azimuth, polar, radial, expected):
    assert np.allclose(
        Vector3d.from_polar(azimuth=azimuth, polar=polar, radial=radial).data,
        expected.data,
        atol=1e-5,
    )