Obsah
1. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
2. Vestavěné deklarace textur (předdefinované textury)
3. Úplný zdrojový kód demonstračního příkladu clisktest6
4. Voroného diagramy a jejich využití při tvorbě textur
5. Použití Voroného diagramů v praxi
6. Úplný zdrojový kód demonstračního příkladu clisktest7
7. Repositář s demonstračními příklady
8. Odkazy na předchozí části seriálu
1. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
V předchozích dvou částech seriálu o programovacím jazyku Clojure a o knihovně Clisk jsme si vysvětlili, jakým způsobem se v této knihovně tvoří procedurální textury. Ukázali jsme si použití několika algoritmů používaných pro tvorbu textur, které mají připomínat přírodní (nepravidelné) povrchy, například písek, mramor či dřevo. Taktéž jsme se zmínili o možnosti vykreslování fraktálů, i když použití fraktálů pro tvorbu textur nemusí být ve všech případech praktické. V dnešním článku popis knihovny Clisk dokončíme. Nejdříve se zmíníme o předdefinovaných texturách, které je možné použít prakticky ihned a následně si ukážeme aplikaci Voroného diagramů (Voronoi diagram) pro tvorbu textur, protože se jedná o velmi užitečnou část knihovny Clisk, společně s podporou Perlinova šumu (Perlin Noise) popsaného minule.
Obrázek 1: Textura deklarovaná následovně:
(offset (v* 0.1 (scale 0.03 vsnoise)) (rgb-from-hsl (v+ [0 0 0.5] (scale 0.3 vsnoise))))
Autor: Mike Anderson
2. Vestavěné deklarace textur (předdefinované textury)
Jak jsme se dozvěděli v předchozích textech, nabízí knihovna Clisk svým uživatelům možnost vytvoření prakticky jakkoli komplexní procedurální textury. Pro tvorbu textury lze používat jak vestavěné funkce (pracující s až čtyřsložkovými vektory), tak i již zmíněnou funkci pro tvorbu Perlinova šumu, několik funkcí pro vytváření pravidelných vzorků (mřížka, šachovnice, soustředné kružnice) atd. Kromě můžeme v této knihovně nalézt i několik předdefinovaných textur, jejichž význam je dvojí – lze je (samozřejmě) přímo použít například ve hrách, ovšem důležitější je fakt, že se uživatelé mohou naučit, jakým způsobem lze efektivně používat všechny funkce touto knihovnou nabízené. Mezi předdefinované textury patří:
# | Textura | Interně se používá |
---|---|---|
1 | agate | plasma |
2 | clouds | plasma |
3 | velvet | Perlinův šum |
4 | flecks | Perlinův šum |
5 | wood | výpočet vzdálenosti od středu |
Všech pět výše zmíněných textur si můžeme v základní podobě (bez použití barvové palety atd.) jednoduše otestovat:
(defn predefined-textures-test [] (let [textures [agate clouds velvet flecks wood]] ; postupně projít všemi prvky vektoru "textures", vytvořit ; dvouprvkový vektor [index+patter], vytvořit jméno výstupního ; souboru a následně zavolat funkci write-texture (doseq [ [i texture] (map-indexed vector textures)] (write-pattern texture (str "texture_" i ".png")))))
Výsledky můžete vidět na obrázcích číslo 2 až 5:
Obrázek 2: Předdefinovaná textura agate.
Obrázek 3: Předdefinovaná textura clouds.
Obrázek 4: Předdefinovaná textura velvet.
Obrázek 5: Předdefinovaná textura flecks.
Obrázek 6: Předdefinovaná textura wood.
3. Úplný zdrojový kód demonstračního příkladu clisktest6
V této kapitole bude uveden výpis úplného zdrojového kódu dnešního prvního demonstračního příkladu nazvaného clisktest6, z něhož jsme použili úryvek a ukázky v předešlé kapitole. Tento příklad po svém spuštění vykreslí vybrané předdefinované textury a uloží je do pětice souborů typu PNG. Většinu funkcí, které jsou v tomto příkladu využity, již známe z předchozích demonstračních příkladů:
Obsah souboru project.clj:
(defproject clisktest6 "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"] [net.mikera/clisk "0.10.0"]] :main ^:skip-aot clisktest6.core :target-path "target/%s" :profiles {:uberjar {:aot :all}})
Obrázek 7: Textura deklarovaná následovně:
(seamless 0.5 (v* [1 0.8 0 0] (compose vnoise [spots y z t])))
Autor: Mike Anderson
Obsah souboru core.clj:
(ns clisktest6.core (:gen-class) (:use clisk.live)) (import java.io.File) (import javax.imageio.ImageIO) (defn write-image "Uložení rastrového obrázku typu BufferedImage do souboru." [image file-name] (ImageIO/write image "png" (File. file-name))) (defn write-pattern "Vytvoření rastrového obrázku na základě předaného patternu." [pattern file-name] (write-image (image pattern) file-name)) (defn predefined-textures-test [] (let [textures [agate clouds velvet flecks wood]] ; postupně projít všemi prvky vektoru "textures", vytvořit ; dvouprvkový vektor [index+patter], vytvořit jméno výstupního ; souboru a následně zavolat funkci write-texture (doseq [ [i texture] (map-indexed vector textures)] (write-pattern texture (str "texture_" i ".png"))))) (defn -main [& args] (try (println "Predefined textures test...") (predefined-textures-test) (println "Done") (catch Throwable e (println (.toString e))) (finally ; jistota, že program vždy korektně skončí (System/exit 0))))
Obrázek 8: Textura deklarovaná následovně:
(v- 1.0 (seamless 0.2 (v* 6 (scale 3 vnoise) (v- 0.1 (vmax 0 (vabs (v- plasma 0.5)))))))
Autor: Mike Anderson
4. Voroného diagramy a jejich využití při tvorbě textur
Poměrně zajímavou a poněkud méně známou pomůckou pro tvorbu procedurálních textur jsou takzvané Voroného diagramy (Voronoi Diagrams). Vytvoření Voroného diagramu v ploše pro účely generování procedurální textury je celkem jednoduché – do plochy se náhodně umístí zvolený počet n bodů b0..bn a následně se celá plocha rozdělí na oblasti, přičemž pro všechny body patřící do jedné oblasti platí, že jejich vzdálenost ke konkrétnímu bodu bi je menší než vzdálenost k jakémukoli jinému bodu bj. Příklad takto zkonstruovaného diagramu lze nalézt například na stránce http://upload.wikimedia.org/wikipedia/commons/8/80/Euclidean_Voronoi_Diagram.png. Tento postup lze rozšířit i do 3D a 4D prostoru a navíc je pro účely vytváření textur vhodnější neobarvovat každou plochu konstantní barvou, ale zvolit gradientní přechod na základě skutečné vzdálenosti každého bodu od hranice oblasti.
Pro vytvoření procedurální textury se používá funkce voronoi-map společně s funkcí voronoi-blocks (právě zde se počítá gradientní přechod). Základním parametrem pro tvorbu takové textury je počet počátečních bodů, který určuje počet oblastí a tím pádem i „měřítko“ textury. Minimální počet bodů je 3, maximální počet bodů je 1000:
(defn voronoi-map-test [] (doseq [i (range 2 10)] (let [voronoi-map (voronoi :points (bit-shift-left 1 i)) pattern (voronoi-blocks :voronoi voronoi-map) file-name (format "%02d.png" i)] (write-pattern pattern file-name))))
Obrázek 9: (voronoi :points 4).
Obrázek 10: (voronoi :points 8)
Obrázek 11: (voronoi :points 16)
Obrázek 12: (voronoi :points 32)
Obrázek 13: (voronoi :points 64)
Obrázek 14: (voronoi :points 128)
Obrázek 15: (voronoi :points 256)
Obrázek 16: (voronoi :points 512)
5. Použití Voroného diagramů v praxi
Již z neupravovaných a nemodifikovaných ukázek uvedených ve čtvrté kapitole je patrné, že se Voroného diagramy mohou využít pro tvorbu textur, které mohou připomínat například rozpraskané sklo, hlínu či povrchy některých hornin. Po vizuální stránce je velmi zajímavá kombinace dvou Voroného diagramů – jeden může sloužit pro určení světlosti pixelů, druhý pak pro výběr barvy. K tomuto účelu lze využít funkci wrap popř. funkci nazvanou rgb-from-hsl, která dokáže provést transformaci libovolné barvy (minimálně trojsložkového vektoru) z barvového prostoru HSL do barvového prostoru RGB. Zajímavé je i použití výsledku výpočtu barvy bodu ve Voroného diagramu pro offset (viz též předposlední část tohoto článku). Podívejme se nyní na několik ukázek vytvořených demonstračním příkladem clisktest7, jehož zdrojový kód je vypsán v šesté kapitole:
Obrázek 17: Textura vytvořená pomocí výrazu (voronoi-blocks :voronoi voronoi1).
Obrázek 18: Textura vytvořená pomocí výrazu (voronoi-blocks :voronoi voronoi2).
Obrázek 19: Textura vytvořená pomocí výrazu (voronoi-blocks :voronoi voronoi3).
Obrázek 20: Textura vytvořená pomocí výrazu (v* 2.0 (voronoi-blocks :voronoi voronoi1)).
Obrázek 21: Textura vytvořená pomocí výrazu (v* 2.0 (voronoi-blocks :voronoi voronoi2)).
Obrázek 22: Textura vytvořená pomocí výrazu (v* 2.0 (voronoi-blocks :voronoi voronoi3)).
Obrázek 23: Textura vytvořená pomocí výrazu (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2)) (warp (voronoi-points :voronoi voronoi1) grain)).
Obrázek 24: Textura vytvořená pomocí výrazu (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2)) (warp (voronoi-points :voronoi voronoi2) grain)).
Obrázek 25: Textura vytvořená pomocí výrazu (v* (v* 20.0 (voronoi-blocks :voronoi voronoi3)) (warp (voronoi-points :voronoi voronoi3) grain)).
6. Úplný zdrojový kód demonstračního příkladu clisktest7
Následuje výpis zdrojového kódu dnešního druhého a současně i posledního demonstračního příkladu nazvaného clisktest7:
Obsah souboru project.clj:
(defproject clisktest7 "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"] [net.mikera/clisk "0.10.0"]] :main ^:skip-aot clisktest7.core :target-path "target/%s" :profiles {:uberjar {:aot :all}})
Obrázek 26: Textura deklarovaná následovně:
(seamless 1.0 (offset (v* 4 vplasma) (v+ (offset 10 vnoise) 0.3)))
Autor: Mike Anderson
Obsah souboru core.clj:
(ns clisktest7.core (:gen-class) (:use clisk.live)) (import java.io.File) (import javax.imageio.ImageIO) (defn write-image "Uložení rastrového obrázku typu BufferedImage do souboru." [image file-name] (ImageIO/write image "png" (File. file-name))) (defn write-pattern "Vytvoření rastrového obrázku na základě předaného patternu." [pattern file-name] (write-image (image pattern) file-name)) (defn voronoi-map-test [] (let [voronoi1 (voronoi :points 10) voronoi2 (voronoi :points 100) voronoi3 (voronoi :points 1000)] (write-pattern (voronoi-blocks :voronoi voronoi1) "voronoi1.png") (write-pattern (voronoi-blocks :voronoi voronoi2) "voronoi2.png") (write-pattern (voronoi-blocks :voronoi voronoi3) "voronoi3.png") (write-pattern (v* 2.0 (voronoi-blocks :voronoi voronoi1)) "voronoi4.png") (write-pattern (v* 2.0 (voronoi-blocks :voronoi voronoi2)) "voronoi5.png") (write-pattern (v* 2.0 (voronoi-blocks :voronoi voronoi3)) "voronoi6.png") (write-pattern (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2)) (warp (voronoi-points :voronoi voronoi1) grain)) "voronoi7.png") (write-pattern (v* (v* 20.0 (voronoi-blocks :voronoi voronoi2)) (warp (voronoi-points :voronoi voronoi2) grain)) "voronoi8.png") (write-pattern (v* (v* 20.0 (voronoi-blocks :voronoi voronoi3)) (warp (voronoi-points :voronoi voronoi3) grain)) "voronoi9.png"))) (defn -main [& args] (try (println "Voronoi map test...") (voronoi-map-test) (println "Done") (catch Throwable e (println (.toString e))) (finally ; jistota, že program vždy korektně skončí (System/exit 0))))
Obrázek 27: Textura deklarovaná následovně:
(seamless 0.25 (compose plasma vsnoise))
Autor: Mike Anderson
7. Repositář s demonstračními příklady
Oba dva dnes popsané demonstrační příklady byly, podobně jako v předchozích částech tohoto seriálu, uloženy do GIT repositáře dostupného na adrese https://github.com/tisnik/clojure-examples. V tabulce zobrazené pod tímto odstavcem naleznete na jednotlivé příklady přímé odkazy:
# | Příklad | Github |
---|---|---|
1 | clisktest6 | https://github.com/tisnik/clojure-examples/tree/master/clisktest6 |
2 | clisktest7 | https://github.com/tisnik/clojure-examples/tree/master/clisktest7 |
Obrázek 28: Textura deklarovaná následovně:
(seamless 0.4 (v- vnoise (v* 6 (v- 0.1 (vmax 0 (vabs (v- plasma 0.5)))))))
Autor: Mike Anderson
8. Odkazy na předchozí části seriálu
- Leiningen: nástroj pro správu projektů napsaných v Clojure
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (2)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (3)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-3/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (4)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-4/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (5)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-5/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (6)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-6/ - Programovací jazyk Clojure a databáze (1.část)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/ - Pluginy pro Leiningen
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-2/
Obrázek 29: Textura deklarovaná následovně:
(seamless 1.0 (compose (scale 0.01 (checker 0 1)) plasma))
Autor: Mike Anderson
9. Odkazy na Internetu
- Clisk
https://github.com/mikera/clisk - clojars: net.mikera/clisk
https://clojars.org/net.mikera/clisk - clojure.inspector
http://clojure.github.io/clojure/clojure.inspector-api.html - Clisk: wiki
https://github.com/mikera/clisk/wiki - Dokumentace vygenerovaná pro knihovnu core.matrix
https://cloojure.github.io/doc/core.matrix/index.html - Size and Dimensionality
https://groups.google.com/forum/#!topic/numerical-clojure/zebBCa68eTw/discussion - Towards core.matrix for Clojure?
https://clojurefun.wordpress.com/2013/01/05/towards-core-matrix-for-clojure/ - The Clojure Toolbox
http://www.clojure-toolbox.com/ - Neanderthal
http://neanderthal.uncomplicate.org/ - Hello world project
https://github.com/uncomplicate/neanderthal/blob/master/examples/hello-world/project.clj - vectorz-clj
https://github.com/mikera/vectorz-clj - vectorz – Examples
https://github.com/mikera/vectorz-clj/wiki/Examples - gloss
https://github.com/ztellman/gloss - HTTP client/server for Clojure
http://www.http-kit.org/ - Array Programming
https://en.wikipedia.org/wiki/Array_programming - Discovering Array Languages
http://archive.vector.org.uk/art10008110 - no stinking loops – Kalothi
http://www.nsl.com/ - Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
http://www.vector.org.uk/ - APL Interpreters
http://www.vector.org.uk/?area=interpreters - APL_(programming_language
http://en.wikipedia.org/wiki/APL_(programming_language - APL FAQ
http://www.faqs.org/faqs/apl-faq/ - APL FAQ (nejnovější verze)
http://home.earthlink.net/~swsirlin/apl.faq.html - A+
http://www.aplusdev.org/ - APLX
http://www.microapl.co.uk/ - FreeAPL
http://www.pyr.fi/apl/index.htm - J: a modern, high-level, general-purpose, high-performance programming language
http://www.jsoftware.com/ - K, Kdb: an APL derivative for Solaris, Linux, Windows
http://www.kx.com - openAPL (GPL)
http://sourceforge.net/projects/openapl - Parrot APL (GPL)
http://www.parrotcode.org/ - Learning J (Roger Stokes)
http://www.jsoftware.com/help/learning/contents.htm - Rosetta Code
http://rosettacode.org/wiki/Main_Page - Why APL
http://www.acm.org/sigapl/whyapl.htm - java.jdbc API Reference
https://clojure.github.io/java.jdbc/ - Hiccup
https://github.com/weavejester/hiccup - Clojure Ring na GitHubu
https://github.com/ring-clojure/ring - A brief overview of the Clojure web stack
https://brehaut.net/blog/2011/ring_introduction - Getting Started with Ring
http://www.learningclojure.com/2013/01/getting-started-with-ring.html - Getting Started with Ring and Compojure – Clojure Web Programming
http://www.myclojureadventure.com/2011/03/getting-started-with-ring-and-compojure.html - Unit Testing in Clojure
http://nakkaya.com/2009/11/18/unit-testing-in-clojure/ - Testing in Clojure (Part-1: Unit testing)
http://blog.knoldus.com/2014/03/22/testing-in-clojure-part-1-unit-testing/ - API for clojure.test – Clojure v1.6 (stable)
https://clojure.github.io/clojure/clojure.test-api.html - Leiningen: úvodní stránka
http://leiningen.org/ - Leiningen: Git repository
https://github.com/technomancy/leiningen - leiningen-win-installer
http://leiningen-win-installer.djpowell.net/ - Clojure 1: Úvod
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/ - Clojure 2: Symboly, kolekce atd.
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/ - Clojure 3: Funkcionální programování
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-3-cast-funkcionalni-programovani/ - Clojure 4: Kolekce, sekvence a lazy sekvence
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-4-cast-kolekce-sekvence-a-lazy-sekvence/ - Clojure 5: Sekvence, lazy sekvence a paralelní programy
http://www.root.cz/clanky/clojure-a-bezpecne-aplikace-pro-jvm-sekvence-lazy-sekvence-a-paralelni-programy/ - Clojure 6: Podpora pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/ - Clojure 7: Další funkce pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/ - Clojure 8: Identity, stavy, neměnné hodnoty a reference
http://www.root.cz/clanky/programovaci-jazyk-clojure-8-identity-stavy-nemenne-hodnoty-a-referencni-typy/ - Clojure 9: Validátory, pozorovatelé a kooperace s Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-9-validatory-pozorovatele-a-kooperace-mezi-clojure-a-javou/ - Clojure 10: Kooperace mezi Clojure a Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/ - Clojure 11: Generátorová notace seznamu/list comprehension
http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/ - Clojure 12: Překlad programů z Clojure do bajtkódu JVM I
http://www.root.cz/clanky/programovaci-jazyk-clojure-12-preklad-programu-z-clojure-do-bajtkodu-jvm/ - Clojure 13: Překlad programů z Clojure do bajtkódu JVM II
2) http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/ - Clojure 14: Základy práce se systémem maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/ - Clojure 15: Tvorba uživatelských maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/ - Clojure 16: Složitější uživatelská makra
http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/ - Clojure 17: Využití standardních maker v praxi
http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/ - Clojure 18: Základní techniky optimalizace aplikací
http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/ - Clojure 19: Vývojová prostředí pro Clojure
http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/ - Clojure 20: Vývojová prostředí pro Clojure (Vimu s REPL)
http://www.root.cz/clanky/programovaci-jazyk-clojure-20-vyvojova-prostredi-pro-clojure-integrace-vimu-s-repl/ - Clojure 21: ClojureScript aneb překlad Clojure do JS
http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/