2012-05-15 8 views
6

Eksperymentuję z tworzeniem małej biblioteki/DSL do syntezy obrazu w Clojure. Zasadniczo chodzi o to, aby umożliwić użytkownikom biblioteki komponowanie zestawów funkcji matematycznych w celu proceduralnego tworzenia interesujących obrazów.DSL do syntezy obrazu Clojure

Funkcje muszą działać na podwójnych wartościach i przyjmować formę przekształcania wektora położenia na wartość koloru, np. (X, y, z) -> (r, g, b, a)

Jednakże ja skierowane kilka interesujących decyzji projektowych:

  • Wejścia mogą mieć 1,2,3 lub może nawet 4 wymiary (x, y, z dodatkowym czasem)
  • Dobrze byłoby wykonać operacje matematyczne wektorowe (produkty z kropkami, dodawanie, mnożenie itp.)
  • Wartościowe byłoby komponowanie funkcji z operacjami takimi jak obrót, skala itp.
  • Ze względów wydajnościowych ważne jest stosowanie w całym procesie pierwotnej podwójnej matematyki (np. oubles w szczególności). Zatem funkcja, która musi zwracać czerwony, zielony i niebieski komponent, być może musi stać się trzema osobnymi funkcjami, które zwracają odpowiednio prymitywne wartości koloru czerwonego, zielonego i niebieskiego.

Jakieś pomysły dotyczące tego, w jaki sposób DSL można rozsądnie osiągnąć w Clojure (1.4 beta)?

+0

jakieś wczesne projekty kawałki go na github? – rplevy

+0

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

+0

jesteś świadomy pan (i mojego pancito, który był czysto-iskell kopię). to była biblioteka bazująca na haskellach, która właśnie to zrobiła. możesz prawdopodobnie podnieść niektóre informacje. może dać ci kilka pomysłów. [...] http: // conal.net/Pan/(jeśli masz nadzieję, że uda Ci się stworzyć coś pięknego, nie zniechęcaj się - wciąż jestem zaskoczony, jak koniom udało się wygenerować tak brzydkie obrazy z tak potężnej biblioteki). ps pancito też http://www.acooke.org/pancito-code/ –

Odpowiedz

0

OK, więc w końcu wymyśliłem dobry sposób robienia tego.

Sztuką było reprezentować funkcje jako wektor kodu (w polu „kod jest danych” sensie np

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

ten może być następnie „skompilowany” stworzyć 3 obiekty, które implementują interfejs Java z następujące metody:.

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

i te obiekty funkcyjne można nazwać wartościami prymitywnych, aby doprowadzić czerwony, zielony i niebieski wartości kolorów dla każdego piksela Wyniki są czymś jak:

enter image description here

Wreszcie możliwe jest skomponowanie funkcji za pomocą prostego DSL, np. skalowanie w górę teksturę można zrobić:

(vscale 10 some-function-vector) 

Mam opublikowany cały kod na GitHub dla wszystkich zainteresowanych:

https://github.com/mikera/clisk

+1

Możesz sprawić, że wygeneruje on kod "source" Piet i użyje go generatywnego cross-kompilatora;) –

1

Spojrzenie na niesamowite narzędzia ImageMagick http://www.imagemagick.org może dać ci wyobrażenie o tym, jakiego rodzaju operacje można oczekiwać od takiej biblioteki.

Być może zobaczysz, że nie będziesz musiał zejść do wektorowej matematyki, jeśli zreplikujesz domyślny zestaw narzędzi IM.