Beispiel #1
0
    def test_point_at_angle_on_ellipse(self):
        """
        Tests :func:`colour.algebra.geometry.point_at_angle_on_ellipse`
        definition.
        """

        np.testing.assert_almost_equal(point_at_angle_on_ellipse(
            np.array([0, 90, 180, 270]), np.array([0.0, 0.0, 2, 1, 0])),
                                       np.array([[2, 0], [0, 1], [-2, 0],
                                                 [0, -1]]),
                                       decimal=7)

        np.testing.assert_almost_equal(point_at_angle_on_ellipse(
            np.linspace(0, 360, 10), np.array([0.5, 0.5, 2, 1, 45])),
                                       np.array([
                                           [1.91421356, 1.91421356],
                                           [1.12883096, 2.03786992],
                                           [0.04921137, 1.44193985],
                                           [-0.81947922, 0.40526565],
                                           [-1.07077081, -0.58708129],
                                           [-0.58708129, -1.07077081],
                                           [0.40526565, -0.81947922],
                                           [1.44193985, 0.04921137],
                                           [2.03786992, 1.12883096],
                                           [1.91421356, 1.91421356],
                                       ]),
                                       decimal=7)
Beispiel #2
0
    def test_point_at_angle_on_ellipse(self):
        """
        Tests :func:`colour.algebra.geometry.point_at_angle_on_ellipse`
        definition.
        """

        np.testing.assert_almost_equal(
            point_at_angle_on_ellipse(
                np.array([0, 90, 180, 270]), np.array([0.0, 0.0, 2, 1, 0])),
            np.array([[2, 0], [0, 1], [-2, 0], [0, -1]]),
            decimal=7)

        np.testing.assert_almost_equal(
            point_at_angle_on_ellipse(
                np.linspace(0, 360, 10), np.array([0.5, 0.5, 2, 1, 45])),
            np.array([
                [1.91421356, 1.91421356],
                [1.12883096, 2.03786992],
                [0.04921137, 1.44193985],
                [-0.81947922, 0.40526565],
                [-1.07077081, -0.58708129],
                [-0.58708129, -1.07077081],
                [0.40526565, -0.81947922],
                [1.44193985, 0.04921137],
                [2.03786992, 1.12883096],
                [1.91421356, 1.91421356],
            ]),
            decimal=7)
