Skip to content

Hodapp87/contextual

Repository files navigation

Contextual

Build Status

This is a Haskell library for drawing algorithmic images based on context-free grammars.

This was inspired by the wonderful Context Free. Over the course of the past few years, I rewrote bits of Context Free in other languages as practice (at least, that's what I tell myself in hindsight):

I'd highly recommend not looking at the code for any of those, since most of it's an ill-maintained mess and proof-of-concept. I started this version in late 2013 when I first started learning Haskell, but in this rewrite I threw away nearly all of the code from that attempt.

The name contextual is something of a pun on Context Free. It might change later when I'm feeling more imaginative.

Right now, it has backends to render to Cairo and to blaze-svg. Some minor differences are still being worked out, but for the most part their outputs should be identical. I am planning on some more backends in the future.

Examples

These are all generated from Test.hs.

HSL spiral

HSL spiral

Sierpinski (ish)

Not Sierpinski

TODOs & Wish-list for Contextual

Documentation

  • Explain here how exactly Contextual works and how one might use it!
  • Explain the examples!
  • Explain better how the order in transformation goes.

Core

  • A way to specify canvas size. Right now, non-square images will throw off the aspect ratio - squares will be drawn as rectangles.
  • Support for other primitives: circle, arc
  • Some diagnostic information in Context such as the number of primitives or average depth.
  • Stopping rendering on grammars that don't converge (e.g. limiting recursion depth or number of primitives)
  • Support for stroke thickness (maybe)
  • Support for text may make for some neat possibilities. It will however probably be difficult to get this consistent across multiple output backends.
  • Some optimization for the use of Cairo, e.g. if we are rendering a big scene to a raster image, then doing it in layers of N primitives may make sense to avoid building up huge scene graphs.

Other Backends

  • Web: Some magic with ghcjs (looks like stack supports it) to allow this to run in, and render in, the browser (Canvas as in diagrams-canvas? SVG? WebGL?)
  • GL: OpenGL/WebGL rendering should be possible with the current primitives. Perhaps start at Beautiful Code or Gloss.
  • IHaskell: Integration with IHaskell and Jupyter. Perhaps I can use the mechanism that ihaskell-charts uses, which looks like it ties in with Chart-cairo.
  • PDF: While Cairo can do this, I'd like properly color-managed PDFs, and I don't think its PDF export will properly do this (as with SVG). PostScript is another option - see how diagrams-postscript does it perhaps.
  • Years ago, I wrote, "Translating something written in Context Free into another programming language would in most cases not be difficult at all - you need just a handful of 2D drawing primitives, a couple basic operations for color space and geometry, the ability to recurse (and to stop recursing when it’s pointless)," but I never tested this idea explicitly. Considering I'm already plenty familiar with generating C code from Haskell via my work with Ivory, this is not especially farfetched. Ivory or inline-c might be good starting places - or Fay or Haste perhaps, if I want to target JavaScript. However, this may not have much point without something else to parametrize it over, e.g. a random seed or a time value in order to animate.
  • Rasterific?
  • ASCII art backend!

General Tidiness/Refactoring

  • Make a typeclass for rendering backends?
  • Factor out the use of Context for rendering, since much of this code seems to be repeated. I'm not sure what form it will take, but it should be possible to define a backend with fewer details, and let the rendering function take care of what amount of context needs to be passed around or managed (e.g. Cairo has state and save/restore and Canvas (IIRC) is much the same, whereas with SVG one simply nests transformations, and I'd imagine that OpenGL is more immediate-mode and requires that we compose the transformations).
  • Use of Data.Reify to transform recursive structures, perhaps to backends that can express recursion natively or to a simplified expression
  • Separate modules for separate backends (as many other libraries do)
  • Perhaps rewriting using a simpler form of Free that just uses the parts I need
  • Am I using Comonad implicitly? Should I be using it explicitly?

Possibly-farfetched

  • Support for animation
  • Extend support to 3D (same idea as in Structure Synth from the amazing Syntopia blog).
  • A way of generating diagrams which explain, one level at a time, the operations of a grammar, might be very helpful and might be doable, but probably difficult.

About

Haskell clone of Context Free

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages