Skip to content

Commit

Permalink
Add various pattern generators.
Browse files Browse the repository at this point in the history
  • Loading branch information
KelSolaar committed Oct 27, 2023
1 parent 31a2fe3 commit eaf8e98
Show file tree
Hide file tree
Showing 12 changed files with 382 additions and 28 deletions.
21 changes: 21 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,27 @@ Rösch-MacAdam Visuals
.. image:: https://raw.githubusercontent.com/colour-science/colour-visuals/master/docs/_static/Plotting_VisualRoschMacAdam.png

Patterns
~~~~~~~~

.. code-block:: python
>>> colour_visuals.pattern_hue_swatches()
.. image:: https://raw.githubusercontent.com/colour-science/colour-visuals/master/docs/_static/Plotting_PatternHueSwatches.png

.. code-block:: python
>>> colour_visuals.pattern_hue_stripes()
.. image:: https://raw.githubusercontent.com/colour-science/colour-visuals/master/docs/_static/Plotting_PatternHueStripes.png

.. code-block:: python
>>> colour_visuals.pattern_colour_wheel()
.. image:: https://raw.githubusercontent.com/colour-science/colour-visuals/master/docs/_static/Plotting_PatternColourWheel.png

User Guide
----------

Expand Down
10 changes: 10 additions & 0 deletions colour_visuals/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
from .grid import (
VisualGrid,
)
from .patterns import (
pattern_colour_wheel,
pattern_hue_stripes,
pattern_hue_swatches,
)
from .pointer_gamut import (
VisualPointerGamut2D,
VisualPointerGamut3D,
Expand Down Expand Up @@ -78,6 +83,11 @@
__all__ += [
"VisualRoschMacAdam",
]
__all__ += [
"pattern_hue_swatches",
"pattern_hue_stripes",
"pattern_colour_wheel",
]
__application_name__ = "Colour - Visuals"

__major_version__ = "0"
Expand Down
229 changes: 229 additions & 0 deletions colour_visuals/patterns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
"""
Pattern Generators
==================
Defines various pattern generators:
- :func:`colour_visuals.pattern_hue_swatches`
- :func:`colour_visuals.pattern_hue_stripes`
- :func:`colour_visuals.pattern_colour_wheel`
"""

from __future__ import annotations

import numpy as np
from colour.hints import Literal, NDArray
from colour.models import HSV_to_RGB
from colour.utilities import full, orient, tstack

__author__ = "Colour Developers"
__copyright__ = "Copyright 2023 Colour Developers"
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
__maintainer__ = "Colour Developers"
__email__ = "[email protected]"
__status__ = "Production"

__all__ = [
"pattern_hue_swatches",
"pattern_hue_stripes",
"pattern_colour_wheel",
]


def pattern_hue_swatches(count: int = 12, samples: int = 256) -> NDArray:
"""
Generate a given count of hue swatches.
Parameters
----------
count
Hue swatch count.
samples
Hue swatch samples.
Examples
--------
>>> import os
>>> import pygfx as gfx
>>> import pylinalg as la
>>> from colour.plotting import plot_image
>>> from colour.utilities import suppress_stdout
>>> from colour_visuals import VisualRGBScatter3D, VisualRGBColourspace3D
>>> from wgpu.gui.auto import WgpuCanvas
>>> plot_image(pattern_hue_swatches())
... # doctest: +ELLIPSIS
(<Figure size ... with 1 Axes>, <...Axes...>)
.. image:: ../_static/Plotting_PatternHueSwatches.png
:align: center
:alt: pattern-hue-swatches
>>> with suppress_stdout():
... canvas = WgpuCanvas(size=(960, 540))
... scene = gfx.Scene()
... scene.add(
... gfx.Background(
... None, gfx.BackgroundMaterial(np.array([0.18, 0.18, 0.18]))
... )
... )
... visual = VisualRGBScatter3D(pattern_hue_swatches(), model="RGB")
... camera = gfx.PerspectiveCamera(50, 16 / 9)
... camera.show_object(visual, up=np.array([0, 0, 1]), scale=1.25)
... scene.add(visual)
... if os.environ.get("CI") is None:
... gfx.show(scene, camera=camera, canvas=canvas)
...
.. image:: ../_static/Plotting_HueSwatches.png
:align: center
:alt: hue-swatches
"""

H = np.linspace(0, 1, count + 1)

xv, yv = np.meshgrid(
np.linspace(0, 1, samples), np.linspace(0, 1, samples)
)

slices = []
for i in range(count + 1):
slices.append(tstack([full(xv.shape, H[i]), xv, yv]))

RGB = HSV_to_RGB(np.hstack(slices))

return RGB


def pattern_hue_stripes(count: int = 6, samples=256):
"""
Generate a given count of hue stripes.
Parameters
----------
count
Hue stripe count.
samples
Hue stripe samples.
Examples
--------
>>> import os
>>> import pygfx as gfx
>>> import pylinalg as la
>>> from colour.plotting import plot_image
>>> from colour.utilities import suppress_stdout
>>> from colour_visuals import VisualRGBScatter3D, VisualRGBColourspace3D
>>> from wgpu.gui.auto import WgpuCanvas
>>> plot_image(pattern_hue_stripes())
... # doctest: +ELLIPSIS
(<Figure size ... with 1 Axes>, <...Axes...>)
.. image:: ../_static/Plotting_PatternHueStripes.png
:align: center
:alt: pattern-hue-stripes
>>> with suppress_stdout():
... canvas = WgpuCanvas(size=(960, 540))
... scene = gfx.Scene()
... scene.add(
... gfx.Background(
... None, gfx.BackgroundMaterial(np.array([0.18, 0.18, 0.18]))
... )
... )
... visual = VisualRGBScatter3D(pattern_hue_stripes(), model="RGB")
... camera = gfx.PerspectiveCamera(50, 16 / 9)
... camera.show_object(visual, up=np.array([0, 0, 1]), scale=1.25)
... scene.add(visual)
... if os.environ.get("CI") is None:
... gfx.show(scene, camera=camera, canvas=canvas)
...
.. image:: ../_static/Plotting_HueStripes.png
:align: center
:alt: hue-stripes
"""

H = np.linspace(0, 1, count + 1)
V = np.linspace(0, 1, samples)

xv, yv = np.meshgrid(H, V)

RGB = HSV_to_RGB(tstack([xv, np.ones(xv.shape), yv]))

return orient(RGB, "90 CCW")


def pattern_colour_wheel(
samples: int = 256,
method: Literal["Colour", "Nuke"] = "Colour",
clip_circle: bool = True,
) -> NDArray:
"""
Generate a colour wheel.
Parameters
----------
samples
Colour wheel samples.
method
Colour wheel method.
clip_circle
Whether to clip the colour wheel to a circle shape.
Examples
--------
>>> import os
>>> import pygfx as gfx
>>> import pylinalg as la
>>> from colour.plotting import plot_image
>>> from colour.utilities import suppress_stdout
>>> from colour_visuals import VisualRGBScatter3D, VisualRGBColourspace3D
>>> from wgpu.gui.auto import WgpuCanvas
>>> plot_image(pattern_colour_wheel())
... # doctest: +ELLIPSIS
(<Figure size ... with 1 Axes>, <...Axes...>)
.. image:: ../_static/Plotting_PatternColourWheel.png
:align: center
:alt: pattern-colour-wheel
>>> with suppress_stdout():
... canvas = WgpuCanvas(size=(960, 540))
... scene = gfx.Scene()
... scene.add(
... gfx.Background(
... None, gfx.BackgroundMaterial(np.array([0.18, 0.18, 0.18]))
... )
... )
... visual = VisualRGBScatter3D(pattern_colour_wheel(), model="RGB")
... camera = gfx.PerspectiveCamera(50, 16 / 9)
... camera.show_object(visual, up=np.array([0, 0, 1]), scale=1.25)
... scene.add(visual)
... if os.environ.get("CI") is None:
... gfx.show(scene, camera=camera, canvas=canvas)
...
.. image:: ../_static/Plotting_ColourWheel.png
:align: center
:alt: colour_wheel
"""

xx, yy = np.meshgrid(
np.linspace(-1, 1, samples), np.linspace(-1, 1, samples)
)

S = np.sqrt(xx**2 + yy**2)
H = (np.arctan2(xx, yy) + np.pi) / (np.pi * 2)

HSV = tstack([H, S, np.ones(H.shape)])
RGB = HSV_to_RGB(HSV)

if clip_circle:
RGB[S > 1] = 0

if method.lower() == "nuke":
RGB = orient(RGB, "Flip")
RGB = orient(RGB, "90 CW")

return RGB
Binary file added docs/_static/Plotting_ColourWheel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/Plotting_HueStripes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/Plotting_HueSwatches.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/Plotting_PatternColourWheel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/Plotting_PatternHueStripes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/Plotting_PatternHueSwatches.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions docs/colour_visuals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@ Helper Visuals
VisualAxes
VisualGrid

Patterns Visuals
----------------

``colour_visuals``

.. currentmodule:: colour_visuals

.. autosummary::
:toctree: generated/
:template: class.rst

pattern_hue_swatches
pattern_hue_stripes
pattern_colour_wheel

Common Utilities
----------------

Expand Down
21 changes: 21 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,27 @@ Rösch-MacAdam Visuals
.. image:: _static/Plotting_VisualRoschMacAdam.png

Patterns
~~~~~~~~

.. code-block:: python
>>> colour_visuals.pattern_hue_swatches()
.. image:: _static/Plotting_PatternHueSwatches.png

.. code-block:: python
>>> colour_visuals.pattern_hue_stripes()
.. image:: _static/Plotting_PatternHueStripes.png

.. code-block:: python
>>> colour_visuals.pattern_colour_wheel()
.. image:: _static/Plotting_PatternColourWheel.png

User Guide
----------

Expand Down
Loading

0 comments on commit eaf8e98

Please sign in to comment.