2012-05-15 17 views
6

Sto sperimentando con la creazione di una piccola libreria/DSL per la sintesi di immagini in Clojure. Fondamentalmente l'idea è di consentire agli utenti della libreria di comporre insiemi di funzioni matematiche per creare proceduralmente immagini interessanti.DSL per sintesi immagine Clojure

Le funzioni devono operare su valori doppi e assumere la forma di convertire un vettore di posizione in un valore di colore, ad es. (X, y, z) -> (r, g, b, a)

Comunque sto affrontando un paio di decisioni di progettazione interessanti:

  • Ingressi potrebbe avere 1,2,3 o forse anche 4 dimensioni (x, y, z più tempo)
  • Sarebbe opportuno fornire operazioni matematiche vettoriali (dot products, addizione, moltiplicazione, ecc.)
  • Sarebbe utile comporre funzioni con operazioni quali rotazione, scala ecc.
  • Per motivi di prestazioni, è importante utilizzare la doppia matematica primitiva in tutto (evitare cioè di creare riquadri oubles in particolare). Quindi una funzione che deve restituire componenti rossi, verdi e blu, forse deve diventare tre funzioni separate che restituiscono rispettivamente i valori primitivi rosso, verde e blu.

Qualche idea su come questo tipo di DSL può essere ragionevolmente raggiunto in Clojure (1.4 beta)?

+0

Got qualsiasi progetto di pezzi iniziali di fino su GitHub? – rplevy

+0

https://github.com/mikera/clisk – mikera

+0

sei a conoscenza di pan (e del mio pancito, che era una copia di puro haskell). quella era una libreria basata su haskell che faceva proprio questo. probabilmente puoi trovare su Google alcune informazioni. potrebbe darti qualche idea. [...] http: // conal.net/Pan/(se speri di generare qualcosa di bello, non scoraggiarti - sono ancora stupito di come Conal sia riuscita a generare immagini così brutte da una libreria così potente). ps pancito troppo http://www.acooke.org/pancito-code/ –

risposta

0

OK, quindi alla fine ho capito un bel modo per farlo.

Il trucco era rappresentare funziona come un vettore di codice (nel "codice è dati" senso, ad esempio

[(Math/sin (* 10 x)) 
(Math/cos (* 12 y)) 
(Math/cos (+ (* 5 x) (* 8 y)))] 

Questo può quindi essere "compilato" per creare 3 oggetti che implementano un'interfaccia Java con il seguente metodo:.

public double calc(double x, double y, double z, double t) { 
    ..... 
} 

e questi oggetti funzione può essere richiamata con valori primitivi per ottenere i valori di colore blu per ogni pixel rosso, verde e risultati sono qualcosa come:

enter image description here

Infine, è possibile comporre le funzioni utilizzando un semplice DSL, ad es. di scalare una texture che si può fare:

(vscale 10 some-function-vector) 

ho pubblicato tutto il codice su GitHub per chiunque sia interessato:

https://github.com/mikera/clisk

+1

Si potrebbe fare generare codice "sorgente" Piet e usarlo come cross-compilatore generativo;) –

1

Uno sguardo ai fantastici strumenti ImageMagick http://www.imagemagick.org può darti un'idea del tipo di operazioni che ci si aspetterebbe da una tale libreria.

Forse vedrete che non sarà necessario scorrere verso il basso per la matematica vettoriale se si replica il set di strumenti IM predefinito.