Beispiel #3
0
def plot_ellipses_MacAdam1942_in_chromaticity_diagram(
        chromaticity_diagram_callable=plot_chromaticity_diagram,
        method='CIE 1931',
        chromaticity_diagram_clipping=False,
        ellipse_parameters=None,
        **kwargs):
    """
    Plots *MacAdam (1942) Ellipses (Observer PGN)* in the
    *Chromaticity Diagram* according to given method.

    Parameters
    ----------
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.
    chromaticity_diagram_clipping : bool, optional,
        Whether to clip the *Chromaticity Diagram* colours with the ellipses.
    ellipse_parameters : dict or array_like, optional
        Parameters for the :class:`Ellipse` class, ``ellipse_parameters`` can
        be either a single dictionary applied to all the ellipses with same
        settings or a sequence of dictionaries with different settings for each
        ellipse.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.diagrams.plot_chromaticity_diagram`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_ellipses_MacAdam1942_in_chromaticity_diagram()  # doctest: +SKIP

    .. image:: ../_static/\
Plotting_Plot_Ellipses_MacAdam1942_In_Chromaticity_Diagram.png
        :align: center
        :alt: plot_ellipses_MacAdam1942_in_chromaticity_diagram
    """

    settings = {'uniform': True}
    settings.update(kwargs)

    figure, axes = artist(**settings)

    settings = dict(kwargs)
    settings.update({'axes': axes, 'standalone': False})

    ellipses_coefficients = ellipses_MacAdam1942(method=method)

    if chromaticity_diagram_clipping:
        diagram_clipping_path_x = []
        diagram_clipping_path_y = []
        for coefficients in ellipses_coefficients:
            coefficients = np.copy(coefficients)

            coefficients[2:4] /= 2

            x, y = tsplit(
                point_at_angle_on_ellipse(
                    np.linspace(0, 360, 36),
                    coefficients,
                ))
            diagram_clipping_path_x.append(x)
            diagram_clipping_path_y.append(y)

        diagram_clipping_path = np.rollaxis(
            np.array([diagram_clipping_path_x, diagram_clipping_path_y]), 0, 3)
        diagram_clipping_path = Path.make_compound_path_from_polys(
            diagram_clipping_path).vertices
        settings.update({'diagram_clipping_path': diagram_clipping_path})

    chromaticity_diagram_callable(**settings)

    ellipse_settings_collection = [{
        'color':
        COLOUR_STYLE_CONSTANTS.colour.cycle[4],
        'alpha':
        0.4,
        'edgecolor':
        COLOUR_STYLE_CONSTANTS.colour.cycle[1],
        'linewidth':
        colour_style()['lines.linewidth']
    } for _ in range(len(ellipses_coefficients))]

    if ellipse_parameters is not None:
        if not isinstance(ellipse_parameters, dict):
            assert len(ellipse_parameters) == len(ellipses_coefficients), (
                'Multiple ellipse parameters defined, but they do not match '
                'the ellipses count!')

        for i, ellipse_settings in enumerate(ellipse_settings_collection):
            if isinstance(ellipse_parameters, dict):
                ellipse_settings.update(ellipse_parameters)
            else:
                ellipse_settings.update(ellipse_parameters[i])

    for i, coefficients in enumerate(ellipses_coefficients):
        x_c, y_c, a_a, a_b, theta_e = coefficients
        ellipse = Ellipse((x_c, y_c), a_a, a_b, theta_e,
                          **ellipse_settings_collection[i])
        axes.add_artist(ellipse)

    settings.update({'standalone': True})
    settings.update(kwargs)

    return render(**settings)
Beispiel #4
0
def ellipses_MacAdam1942(method='CIE 1931'):
    """
    Returns *MacAdam (1942) Ellipses (Observer PGN)* coefficients according to
    given method.

    Parameters
    ----------
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Computation method.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> ellipses_MacAdam1942()[0]  # doctest: +SKIP
    array([  1.60000000e-01,   5.70000000e-02,   5.00000023e-03,
             1.56666660e-02,  -2.77000015e+01])
    """

    method = method.upper()

    if method == 'CIE 1931':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy

    elif method == 'CIE 1960 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_UCS_uv(xy)

    elif method == 'CIE 1976 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_Luv_uv(xy)

    else:
        raise ValueError(
            'Invalid method: "{0}", must be one of '
            '{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}'.format(
                method))

    x, y, _a, _b, _theta, a, b, theta = tsplit(MACADAM_1942_ELLIPSES_DATA)

    ellipses_coefficients = []
    for i in range(len(theta)):
        xy = point_at_angle_on_ellipse(
            np.linspace(0, 360, 36),
            [x[i], y[i], a[i] / 60, b[i] / 60, theta[i]],
        )
        ij = xy_to_ij(xy)
        ellipses_coefficients.append(
            ellipse_coefficients_canonical_form(ellipse_fitting(ij)))

    return ellipses_coefficients
