I’m experimenting with creating a small library/DSL for image synthesis in Clojure. Basically the idea is to allow users of the library to compose sets of mathematical functions to procedurally create interesting images.
The functions need to operate on double values, and take the form of converting a location vector into a colour value, e.g. (x,y,z) – > (r,g,b,a)
However I’m facing a few interesting design decisions:
- Inputs could have 1,2,3 or maybe even 4 dimensions (x,y,z plus time)
- It would be good to provide vector maths operations (dot products, addition, multiplication etc.)
- It would be valuable to compose functions with operations such as rotate, scale etc.
- For performance reasons, it is important to use primitive double maths throughout (i.e. avoid creating boxed doubles in particular). So a function which needs to return red, green and blue components perhaps needs to become three separate functions which return the primitive red, green and blue values respectively.
Any ideas on how this kind of DSL can reasonably be achieved in Clojure (1.4 beta)?
OK, so I eventually figured out a nice way of doing this.
The trick was to represent functions as a vector of code (in the “code is data” sense, e.g.
This can then be “compiled” to create 3 objects that implement a Java interface with the following method:
And these function objects can be called with primitive values to get the Red, Green and Blue colour values for each pixel. Results are something like:
Finally, it’s possible to compose the functions using a simple DSL, e.g. to scale up a texture you can do:
I’ve published all the code on GitHub for anyone interested:
https://github.com/mikera/clisk