rixx.de (Einträge über tutorial)https://rixx.de/de/categories/c-tutorial.atom2023-08-04T17:30:29ZrixxNikola∞ Tannenbaum!https://rixx.de/de/blog/tannenbaum/2019-12-10T02:16:14+01:002019-12-10T02:16:14+01:00rixx<p></p><div class="header-image bordered post-image">
<img src="https://rixx.de/img/tannenbaum/tannen.png" title="">
<div class="post-image-caption"> <a href="https://ootannenbaum.rixx.de">Source.</a></div>
</div>
<p>Am ersten Advent haben meine Geschwister (13 & 15) und ich Tannenbäume gebaut – aber nicht aus Holz! Wir haben
betrieben, was <em>„Generative Art“</em> heißt. Das Ergebnis lässt sich unter <a href="https://xn--7j8h.rixx.de">🎄.rixx.de</a> bewundern (oder
<a href="https://ootannenbaum.rixx.de">ootannenbaum.rixx.de</a> für die weniger Emoji-Affinen). Per Knopfdruck kann man da
zufällige Weihnachtsbäume generieren.</p>
<p>Das an sich ist schon ziemlich cool, finde ich (möglicherweise bin ich da allerdings voreingenommen). Der Weg dahin ist
aber noch cooler: Zugegebenermaßen habe ich die Tipparbeit getan, aber die beiden Großen haben von Ideen bis
Rechenarbeit alles mitgemacht. Damit das für andere leicht nachzumachen ist, erzähle ich hier ein bisschen, wie das
lief, und wie ihr so etwas angehen könnt.</p>
<h4 id="ressourcen">Ressourcen</h4>
<p>Vorab: Ihr könnt euch genau angucken, wie wir das mit den Weihnachtsbäumen gemacht haben – die Datei liegt
<a href="https://github.com/rixx/ootannenbaum/blob/master/js/tannenbaum.js">hier</a>, und ist ausgiebig und auf deutsch mit
Kommentaren versehen, die erklären, was passiert. (Die Kommentare sind fast schon ihr eigener Blogpost). Wenn ihr noch
überhaupt nie mit so etwas zu tun hattet, kann ich euch vorher sehr <a href="https://media.ccc.de/v/35c3-1-generative-art-with-paper-js">diesen
Vortrag</a> von der großartigen
<a href="https://bleeptrack.de">bleeptrack</a> empfehlen, die einen super Einstieg liefert. Wenn ihr hier nach ganz unten scrollt,
findet ihr auch noch weitere nützliche Links.</p>
<h4 id="vorkenntnisse">Vorkenntnisse</h4>
<p>Wenn ihr euch jetzt fragt, was ihr für Vorkenntnisse haben müsst, um so etwas zu schreiben: gar nicht so viele! Es
reicht Ausdauer <em>oder</em> Vorwissen (ein bisschen einer beliebigen Programmiersprache und etwas Englisch) <em>oder</em> eine
andere Person mit Vorwissen, die euch hilft. Wenn ihr niemanden kennt, der helfen kann: Guckt mal, ob ihr einen lokalen
Hackerspace besuchen könnt, oder an einem Website- oder Programmierworkshop in eurer Nähe teilnehmen könnt.</p>
<p>Zum Vergleich: mein Bruder ist in der 10. Klasse, und hat schon etwas mit Java programmiert und in der Schule mal ein
bisschen HTML gelernt, und kam total gut mit. Meine Schwester ist in der 8. Klasse, hat noch nicht programmiert, keine
Websiten gebaut, und kam auch gut mit, besonders dabei, das Aussehen zu entwerfen und an den einzelnen Parametern zu
drehen, bis ein schönes Ergebnis herauskam.</p>
<p></p><div class="header-image bordered post-image">
<img src="https://rixx.de/img/tannenbaum/hack.jpg" title="">
<div class="post-image-caption"></div>
</div>
<h4 id="ablauf">Ablauf</h4>
<p>Um so einen Generator zu schreiben, überlegt man sich am besten zuerst die einfachste mögliche Form, die Teil der
Zielgestalt ist. Die versucht man dann, im super-praktischen Editor unter
<a href="http://sketch.paperjs.org">sketch.paperjs.org</a> erscheinen zu lassen. Für ein Rechteck könnt ihr zum Beispiel diesen
Code hier kopieren, und dann oben auf den „Run“-Knopf drücken:</p>
<div class="code"><pre class="code literal-block"><span class="nx">rechteck</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Path</span><span class="p">.</span><span class="nx">Rectangle</span><span class="p">(</span><span class="ow">new</span><span class="w"> </span><span class="nx">Point</span><span class="p">(</span><span class="mf">100</span><span class="p">,</span><span class="w"> </span><span class="mf">100</span><span class="p">),</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Size</span><span class="p">(</span><span class="mf">200</span><span class="p">,</span><span class="w"> </span><span class="mf">300</span><span class="p">));</span>
<span class="nx">rechteck</span><span class="p">.</span><span class="nx">fillColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"red"</span><span class="p">;</span>
<span class="nx">rechteck</span><span class="p">.</span><span class="nx">strokeColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">;</span>
<span class="nx">rechteck</span><span class="p">.</span><span class="nx">strokeWidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">5</span><span class="p">;</span>
<span class="nx">rechteck</span><span class="p">.</span><span class="nx">rotate</span><span class="p">(</span><span class="mf">45</span><span class="p">)</span>
</pre></div>
<p>Das erstellt ein Rechteck an der Koordinate (100, 100). Dabei ist (0, 0) oben links! Die erste Zahl ist der x-Wert, der
sagt, wie weit etwas nach rechts geschoben wird, und die zweite Zahl der y-Wert, die sagt, wie weit die Position nach
unten verschoben wird.</p>
<p>Das Rechteck machen wir 200x300 Pixel groß, füllen es rot, und geben ihm einen 5 Pixel dicken schwarzen Rand. Dann
drehen wir es noch um 45°. Mit diesem Anfang lässt sich erst mal super rumspielen! Was sich sonst damit so machen lässt,
findet sich in der <a href="http://paperjs.org/reference/rectangle/">Dokumentation</a>. Nicht wundern, wenn die erst mal verwirrend
aussieht, das ist bei technischer Doku völlig normal. Es hilft, sich erst mal die Teile der Doku anzugucken, die man
schon versteht. Sucht z.B. nach <a href="http://paperjs.org/reference/path/#rotate-angle">"rotate"</a>, um zu lesen, wie
beschrieben ist, dass das, naja, eben ein gezeichnetes Objekt dreht.</p>
<p>Für die Weihnachtsbäume haben wir zuerst ein paar Dreiecke übereinander stapeln wollen. Dafür haben wir uns zusammen
überlegt, was für Koordinaten das Dreieck haben soll: dass nämlich der obere Punkt auf der x-Achse genau mittig zwischen
den anderen beiden liegen soll. Dann haben wir so lange mit dem Editor und ein paar ausgedachten Zahlen gespielt, bis
auch das herausgekommen ist, was wir wollten.</p>
<h4 id="tipps">Tipps</h4>
<p>Der wichtigste Ratschlag überhaupt ist: in <strong>ganz kleinen Schritten</strong> vorgehen! Guckt nach jeder Änderung, was sich
getan hat, und ob es wirklich das ist, was ihr euch vorgestellt habt. Das schöne daran, mit Zeichnungen zu arbeiten,
ist, dass Fehler oft schnell sehr witzig aussehen. Wir hatten nicht nur einmal einen Baum, der zu winzig, zu riesig,
oder sogar kopfüber war!</p>
<p>Kleine Schritte können sein: Ein Element zeichnen. Ein weiteres zeichnen. Es farbig anmalen. Ein drittes dazu zeichnen,
mit einer anderen Farbe. Die Breite eines Elements zufällig zu machen. Die Anzahl eines Elements zufällig zu machen.</p>
<p>Der zweitwichtigste Ratschlag ist: <strong>lernt von anderen</strong>. Die allerallerallermeisten Probleme haben schon andere gehabt
und gelöst. Es tut gut, es erst mal ein bisschen selber zu versuchen (so lernt man oft was), aber wenns dann nicht geht,
kann man super über Google oder bei ähnlichen Projekten nachsehen, wie da ähnliche Probleme gelöst wurden. Wir haben
z.B. einfach direkt von <a href="https://bleeptrack.de">Bleeptrack</a> abgeschrieben, wie am Ende aus den Weihnachtsbäumen
Bilddateien werden. Und umgekehrt könnt ihr jetzt bei uns im ausgiebig kommentierten Code nachlesen, wie was geht.</p>
<h4 id="zufall">Zufall!</h4>
<p>Wenn ihr dann nach einer Weile eine fertige Figur gezeichnet habt, könnt ihr euch an den witzigsten Teil machen: Zufall
einbauen! Das ist nicht ganz einfach, aber dafür macht es eine Menge Spaß, und belohnt euch mit unerwarteten
Ergebnissen!</p>
<p>JavaScript kennt eine Funktion namens <code>Math.random()</code>, die euch eine Zahl mit vielen Kommastellen zwischen 0 und 1
zurückgibt. Wir haben uns dazu als allererstes eine kleine Helferfunktion geschrieben, die eine <strong>Zufallszahl</strong> zwischen
zwei Werten produziert:</p>
<div class="code"><pre class="code literal-block"><span class="kd">function</span><span class="w"> </span><span class="nx">zufallszahl</span><span class="p">(</span><span class="nx">min</span><span class="p">,</span><span class="w"> </span><span class="nx">max</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// Diese Funktion gibt eine zufällige Zahl zwischen min und max zurück.</span>
<span class="w"> </span><span class="c1">// Minimum ist inklusive, maximum ist exklusive.</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nx">max</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">min</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">min</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Darauf lässt es sich dann viel einfacher aufbauen. Zum Beispiel könnt ihr sagen, dass eure Figur zwischen 100 und 300
Pixel breit sein soll, oder sich um 45 bis 90 Grad drehen soll. Das Ganze lässt sich auch wie ein Würfel oder ein
Münzwurf benutzen, zB um zu entscheiden, ob etwas zusätzliches gezeichnet werden soll. Wir zeichnen zb nur etwa zwei von
drei Weihnachtsbäumen einen Stern auf die Spitze.</p>
<h4 id="farbe">Farbe</h4>
<p>Die <strong>Breite und Höhe</strong> einer Figur sind der beste Einstieg an der Zufallsgenerierung. Sie zwingen einen allerdings,
sich ein paar Sachen gründlicher zu überlegen: Wenn ein Teil des Bilds zufällig breit ist, muss sich die Position der
angrenzenden Teile daran anschließen, dh es muss etwas mehr Mathe in den Code. Zusätzlich könnt ihr aber auch die
<strong>Farbe</strong> variieren.</p>
<p>Die Farben in paper.js und auch in vielen anderen Programmen setzen sich aus drei Teilen zusammen: rot, grün und blau
(das <strong>RGB</strong>-System). Oft werden diese Werte zwischen 0 und 255 angegeben. paper.js nimmt stattdessen Werte zwischen 0
und 1 – ich finde es aber schwieriger, mir da vorzustellen, was ein guter Farbwert ist, deshalb haben wir weiter die
großen Zahlen genommen, und sie einfach am Ende durch 256 geteilt. Das sieht bei uns zum Beispiel so aus, um ein schönes
Grün zu finden:</p>
<div class="code"><pre class="code literal-block"><span class="kd">var</span><span class="w"> </span><span class="nx">rot</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">zufallszahl</span><span class="p">(</span><span class="mf">0</span><span class="p">,</span><span class="w"> </span><span class="mf">100</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">256</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">gruen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">zufallszahl</span><span class="p">(</span><span class="mf">115</span><span class="p">,</span><span class="w"> </span><span class="mf">255</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">256</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">blau</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">zufallszahl</span><span class="p">(</span><span class="mf">40</span><span class="p">,</span><span class="w"> </span><span class="mf">130</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">256</span>
<span class="nx">dreieck</span><span class="p">.</span><span class="nx">fillColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Color</span><span class="p">(</span><span class="nx">rot</span><span class="p">,</span><span class="w"> </span><span class="nx">gruen</span><span class="p">,</span><span class="w"> </span><span class="nx">blau</span><span class="p">)</span>
</pre></div>
<p>Wo bekommt man die Grenzwerte her, dass wir z.B. einen rot-Wert zwischen 0 und 100 wollen? Wenn ihr in der Suchmaschine
eurer Wahl nach <a href="https://duckduckgo.com/?q=colorpicker&atb=v102-1&ia=answer">Colorpicker</a> sucht, solltet ihr einen
Auswahldialog für Farben finden. Da könnt ihr mal suchen, welche Farben für euch in Frage kommen, und während ihr den
Farbpunkt durch die Gegend zieht, die RGB-Werte im Blick behalten. Das gibt euch eine gute erste Schätzung (und macht
sich übrigens viel leichter zu zweit, wenn eine zieht und eine guckt). Danach könnt ihr die Werte noch nachbessern, wenn
euch auffällt, dass z.B. zu bläuliche Farben dabei generiert werden.</p>
<h4 id="weiterfuhrende-links">Weiterführende Links</h4>
<p>Und das ist, wie ihr anfangen könnt, selber Zeichnungen zu generieren! Ich hoffe, das hilft für den Anfang, und ihr habt
viel Spaß damit.</p>
<p>Hier findet ihr <strong>Quellen</strong> und <strong>weiterführende Informationen</strong>:</p>
<ul>
<li><a href="https://ootannenbaum.rixx.de">ootannenbaum.rixx.de</a>, der Weihnachtsbaumgenerator.</li>
<li><a href="https://github.com/rixx/ootannenbaum">Der Quelltext</a> mit ausführlichen Kommentaren</li>
<li>Von bleeptrack<ul>
<li><a href="https://media.ccc.de/v/35c3-1-generative-art-with-paper-js">Ein toller Einführungsvortrag in paper.js</a></li>
<li><a href="https://bleeptrack.de">Website</a></li>
<li><a href="https://beetles.bleeptrack.de/">Käfergenerator</a></li>
<li><a href="https://overflower.bleeptrack.de/">Mandalagenerator</a></li>
<li><a href="https://cccamp19.bleeptrack.de/">Raketengenerator</a></li>
</ul>
</li>
<li><a href="http://sketch.paperjs.org/">Editor von paper.js</a>: Dort kann man live mit Code malen</li>
<li><a href="http://paperjs.org/">Dokumentation von paper.js</a></li>
<li><a href="https://www.reddit.com/r/generative/top/">Schöne Beispiele und Ideen</a></li>
</ul>