Beispiel #5
0
def plot_ellipses_MacAdam1942_in_chromaticity_diagram(
        chromaticity_diagram_callable=plot_chromaticity_diagram,
        method='CIE 1931',
        chromaticity_diagram_clipping=False,
        ellipse_parameters=None,
        **kwargs):
    """
    Plots *MacAdam (1942) Ellipses (Observer PGN)* in the
    *Chromaticity Diagram* according to given method.

    Parameters
    ----------
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.
    chromaticity_diagram_clipping : bool, optional,
        Whether to clip the *Chromaticity Diagram* colours with the ellipses.
    ellipse_parameters : dict or array_like, optional
        Parameters for the :class:`Ellipse` class, ``ellipse_parameters`` can
        be either a single dictionary applied to all the ellipses with same
        settings or a sequence of dictionaries with different settings for each
        ellipse.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.diagrams.plot_chromaticity_diagram`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_ellipses_MacAdam1942_in_chromaticity_diagram()  # doctest: +SKIP

    .. image:: ../_static/\
Plotting_Plot_Ellipses_MacAdam1942_In_Chromaticity_Diagram.png
        :align: center
        :alt: plot_ellipses_MacAdam1942_in_chromaticity_diagram
    """

    settings = {'uniform': True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    settings = dict(kwargs)
    settings.update({'axes': axes, 'standalone': False})

    ellipses_coefficients = ellipses_MacAdam1942(method=method)

    if chromaticity_diagram_clipping:
        diagram_clipping_path_x = []
        diagram_clipping_path_y = []
        for coefficients in ellipses_coefficients:
            coefficients = np.copy(coefficients)

            coefficients[2:4] /= 2

            x, y = tsplit(
                point_at_angle_on_ellipse(
                    np.linspace(0, 360, 36),
                    coefficients,
                ))
            diagram_clipping_path_x.append(x)
            diagram_clipping_path_y.append(y)

        diagram_clipping_path = np.rollaxis(
            np.array([diagram_clipping_path_x, diagram_clipping_path_y]), 0, 3)
        diagram_clipping_path = Path.make_compound_path_from_polys(
            diagram_clipping_path).vertices
        settings.update({'diagram_clipping_path': diagram_clipping_path})

    chromaticity_diagram_callable(**settings)

    ellipse_settings_collection = [{
        'color': COLOUR_STYLE_CONSTANTS.colour.cycle[4],
        'alpha': 0.4,
        'edgecolor': COLOUR_STYLE_CONSTANTS.colour.cycle[1],
        'linewidth': colour_style()['lines.linewidth']
    } for _ellipses_coefficient in ellipses_coefficients]

    if ellipse_parameters is not None:
        if not isinstance(ellipse_parameters, dict):
            assert len(ellipse_parameters) == len(ellipses_coefficients), (
                'Multiple ellipse parameters defined, but they do not match '
                'the ellipses count!')

        for i, ellipse_settings in enumerate(ellipse_settings_collection):
            if isinstance(ellipse_parameters, dict):
                ellipse_settings.update(ellipse_parameters)
            else:
                ellipse_settings.update(ellipse_parameters[i])

    for i, coefficients in enumerate(ellipses_coefficients):
        x_c, y_c, a_a, a_b, theta_e = coefficients
        ellipse = Ellipse((x_c, y_c), a_a, a_b, theta_e,
                          **ellipse_settings_collection[i])
        axes.add_artist(ellipse)

    settings.update({'standalone': True})
    settings.update(kwargs)

    return render(**settings)
Beispiel #6
0
def ellipses_MacAdam1942(method='CIE 1931'):
    """
    Returns *MacAdam (1942) Ellipses (Observer PGN)* coefficients according to
    given method.

    Parameters
    ----------
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Computation method.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> ellipses_MacAdam1942()[0]  # doctest: +SKIP
    array([  1.60000000e-01,   5.70000000e-02,   5.00000023e-03,
             1.56666660e-02,  -2.77000015e+01])
    """

    method = method.upper()

    if method == 'CIE 1931':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy

    elif method == 'CIE 1960 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_UCS_uv(xy)

    elif method == 'CIE 1976 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_Luv_uv(xy)

    else:
        raise ValueError(
            'Invalid method: "{0}", must be one of '
            '{{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}}'.format(
                method))

    x, y, _a, _b, _theta, a, b, theta = tsplit(MACADAM_1942_ELLIPSES_DATA)

    ellipses_coefficients = []
    # pylint: disable=C0200
    for i in range(len(theta)):
        xy = point_at_angle_on_ellipse(
            np.linspace(0, 360, 36),
            [x[i], y[i], a[i] / 60, b[i] / 60, theta[i]],
        )
        ij = xy_to_ij(xy)
        ellipses_coefficients.append(
            ellipse_coefficients_canonical_form(ellipse_fitting(ij)))

    return ellipses_coefficients