{"id":19824896,"url":"https://github.com/dennis-van-gils/opensimplex-loops","last_synced_at":"2026-01-23T17:32:55.382Z","repository":{"id":65517730,"uuid":"593720046","full_name":"Dennis-van-Gils/opensimplex-loops","owner":"Dennis-van-Gils","description":"Python library to generate seamlessly-looping animated images and closed curves, and seamlessy-tileable images. Based on 4D OpenSimplex noise.","archived":false,"fork":false,"pushed_at":"2024-08-12T13:33:44.000Z","size":4694,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-16T07:48:17.815Z","etag":null,"topics":["4d","curves","images","loop","looping","noise","opensimplex","polar","seamless","textures","tileable"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dennis-van-Gils.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.rst","dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"Dennis-van-Gils","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2023-01-26T17:31:33.000Z","updated_at":"2024-08-12T13:33:48.000Z","dependencies_parsed_at":"2024-08-12T11:17:28.528Z","dependency_job_id":null,"html_url":"https://github.com/Dennis-van-Gils/opensimplex-loops","commit_stats":{"total_commits":19,"total_committers":1,"mean_commits":19.0,"dds":0.0,"last_synced_commit":"1dc723d12aece3cb52eec85b319d5bce6a30d111"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dennis-van-Gils%2Fopensimplex-loops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dennis-van-Gils%2Fopensimplex-loops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dennis-van-Gils%2Fopensimplex-loops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dennis-van-Gils%2Fopensimplex-loops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dennis-van-Gils","download_url":"https://codeload.github.com/Dennis-van-Gils/opensimplex-loops/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248144525,"owners_count":21054943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["4d","curves","images","loop","looping","noise","opensimplex","polar","seamless","textures","tileable"],"created_at":"2024-11-12T11:06:25.586Z","updated_at":"2026-01-23T17:32:55.334Z","avatar_url":"https://github.com/Dennis-van-Gils.png","language":"Python","funding_links":["https://github.com/sponsors/Dennis-van-Gils"],"categories":[],"sub_categories":[],"readme":".. image:: https://img.shields.io/pypi/v/opensimplex-loops\n    :target: https://pypi.org/project/opensimplex-loops\n.. image:: https://img.shields.io/pypi/pyversions/opensimplex-loops\n    :target: https://pypi.org/project/opensimplex-loops\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n    :target: https://github.com/psf/black\n.. image:: https://img.shields.io/badge/License-MIT-purple.svg\n    :target: https://github.com/Dennis-van-Gils/opensimplex-loops/blob/master/LICENSE.txt\n.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.13304280.svg\n    :target: https://doi.org/10.5281/zenodo.13304280\n\nOpenSimplex Loops\n=================\n\nThis library provides higher-level functions that can generate seamlessly-looping\nanimated images and closed curves, and seamlessy-tileable images. It relies on 4D\nOpenSimplex noise, which is a type of\n`gradient noise \u003chttps://en.wikipedia.org/wiki/Gradient_noise\u003e`_ that features\nspatial coherence.\n\n- Github: https://github.com/Dennis-van-Gils/opensimplex-loops\n- PyPI: https://pypi.org/project/opensimplex-loops\n\nThis library is an extension to the\n`OpenSimplex Python library by lmas \u003chttps://github.com/lmas/opensimplex\u003e`_.\n\nInspiration taken from\n`Coding Challenge #137: 4D OpenSimplex Noise Loop \u003chttps://youtu.be/3_0Ax95jIrk\u003e`_\nby `The Coding Train \u003chttps://www.youtube.com/c/TheCodingTrain\u003e`_.\n\n\nDemos\n=====\n\n``looping_animated_2D_image()``\n-------------------------------\n\n    .. image:: https://raw.githubusercontent.com/Dennis-van-Gils/opensimplex-loops/master/images/demo_looping_animated_2D_image.gif\n        :alt: looping_animated_2D_image\n\n    Seamlessly-looping animated 2D images.\n\n    Code: `\u003cdemos/demo_looping_animated_2D_image.py\u003e`_\n\n``looping_animated_closed_1D_curve()``\n--------------------------------------\n\n    .. image:: https://raw.githubusercontent.com/Dennis-van-Gils/opensimplex-loops/master/images/demo_looping_animated_circle.gif\n        :alt: looping_animated_circle\n\n    .. image:: https://raw.githubusercontent.com/Dennis-van-Gils/opensimplex-loops/master/images/demo_looping_animated_closed_1D_curve.gif\n        :alt: looping_animated_closed_1D_curve\n\n    Seamlessly-looping animated 1D curves, each curve in turn also closing up\n    seamlessly back-to-front.\n\n    Code: `\u003cdemos/demo_looping_animated_circle.py\u003e`_\n\n    Code: `\u003cdemos/demo_looping_animated_closed_1D_curve.py\u003e`_\n\n``tileable_2D_image()``\n-----------------------\n\n    .. image:: https://raw.githubusercontent.com/Dennis-van-Gils/opensimplex-loops/master/images/demo_tileable_2D_image.png\n        :alt: tileable_2D_image\n\n    Seamlessly-tileable 2D image.\n\n    Code: `\u003cdemos/demo_tileable_2D_image.py\u003e`_\n\n\nInstallation\n============\n\n::\n\n    pip install opensimplex-loops\n\nThis will install the following dependencies:\n\n- ``opensimplex``\n- ``numpy``\n- ``numba``\n- ``numba-progress``\n\nNotes:\n\n- The `OpenSimplex` library by lmas does not enforce the use of the\n  `numba \u003chttps://numba.pydata.org/\u003e`_ package, but is left optional instead.\n  Here, I have set it as a requirement due to the heavy computation required\n  by these highler-level functions. I have them optimized for `numba` which\n  enables multi-core parallel processing within Python, resulting in major\n  speed improvements compared to as running without. I have gotten computational\n  speedups by a factor of ~200.\n\n- Note that the very first call of each of these OpenSimplex functions will take\n  a longer time than later calls. This is because `numba` needs to compile this\n  Python code to bytecode specific to your platform, once.\n\n- The ``numba-progress`` package is actually optional. When present, a progress\n  bar will be shown during the noise generation.\n\n\nAPI\n===\n\n``looping_animated_2D_image(...)``\n----------------------------------\n\n    Generates a stack of seamlessly-looping animated 2D raster images drawn\n    from 4D OpenSimplex noise.\n\n    The first two OpenSimplex dimensions are used to describe a plane that gets\n    projected onto a 2D raster image. The last two dimensions are used to\n    describe a circle in time.\n\n    Args:\n        N_frames (`int`, default = 200)\n            Number of time frames\n\n        N_pixels_x (`int`, default = 1000)\n            Number of pixels on the x-axis\n\n        N_pixels_y (`int` | `None`, default = `None`)\n            Number of pixels on the y-axis. When set to None `N_pixels_y` will\n            be set equal to `N_pixels_x`.\n\n        t_step (`float`, default = 0.1)\n            Time step\n\n        x_step (`float`, default = 0.01)\n            Spatial step in the x-direction\n\n        y_step (`float` | `None`, default = `None`)\n            Spatial step in the y-direction. When set to None `y_step` will be\n            set equal to `x_step`.\n\n        dtype (`type`, default = `numpy.double`)\n            Return type of the noise array elements. To reduce the memory\n            footprint one can change from the default `numpy.double` to e.g.\n            `numpy.float32`.\n\n        seed (`int`, default = 3)\n            Seed value for the OpenSimplex noise\n\n        verbose (`bool`, default = `True`)\n            Print 'Generating noise...' to the terminal? If the `numba_progress`\n            package is present a progress bar will also be shown.\n\n    Returns:\n        The 2D image stack as 3D array [time, y-pixel, x-pixel] containing the\n        OpenSimplex noise values as floating points. The output is garantueed to\n        be in the range [-1, 1], but the exact extrema cannot be known a-priori\n        and are probably quite smaller than [-1, 1].\n\n``looping_animated_closed_1D_curve(...)``\n-----------------------------------------\n\n    Generates a stack of seamlessly-looping animated 1D curves, each curve in\n    turn also closing up seamlessly back-to-front, drawn from 4D OpenSimplex\n    noise.\n\n    The first two OpenSimplex dimensions are used to describe a circle that gets\n    projected onto a 1D curve. The last two dimensions are used to describe a\n    circle in time.\n\n    Args:\n        N_frames (`int`, default = 200)\n            Number of time frames\n\n        N_pixels_x (`int`, default = 1000)\n            Number of pixels of the curve\n\n        t_step (`float`, default = 0.1)\n            Time step\n\n        x_step (`float`, default = 0.01)\n            Spatial step in the x-direction\n\n        dtype (`type`, default = `numpy.double`)\n            Return type of the noise array elements. To reduce the memory\n            footprint one can change from the default `numpy.double` to e.g.\n            `numpy.float32`.\n\n        seed (`int`, default = 3)\n            Seed value for the OpenSimplex noise\n\n        verbose (`bool`, default = `True`)\n            Print 'Generating noise...' to the terminal? If the `numba_progress`\n            package is present a progress bar will also be shown.\n\n    Returns:\n        The 1D curve stack as 2D array [time, x-pixel] containing the\n        OpenSimplex noise values as floating points. The output is garantueed to\n        be in the range [-1, 1], but the exact extrema cannot be known a-priori\n        and are probably quite smaller than [-1, 1].\n\n``tileable_2D_image(...)``\n--------------------------\n\n    Generates a seamlessly-tileable 2D raster image drawn from 4D OpenSimplex\n    noise.\n\n    The first two OpenSimplex dimensions are used to describe a circle that gets\n    projected onto the x-axis of the 2D raster image. The last two dimensions\n    are used to describe another circle that gets projected onto the y-axis of\n    the 2D raster image.\n\n    Args:\n        N_pixels_x (`int`, default = 1000)\n            Number of pixels on the x-axis\n\n        N_pixels_y (`int` | `None`, default = `None`)\n            Number of pixels on the y-axis. When set to None `N_pixels_y` will\n            be set equal to `N_pixels_x`.\n\n        x_step (`float`, default = 0.01)\n            Spatial step in the x-direction\n\n        y_step (`float` | `None`, default = `None`)\n            Spatial step in the y-direction. When set to None `y_step` will be\n            set equal to `x_step`.\n\n        dtype (`type`, default = `numpy.double`)\n            Return type of the noise array elements. To reduce the memory\n            footprint one can change from the default `numpy.double` to e.g.\n            `numpy.float32`.\n\n        seed (`int`, default = 3)\n            Seed value for the OpenSimplex noise\n\n        verbose (`bool`, default = `True`)\n            Print 'Generating noise...' to the terminal? If the `numba_progress`\n            package is present a progress bar will also be shown.\n\n    Returns:\n        The 2D image as 2D array [y-pixel, x-pixel] containing the\n        OpenSimplex noise values as floating points. The output is garantueed to\n        be in the range [-1, 1], but the exact extrema cannot be known a-priori\n        and are probably quite smaller than [-1, 1].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdennis-van-gils%2Fopensimplex-loops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdennis-van-gils%2Fopensimplex-loops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdennis-van-gils%2Fopensimplex-loops/lists"}