Giter Site home page Giter Site logo

jasonwebb / 2d-differential-growth-experiments Goto Github PK

View Code? Open in Web Editor NEW
222.0 13.0 18.0 102.81 MB

Visual experiments exploring differential growth as a 2D morphogenesis tool.

Home Page: https://jasonwebb.github.io/2d-differential-growth-experiments/

License: Other

JavaScript 67.84% HTML 23.77% CSS 8.40%
javascript 2d differential-growth p5js morphogenesis creative-coding generative-art procedural

2d-differential-growth-experiments's Introduction

Read my Medium article to learn more about differential growth and this project.

Additional media is available on my portfolio

This repo contains a series of visual experiments built with JavaScript that explore the topic of differential growth as a method for generating interesting 2D forms.

I am particularly interested in the application of such techniques in the context of digital fabrication, so these experiments will be more focused on schematic representations (colorless, vector-based, SVG/STL exports) over purely visual effects.

About differential growth

Differential growth is a process that uses simple rules to produce undulating, buckling forms that mimic or simulate similar forms found in the natural world. Meandering rivers, rippled surface textures of plants/seeds/fruits, space-filling behaviors of worms, snakes, intestines, and more are all reminiscent of this process, perhaps even making use of some of the same principles through physical and organic components.

The process itself can be described algorithmically at a high level by first supposing that we are starting with a single continuous path consisting of points (called nodes) connected by lines (called edges). In such a system, we apply the following rules:

  1. Each node wants to be closer to it's connected neighbors, and will experience an attraction force towards them.
  2. Each node wants to sit on a straight line between it's neighbors to minimize curvature.
  3. Each node must never be too close to any other node to prevent pinching or breaking of the overall continuity of the line.
  4. When the distance between two nodes exceeds a predefined distance (due to the influence of the other rules), a new node must be injected between them to split the line.
  5. New nodes are introduced to the system according to some growth scheme in order to induce asymmetry.
    • Without this rule the entire system would just uniformly expand and reach an equilibrium state.

Within these rules you can see several opportunities for customization that enable a certain amount of creative direction to be imposed by the developer. These include:

  • The maximum distance between connected nodes before their shared edge is split.
  • The minimum distance between all nodes.
  • The attraction force between connected nodes.
  • The repulsion force between nearby nodes.
  • The radius around each node used to calculate which nearby nodes have an influence on it.
  • A growth scheme that determines when and how new nodes are introduced to the system to induce interesting asymmetry.

Global keyboard controls

All of these keyboard controls are available in each experiment.

Key Result
1-9 Change initial seed path shape (if available)
t Toggle trace mode
n Toggle visibility of nodes
r Reset simulation with same parameters
Space Pause or unpause the simulation
i Toggle inverting of colors
d Toggle "debug mode"
f Toggle shape fills
h Toggle drawing of periodic path history
s Download an SVG of current geometry
b Toggle visibility of path bounds

Going further

This repository is more like a sketchbook, meant to contain some thematic scribbles on the topic of differential growth. I did not take a very rigorous approach in these experiments, opting to focus more on curiosity and effects than sheer performance and broader applications.

There are a lot of ways that the code I've written can be improved, or the algorithm itself explored more deeply, and I encourage you to take the next steps to expand upon what I've provided and create something new and awesome! Here are a few ideas that I've thought about exploring:

  1. Tune forces (attraction, repulsion, and alignment) to identify stable and interesting regions of the parameter space.
  2. Make optimization improvements to enable larger scales, without compromising too much in code readability.
    • Maybe a more efficient spatial index or nearest-neighbor algorithm can be found?
  3. Move into the third dimension. Many routes to explore here, including:
    1. Keep the simulation focused on 2D, but take snapshots on intervals and increment Z position for next iteration.
    2. Use a 3D package like ThreeJS and map the same 2D simulation onto the surfaces of 3D meshes.
    3. Explore professional-grade VFX and CAD options like Houdini, Unity, and Rhino + Grasshopper to achieve extreme performance.
  4. Port the code into a more performant language / framework like openFrameworks or Cinder. Even the Java-based Processing environment may show some performance gains!

References

Local install instructions

  1. Run npm install in both the root (/) and core/ folders.
  2. Run gulp to kick off a watch process and a browser window with LiveReload enabled.
  3. Keep Gulp running and the browser window open while making changes. If all goes well, new builds will kick off when you save your changes and the browser will refresh!

Packages used

  • p5js for canvas drawing and miscellaneous helper functions (like lerp and map).
  • rbush for a fast R-tree spatial index implementation
  • rbush-knn for k-nearest neighbors searching of rbush index
  • point-in-polygon for constraining nodes inside of bounding paths
  • svg-pathdata for extracting X,Y coordinates out of SVG <path> elements. Used to import SVG files.
  • svg-points for generating the d attribute of SVG <path> elements. Used to export SVG files from paths.
  • file-saver for initiating a download prompt when exporting SVG files
  • browserify, babel, and others for working with modern ES6 and module patterns.

Samples

Single line growth process

Triangle

Multiple shapes

SVG supershape as input

Opposing arcs converging

2d-differential-growth-experiments's People

Contributors

douglowder avatar jasonwebb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

2d-differential-growth-experiments's Issues

SVG download

HI Jason,
I have loved watching the GitHub.io deomos, and would like to try and plot a few of the examples. When I down load the SVG ( press s) the SVG seems to have an error and can not be opened in either Inkscape nor fusion. Is there something I need to do differently when downloading the SVG ?
differential-growth-1587315052808.zip

Research and implement a module system

I'd like to break my classes and parameters out into dedicated files to make the codebase easier to navigate and expand, but I have to admit that my knowledge of module systems in the browser is a bit lacking, especially when ES6 + Babel is involved.

I need to research the two most widespread systems in use today and figure out how they can work with ES6 + Babel.

  • AMD (RequireJS)
  • CommonJS

Research spatial search algorithms to improve performance

One critical aspect of this system that may not be handled by a physics engine is the ability to locate all of the nodes around a given node within a certain radius. All of these nodes will exert a "repulsion" force on each other, which would be easily handled by the physics engine, but finding those nodes in the first place is a more specialized problem.

Various algorithms (and libraries) exist to efficiently solve this problem. These are generally classified as "spatial search" algorithms, and include algorithms like R-trees, KD trees, quadtrees, octrees, and maybe more. Some are more abstracted than others, and may or may not be appropriate for this simplified problem (a two-dimensional system)

Extrnal svg not rendering as expected

I am having some difficulty in using external SVGs, also when using the playground This is an example of the SVG I would like to use.
test.svg.txt
This is what I would expect to see
image
but this is what is rendered on import
image
Can you give some pointers on the SVG formatting that is expected?

Question: Could it also be used to shrink a form until we get just the center line?

Thank you very much for sharing this great library!,
it is always very impressive when mathematics and computer science become visible.

Your software gave me an idea:
It's strange that we still have the unresolved computer science problem to
create a single stroke font from an outline font:

Outline Font to Single Line, Stroke Font

Therefore I have this question:

Would it be possible to use your software to shrink an outline until only one line remains?

Thanks a lot for any answer.
Kind regards,
Thomas

Choose a physics engine to integrate to improve performance

Currently the application slows down (on my machine) once about 500 nodes have been added to the screen. This is caused mainly by the brute force method I used to determine and apply various forces (attraction, repulsion, and alignment).

I've also not implemented acceleration into the movements of the nodes, which may make the geometry more stable, or at least make it look nicer.

There are a few great JavaScript physics engines out there that all look equally good for this project at first glance. I just need to take some time to check them all out more thoroughly and make a decision.

Engines to evaluate:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.