Compare commits
No commits in common. "master" and "cw1" have entirely different histories.
BIN
7_Centaurea_cyanus.jpg
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
Anabaenaflosaquae_EPA.jpg
Normal file
After Width: | Height: | Size: 54 KiB |
@ -1,3 +0,0 @@
|
|||||||
# MWS_2021
|
|
||||||
|
|
||||||
W tym repozytorium znajdują się zadania do przedmiotu Modelowanie wirtualnych światów
|
|
BIN
Screenshot 2021-03-13 at 14.29.10.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
Screenshot 2021-03-14 at 07.32.36.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
Screenshot 2021-03-14 at 07.32.56.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
Screenshot 2021-03-14 at 07.33.17.png
Normal file
After Width: | Height: | Size: 193 KiB |
BIN
Turtle-animation-20210312091611500.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
Turtle-animation-20210312091653497.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
Turtle-animation-20210313140337212.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
Turtle-animation-20210313143359379.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
Turtle-animation.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
Unityscreen.png
Normal file
After Width: | Height: | Size: 3.2 MiB |
BIN
Von_Koch_curve.gif
Normal file
After Width: | Height: | Size: 13 KiB |
1419
Wirtualne światy ĆW1.html
Normal file
342
Wirtualne światy ĆW1.md
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
# Ćwiczenia 14.03
|
||||||
|
|
||||||
|
## Hello World w Unity
|
||||||
|
|
||||||
|
(Pliki [https://git.wmi.amu.edu.pl/andkok/Unity_artifitial_world/src/branch/cw1/materiałyHelloWorld](https://git.wmi.amu.edu.pl/andkok/Unity_artifitial_world/src/branch/cw1/materiałyHelloWorld) )
|
||||||
|
|
||||||
|
1. ### Utwórz nowy projekt
|
||||||
|
|
||||||
|
- [ ] Otwórz Unity Hub
|
||||||
|
- [ ] Wybierz NEW
|
||||||
|
- [ ] 3D, wpisz nazwę i wybierz lokalizacje na twoim komputerze. Zatwierdź klikając CREATE
|
||||||
|
|
||||||
|
2. ### Import materiałów, tworzenie terenu i prostych krztałtów
|
||||||
|
|
||||||
|
<img src="Unityscreen.png" style="zoom:50%;" />
|
||||||
|
|
||||||
|
Po środku ekranu jest podgląd sceny (karta Scene). Żeby się w nim przemieszczać klikamy Q i wtedy możemy przesuwać obraz myszką (kliknięcie na prawy przycisk myszy do obracania widoku). Klawisz W zmienia w tryb przesuwania obiektów, a klawisz E jest do obracania obiektów i R zmiany rozmiarów.
|
||||||
|
|
||||||
|
W dolnej części ekranu, w karcie Project przechowujemy wszystkie modele, tekstury, skrypty i inne potrzebne elementy
|
||||||
|
|
||||||
|
- [ ] W folderze Assets kliknij prawym przyciskiem myszy i z menu wybierz Create -> Folder. Nazwij folder tekstury
|
||||||
|
|
||||||
|
- [ ] Otwórz ten folder i przeciągnij do niego wcześniej pobrane tekstury
|
||||||
|
|
||||||
|
Po lewej stronie jest karta Hierarchy. W niej znajdują się wszystkie obiekty, które są w tworzonej scenie. Tam się dodaje nowe elementy sceny i ustawia zależności pomiędzy elementami
|
||||||
|
|
||||||
|
#### Teren
|
||||||
|
|
||||||
|
- [ ] Kliknij prawym przyciskiem myszy w polu Hierarchy i wybierz 3D Object -> Terrain
|
||||||
|
|
||||||
|
Po prawej stronie mamy karte inspector w której są ustawienia zaznaczonego obiektu
|
||||||
|
|
||||||
|
<img src="ph00009.png" style="zoom:33%;" />
|
||||||
|
|
||||||
|
- [ ] Dodaj teksturę terenu
|
||||||
|
|
||||||
|
- [ ] W Inspektorze przy zakładce Terrain wybierz drugą opcje (ikonka pędzelka)
|
||||||
|
- [ ] Wybierz z menu Paint Texture
|
||||||
|
- [ ] Kliknij Edit Terrain Layers -> Create Layer
|
||||||
|
- [ ] Dodaj trzy tekstury
|
||||||
|
- [ ] Urozmaić teren zaznaczając tekstury i malując przy pomocy wybranych poniżej pędzli
|
||||||
|
|
||||||
|
- [ ] Zmień wysokości terenu
|
||||||
|
|
||||||
|
- [ ] W Inspektorze przy zakładce Terrain wybierz drugą opcje (ikonka pędzelka)
|
||||||
|
- [ ] Wybierz z menu Raise or Lower Terrain
|
||||||
|
- [ ] Podnosi się teren "malując" po obiekcie terenu, żeby teren obniżyć należy trzymać wciśnięty shift
|
||||||
|
|
||||||
|
#### Proste kształty
|
||||||
|
|
||||||
|
- [ ] W karcie Hierarchy kliknij prawym przyciskiem myszy i wybierz 3D Object -> Sphere
|
||||||
|
|
||||||
|
- [ ] żeby nadać kuli koloru utwórz materiał
|
||||||
|
|
||||||
|
- [ ] <img src="ph00008.png" style="zoom:33%;" />
|
||||||
|
- [ ] Dodaj teksture SphereNormals do tekstur i Inspektorze wybierz texture type: Normal Map, zaznacz create from grayscale, wrap mode: mirror
|
||||||
|
- [ ] W folderze Assets utwórz folder Materiały i kliknij prawym przyciskiem myszy i wybierz Create -> Material
|
||||||
|
- [ ] <img src="ph00007.png" style="zoom:33%;" />
|
||||||
|
- [ ] Wybierz kolor Albedo i dodaj teksture do "Normal Map"
|
||||||
|
- [ ] Przeciągnij materiał na kulę
|
||||||
|
|
||||||
|
- [ ] żeby na kulę działała grawitacja i kolizja dodajemy do niej Rigid Body (Add Component -> Rigidbody), i w Constrains - Freeze rotation zaznacz wszystkie (żeby nam się kula nie stoczyła)
|
||||||
|
|
||||||
|
- [ ] <img src="ph00006.png" style="zoom:33%;" /> <img src="ph00005.png" style="zoom:33%;" />
|
||||||
|
|
||||||
|
3. ### Dodawanie skryptu C#
|
||||||
|
|
||||||
|
W Unity za większość akcji i różnych interakcji odpowiadają skrypty C#
|
||||||
|
|
||||||
|
- [ ] Utwórz folder skrypty i w nim Create -> C# Script, nazwij go Player.
|
||||||
|
|
||||||
|
- [ ] Otwórz ten skrypt i Przed funkcją Start dodaj zmienne:
|
||||||
|
|
||||||
|
```c#
|
||||||
|
public float speed = 0.1f;
|
||||||
|
public float rotationSpeed = 0.1f;
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] wewnątrz funkcji Update wklej:
|
||||||
|
|
||||||
|
```c#
|
||||||
|
float move = Input.GetAxis("Vertical") * speed; // Pobierz dane od użytkownika (klawisze strzałek lub joystick) i przeskaluj wcześniej podaną wartością (przód tył)
|
||||||
|
float rotate = Input.GetAxis("Horizontal") * rotationSpeed; // Pobierz dane od użytkownika (klawisze strzałek lub joystick) i przeskaluj wcześniej podaną wartością (obrót)
|
||||||
|
Vector3 moveVector = new Vector3(PODAJ_X,PODAJ_Y,PODAJ_Z); // Wektor przesuwający objekt DO EDYCJI
|
||||||
|
gameObject.GetComponent<Transform>().Translate(moveVector, Space.Self); // Funkcja przesuwająca objekt
|
||||||
|
gameObject.GetComponent<Transform>().Rotate(PODAJ_X,PODAJ_Y,PODAJ_Z, Space.Self); // Funkcja obracająca objekt DO EDYCJI
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] Zamień wartości wektora ruchu i funkcji obrotu
|
||||||
|
|
||||||
|
- [ ] Przeciągnij skrypt na object Player lub w Inspektorze obiektu Player wybierz Add Component i dodaj Player
|
||||||
|
|
||||||
|
4. ### Ustawianie oświetlenia (globalne)
|
||||||
|
|
||||||
|
- [ ] Ustawienia oświetlenia są w Window -> Rendering -> Ligthning, można je sobie przypiąć w dowolnym miejscu (ja przesuwam je koło inspektora)
|
||||||
|
- [ ] <img src="ph00004.png" style="zoom:33%;" />
|
||||||
|
- [ ] Dodajemy nowe ustawienia (New Ligthning Settings)
|
||||||
|
- [ ] Można zmienić Ligthmapper na Progressive GPU
|
||||||
|
- [ ] Po dostosowaniu ustawień klikamy Generate Lightning (to może chwilę potrwać, nawet do kilku minut)
|
||||||
|
|
||||||
|
5. ### Tworzenie wielu elementów skryptem z ustawianiem ich za pomocą macierzy (Clock)
|
||||||
|
|
||||||
|
<img src="ph00001.png" style="zoom:25%;" />
|
||||||
|
|
||||||
|
- [ ] Utwórz objekt tarczy zegara (tekstura <img src="clock.png" style="width:25px;" /> , zamień przy tworzeniu materiału Rendering mode na Transparent)
|
||||||
|
|
||||||
|
- [ ] Utwórz obiekt, który posłuży jako szablon wskazówek zegara
|
||||||
|
|
||||||
|
- [ ] Dodaj kod ustawiający zegar do obiektu tarczy zegara
|
||||||
|
|
||||||
|
```c#
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
public class Clock : MonoBehaviour
|
||||||
|
{
|
||||||
|
public GameObject clockHand; // szablon wyglądu wskazówki zegara
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
DateTime centuryBegin = new DateTime(2001, 1, 1);
|
||||||
|
DateTime currentDate = DateTime.Now;
|
||||||
|
long elapsedTicks = currentDate.Ticks - centuryBegin.Ticks;
|
||||||
|
TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
|
||||||
|
|
||||||
|
float stopWatchTime = Time.unscaledTime; // Czas w sekundach od startu aplikacji (mały zegar)
|
||||||
|
float nowTime = (float)(((int)(elapsedSpan.TotalSeconds)) % 86400); // Czas w sekundach od początku doby (0:00) (duży zegar)
|
||||||
|
// Stop Watch Time:
|
||||||
|
|
||||||
|
float swHour = 0.0f;
|
||||||
|
float swMinute = 0.0f;
|
||||||
|
float swSecond = 0.0f;
|
||||||
|
// Global Time:
|
||||||
|
float hour = 0.0f;
|
||||||
|
float minute = 0.0f;
|
||||||
|
float second = 0.0f;
|
||||||
|
// Ustaw pozycje, rozmiar i obrót wskazówek zegara z wykorzystaniem przekształceń macierzowych:
|
||||||
|
// (Matrix4x4.Translate, Matrix4x4.Scale, Matrix4x4.Rotate) dwa pierwsze przyjmują Vector3, a obroty przyjmują Quaternion.Euler( X, Y, Z) (już bez new, bo to funkcja)
|
||||||
|
|
||||||
|
var transformationHsw = Matrix4x4.Translate(new Vector3(0, 0, 0));
|
||||||
|
var transformationMsw = Matrix4x4.Translate(new Vector3(0, 0, 0));
|
||||||
|
var transformationSsw = Matrix4x4.Translate(new Vector3(0, 0, 0));
|
||||||
|
|
||||||
|
var transformationH = Matrix4x4.Translate(new Vector3(0, 0, 0));
|
||||||
|
var transformationM = Matrix4x4.Translate(new Vector3(0, 0, 0));
|
||||||
|
var transformationS = Matrix4x4.Translate(new Vector3(0, 0, 0));
|
||||||
|
|
||||||
|
// Create game objects instances
|
||||||
|
|
||||||
|
Graphics.DrawMeshInstanced(clockHand.GetComponent<MeshFilter>().mesh, 0, clockHand.GetComponent<MeshRenderer>().material, new Matrix4x4[6]{transformationHsw, transformationMsw, transformationSsw, transformationH, transformationM, transformationS});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] Zaznacz w inspektorze przy Clock Hand wcześniej przygotowany objekt
|
||||||
|
|
||||||
|
- [ ] Dodaj odpowiednie przekształcenia, tak aby duży zegar pokazywał czas i mały zegar pokazywał czas od uruchomienia aplikacji
|
||||||
|
|
||||||
|
# L-System
|
||||||
|
|
||||||
|
W tej części zajęć skupimy się na tworzeniu L-Systemów i wykorzystaniu ich do reprezentacji zjawisk przyrodniczych.
|
||||||
|
|
||||||
|
> **Przypomnienie**
|
||||||
|
> **L-System** to system przepisywania i gramatyka formalna. Składa się z: symboli, które tworzą ciągi znaków; reguł produkcyjnych, które opisują na co należy przepisać dany znak; aksjomatu, czyli początkowego ciągu znaków; i mechanizmu, który tłumaczy ciąg znaków na reprezentacje geometryczną
|
||||||
|
|
||||||
|
Bazą dla tych zajęć jest książka Algorithmic Beauty of Plants dostępna za darmo pod [linkiem](http://algorithmicbotany.org/papers/abop/abop.lowquality.pdf) lub [w wyższej jakości](http://algorithmicbotany.org/papers/abop/abop.pdf)
|
||||||
|
|
||||||
|
## Składnia L-Systemów
|
||||||
|
|
||||||
|
Projekt zawiera bibliotekę, która interpretuje L-Systemy. Ich definicję pobiera z oddzielnego pliku. Ich składnie opisuję definicja L-Systemu opisującego rozwój bakterii Anabaena znajduje się w projekcie pod ścieżką `Assets\LSystem\Anabaena.txt` i wygląda następująco:
|
||||||
|
|
||||||
|
```
|
||||||
|
#axiom
|
||||||
|
L
|
||||||
|
#rules
|
||||||
|
L->lR
|
||||||
|
R->Lr
|
||||||
|
l->L
|
||||||
|
r->R
|
||||||
|
#end rules
|
||||||
|
```
|
||||||
|
|
||||||
|
Plik należy zacząć od linii `#axiom`, następnie w następnej linii zamieścić ciąg początkowy. Później pomiędzy liniami `#rules` i `#end rules` umieścić instrukcje przepisywania według zasady:
|
||||||
|
```<znak przepisywany>-><wynik przepisania> ```
|
||||||
|
każdy znak przed strzałką i po strzałce (z wyjątkiem reguł o których później) jest traktowany jako następny symbol. W przypadku kilku reguł, które dotyczą tego samego symbolu wykona się ta, która jest wyżej w pliku. Między reguły można dodawać komentarze, znakiem komentującym jest `#`. Jeżeli znak nie posiada żadnej reguły, która by go opisywała, to nie jest on zmieniany.
|
||||||
|
|
||||||
|
Odpal scenę **LSystemFromFile**, zaznacz **LSystemController** w panelu po prawej. Po lewej w polu **L System Path** wpisz `Assets\LSystem\Anabaena.txt` kliknij **Load File**, by załadować LSystem. Następnie Evaluate, by wykonać przepisanie. W scenie wyświetlą się obiekty reprezentujące symbole a w konsoli wyświetli się wynik przepisania.
|
||||||
|
|
||||||
|
Składnia wszystkich rozszerzeń jest zaprezentowana w pliku `SampleLSystem.txt` w tej chwili niektóre reguły mogą byc niezrozumiałe, ale może się on przydać później jako wzorzec.
|
||||||
|
|
||||||
|
## Turtle Graphics
|
||||||
|
|
||||||
|
Turtle Graphics jest metodą tworzenia grafiki komputerowej, wykorzystuje kursor (tytułowego żółwia) wykonujący instrukcje w przestrzeni lokalnej.
|
||||||
|
|
||||||
|
![https://en.wikipedia.org/wiki/Turtle_graphics](Turtle-animation-20210313143359379.gif)
|
||||||
|
|
||||||
|
L-Systemy można interpretować za pomocą Turtle Graphics, poprzez przypisanie każdemu symbolowi instrukcji jaką ma wykonać żółw. Następnie żółw będzie wykonywał kolejne instrukcje czytając napis od lewej do prawej.
|
||||||
|
|
||||||
|
Na początek zaczniemy od prostej reprezentacji, gdzie `+` będzie oznaczał w kierunku zgodnym z ruchem wskazówek zegara o wskazany kąt, natomiast `-` w przeciwnym. Kąt zwyczajowo oznacza się grecką literą $\delta$. Każdy inny symbol będzie oznaczał idź prosto o 1.
|
||||||
|
|
||||||
|
Odpal Scenę LSystem2D, załaduj plik `Sierpinski.txt`, ustaw kąt na 60 stopni i wykonaj kilka kroków.
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
napisz Lsystem, który będzie rysował gwiazdkę kocha
|
||||||
|
|
||||||
|
1. #### Krzywa kocha:
|
||||||
|
|
||||||
|
<img src="../../../../Downloads/Wirtualne Światy treść zadań/Kochsim.gif" />
|
||||||
|
|
||||||
|
<img src="../../../../Downloads/Wirtualne Światy treść zadań/RPReplay_Final1615641331.gif" style="zoom:50%;" />
|
||||||
|
|
||||||
|
Opis:
|
||||||
|
|
||||||
|
1. Podziel linię na 3 równę części
|
||||||
|
2. Przy środkowej części narysuj równoboczny trójkąt zwrócony na zewnątrz
|
||||||
|
3. Usuń środkową część pierwotnej lini
|
||||||
|
|
||||||
|
Musimy z jednej lini zrobić 4 nowe, z czego pierwsza i ostatnia idą w tym samym kierunku, a dwie środkowe idą pod innym kątem (podpowiedź: dając dwa razy + lub - możesz zwiększyć kąt)
|
||||||
|
|
||||||
|
2. #### W pierwszym kroku L-Systemu utwórz trójkąt
|
||||||
|
|
||||||
|
![](Von_Koch_curve.gif)
|
||||||
|
|
||||||
|
## Bracketed L-systems
|
||||||
|
|
||||||
|
W podstawowej wersji L-Systemy są pojedyńczym ciągiem znaków, by uzyskać możliwość tworzenia rozgałęzień wprowadzamy dwa specjalne znaki `[` oraz `]` pierwszy mówi, żeby zapamiętać obecny stan, drugi oznacza by wrócić do stanu zapamiętanym przy ostatnim znaku `[`. Przykładowo ciąg symboli `F[+FFF][-F]FF` dla $\delta=90$ będzie reprezentowany następująco
|
||||||
|
![obraz](im_bracketed-5642437.jpg)
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
Stwórz systemy a i e:
|
||||||
|
|
||||||
|
<img src="../../../../Downloads/Wirtualne Światy treść zadań/Screenshot 2021-03-13 at 14.29.06.png" alt="Screenshot 2021-03-13 at 14.29.06" /> ![Screenshot 2021-03-13 at 14.29.10](Screenshot 2021-03-13 at 14.29.10.png)
|
||||||
|
|
||||||
|
## Pisanie własnej interpretacji LSystemów
|
||||||
|
|
||||||
|
Wróćmy do sceny LSystemFromFile W tej scenie zamiast kresek pojawiają się figury reprezentujące komórki (czerwona lewa, zielona prawa, niska młoda, wysoka dorosła). Otwórz skrypt AnabeanaTurtle.cs, który odpowiada za rysowanie. Zawiera on klasę `AnabeanaTurtle` dziedziczącą po `TurtleLSystem`. `TurtleLSystem` jest klasą abstrakcyjną, wymaga zdefiniowania funkcji `initLiteralInterpretation`, w której należy opisać jak interpretować symbole.
|
||||||
|
|
||||||
|
```CS
|
||||||
|
protected override void initLiteralInterpretation() {
|
||||||
|
turtleInterpretation = new Dictionary<string, Func<float[], Tuple<GameObject, Matrix4x4>>>();
|
||||||
|
//turtleInterpretation
|
||||||
|
var transformation = Matrix4x4.Translate(new Vector3(0.0f, 0.1f, 0)) * Matrix4x4.Scale(new Vector3 (0.05f, 0.1f, 0.05f));
|
||||||
|
|
||||||
|
turtleInterpretation.Add("+", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, 0, -angle))));
|
||||||
|
turtleInterpretation.Add("-", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, 0, angle))));
|
||||||
|
|
||||||
|
//Wildcard how to represent any other symbol
|
||||||
|
turtleInterpretation.Add("*.*", (float[] args) => new Tuple<GameObject, Matrix4x4>(obj, transformation));
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Żeby tego dokonać należy uzupełnić słownik `turtleInterpretation`, którego kluczami są opisywane symbole jako stringi. Natomiast wartościami są funkcje, które przyjmują jako argument tablicę parametrów danego symbolu (o tym później) a zwracają Krotkę, której pierwszym elementem jest rysowany obiekt, natomiast drugim transformacja, jaką wykona żółw. Powyższym przykładzie obiekty są czytane z modeli a transformacja zawsze jest taka sama, czyli translacja o wektor (0.1,0,0) i skalowanie o wektor (0.1,0.1,0.1). (Skalowania nie są pamiętane przez żółwia)
|
||||||
|
|
||||||
|
Te funkcje są wykorzystywane przez żółwia do interpretacji ciągu symboli. Przykładowo `LRr` zostanie zinterpretowany następująco:
|
||||||
|
|
||||||
|
* żółw przesuwa się o 0.1 w osi X umieszcza bigL w punkcie (0.1,0,0)
|
||||||
|
* żółw przesuwa się o 0.1 w osi X umieszcza bigR w punkcie (0.2,0,0) (ponieważ (0.1,0,0)+(0.1,0,0)=(0.2,0,0) )
|
||||||
|
* żółw przesuwa się o 0.1 w osi X umieszcza bigL w punkcie (0.3,0,0)
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
Jak wyszukasz w internecie obrazki Anabaeny, zobaczysz, że są one często powykręcane, dodaj do macierz przekształceń obroty w osi Y o losowy kąt pomiędzy -20 a 20 stopni.
|
||||||
|
|
||||||
|
## Parametryczne L-Systemy
|
||||||
|
|
||||||
|
Parametryczne L-Systemy operują na symbolach parametrycznych znakach, czyli takich, które posiadają 0 lub więcej parametrów rzeczywistych. Pozwala to przechowywać różne wewnętrzne stany obiektów. Przykładowo dla modelu Anabeany powyżej rozróżniamy tylko 2 stany, młody i dorosły. Dzięki parametrycznym L-Systemom możemy opisać wiek w sposób bardziej ciągły. Przykładowo poniższy L-System komórki która rośnie i jak osiągnie odpowiedni wiek rozdziela się na dwie młode komórki
|
||||||
|
|
||||||
|
```
|
||||||
|
#axiom
|
||||||
|
B(1)
|
||||||
|
#rules
|
||||||
|
B(a) : a<2 -> B(a+0.1)
|
||||||
|
B(a) : a>=2 -> B(1)B(1)
|
||||||
|
#end rules
|
||||||
|
```
|
||||||
|
|
||||||
|
Parametry zapisuje się wewnątrz nawiasów po przecinku. W aksjomacie muszą one mieć wartości liczbowe. Po lewej stronie trzeba nadać parametrom nazwy (mogą mieć one więcej niż jeden znak). Symbole są identyfikowane po nazwie i liczbie znaków. Po dwukropku można podać warunki logiczne jakie musi spełnić symbol. można w tym umieszczać operacje matematyczne, dozwolone jest mnożenie, dzielenie, dodawanie i odejmowanie. podobnie w parametrach po prawej stronie
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
Napisz dla parametrycznej wersji Anabeny taką interpretację, żeby komórki rosły wraz z wiekiem.
|
||||||
|
|
||||||
|
## Stochastyczne L-Systemy
|
||||||
|
|
||||||
|
Niektóre procesy biologiczne są zbyt skomplikowane albo niedostatecznie zbadane, żeby można je było je zasymulować lub zwyczajnie nie mamy potrzeby symulować mechanizmów tak dokładnie. Zamiast tego możemy skorzystać z losowości, która przybliży zachowanie natury.
|
||||||
|
|
||||||
|
Przykładowo możemy losowo decydować czy w roślinie wyrośnie boczna gałąź czy nie. Co realizuje poniższy L-System (znajduje się on także w pliku `stochastic.txt`)
|
||||||
|
|
||||||
|
```
|
||||||
|
#axiom
|
||||||
|
B
|
||||||
|
#rules
|
||||||
|
B -> #stochastic
|
||||||
|
p=3 FB
|
||||||
|
p=1 [+FB]FB
|
||||||
|
p=1 [-FB]FB
|
||||||
|
p=1 F
|
||||||
|
#stochastic end
|
||||||
|
#rules end
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
W powyższym przypadku mamy symbol B, który symbolizuje merystem (część rośliny zdolną do rozwoju); F oznacza rozwiniętą gałąź. B może rozwinąć łodygę, wytworzyć gałąź po prawej, wytworzyć gałąź po lewej lub zaprzestać rozwój.
|
||||||
|
|
||||||
|
Odpal scenę `LSystem2D` załaduj `stochastic.txt` i odpal kilka razy od początku (żeby zresetować, kliknij *Load File*).
|
||||||
|
|
||||||
|
Reguły stochastyczne należy zacząć od słowa `#stochastic`. Następnie po linijce wypisać wyniki, poprzedzając je frazą `p=W`, gdzie `W` to waga danego wyniku. Wagi mogą być dowolną dodatnią liczbą rzeczywistą. Interpreter na podstawie wag przydzieli prawdopodobieństwo kolejnym wynikom. Przykładowo w powyższym L-Systemie reguły zostaną wykonane następująco:
|
||||||
|
|
||||||
|
* FB z prawdopodobieństwem $\frac{3}{6}$
|
||||||
|
* [+FB]FB z prawdopodobieństwem $\frac{1}{6}$
|
||||||
|
* [+FB]FB z prawdopodobieństwem $\frac{1}{6}$
|
||||||
|
* F z prawdopodobieństwem $\frac{1}{6}$
|
||||||
|
|
||||||
|
<img src="Screenshot 2021-03-14 at 07.32.36.png" alt="Screenshot 2021-03-14 at 07.32.36" style="zoom:33%;" /><img src="Screenshot 2021-03-14 at 07.32.56.png" alt="Screenshot 2021-03-14 at 07.32.56" style="zoom:33%;" /> <img src="Screenshot 2021-03-14 at 07.33.17.png" alt="Screenshot 2021-03-14 at 07.33.17" style="zoom:33%;" />
|
||||||
|
|
||||||
|
### zadanie
|
||||||
|
|
||||||
|
Obecnie zdarza się tak, że L-System wchodzi w ostatnią regułę na samym początku i nic nie wyrasta. Innym razem wyrasta bardzo dużo odgałęzień i całość wymyka się spod kontroli a na pewno przestaje przypominać roślinę. Pomyśl jak można zaradzić tym dwóm problemom, zmodyfikuj L-System tak, by ich uniknąć. Możesz dodać nowe symbole lub/i wykorzystać symbole parametryczne.
|
||||||
|
|
||||||
|
## Zadanie domowe
|
||||||
|
|
||||||
|
Scena `LSystem3D` jest kopią sceny `LSystem2D`, korzysta ona ze skryptu `Turtle3D` zamiast `Turtle2D` (chociaż są one na razie identyczne). Dodaj do `Turtle3D` obsługę obrotów w trzech wymiarach za pomocą znaków:
|
||||||
|
|
||||||
|
* `&` obrót do góry (pitch), czyli obrót względem osi X o kąt $\delta$
|
||||||
|
* `^` obrót do góry (pitch), czyli obrót względem osi X o kąt $-\delta$
|
||||||
|
* `\` obrót do obrót w prawo (roll), czyli obrót względem osi Y o kąt $-\delta$
|
||||||
|
* `/` obrót do obrót w lewo (roll), czyli obrót względem osi Y o kąt $\delta$
|
||||||
|
|
||||||
|
Poza tym dla symboli `L` i `F` dodaj interpretacje kolejno jako liść i kwiat. W folderze Models są gotowe modele, ale możesz ściągnąć własne.
|
||||||
|
|
||||||
|
Wykorzystaj dotychczasową wiedzę i powyższą interpretację, by stworzyć L-System generujący roślinę polną jak poniższy chaber.
|
||||||
|
|
||||||
|
![rysunek chabra z wikipedii](7_Centaurea_cyanus.jpg)
|
BIN
Wirtualne światy ĆW1.pdf
Normal file
BIN
cw1 p2/7_Centaurea_cyanus.jpg
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
cw1 p2/Anabaenaflosaquae_EPA.jpg
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
cw1 p2/Screenshot 2021-03-13 at 14.29.10.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
cw1 p2/Screenshot 2021-03-14 at 07.32.36.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
cw1 p2/Screenshot 2021-03-14 at 07.32.56.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
cw1 p2/Screenshot 2021-03-14 at 07.33.17.png
Normal file
After Width: | Height: | Size: 193 KiB |
BIN
cw1 p2/Turtle-animation-20210312091611500.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
cw1 p2/Turtle-animation-20210312091653497.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
cw1 p2/Turtle-animation-20210313140337212.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
cw1 p2/Turtle-animation-20210313143359379.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
cw1 p2/Turtle-animation.gif
Normal file
After Width: | Height: | Size: 727 KiB |
BIN
cw1 p2/Unityscreen.png
Normal file
After Width: | Height: | Size: 3.2 MiB |
BIN
cw1 p2/Von_Koch_curve.gif
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
cw1 p2/bracketed zad 1.JPG
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
cw1 p2/clock.png
Normal file
After Width: | Height: | Size: 21 KiB |
208
cw1 p2/cw1.html
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="generator" content="pandoc" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||||
|
<title>cw1</title>
|
||||||
|
<style>
|
||||||
|
code{white-space: pre-wrap;}
|
||||||
|
span.smallcaps{font-variant: small-caps;}
|
||||||
|
span.underline{text-decoration: underline;}
|
||||||
|
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||||
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||||
|
ul.task-list{list-style: none;}
|
||||||
|
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||||
|
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||||
|
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||||
|
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||||
|
div.sourceCode { margin: 1em 0; }
|
||||||
|
pre.sourceCode { margin: 0; }
|
||||||
|
@media screen {
|
||||||
|
div.sourceCode { overflow: auto; }
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
pre > code.sourceCode { white-space: pre-wrap; }
|
||||||
|
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||||
|
}
|
||||||
|
pre.numberSource code
|
||||||
|
{ counter-reset: source-line 0; }
|
||||||
|
pre.numberSource code > span
|
||||||
|
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||||
|
pre.numberSource code > span > a:first-child::before
|
||||||
|
{ content: counter(source-line);
|
||||||
|
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||||
|
border: none; display: inline-block;
|
||||||
|
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||||
|
-khtml-user-select: none; -moz-user-select: none;
|
||||||
|
-ms-user-select: none; user-select: none;
|
||||||
|
padding: 0 4px; width: 4em;
|
||||||
|
color: #aaaaaa;
|
||||||
|
}
|
||||||
|
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||||||
|
div.sourceCode
|
||||||
|
{ }
|
||||||
|
@media screen {
|
||||||
|
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||||
|
}
|
||||||
|
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
||||||
|
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
||||||
|
code span.at { color: #7d9029; } /* Attribute */
|
||||||
|
code span.bn { color: #40a070; } /* BaseN */
|
||||||
|
code span.bu { } /* BuiltIn */
|
||||||
|
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
||||||
|
code span.ch { color: #4070a0; } /* Char */
|
||||||
|
code span.cn { color: #880000; } /* Constant */
|
||||||
|
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
||||||
|
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
||||||
|
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
||||||
|
code span.dt { color: #902000; } /* DataType */
|
||||||
|
code span.dv { color: #40a070; } /* DecVal */
|
||||||
|
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
||||||
|
code span.ex { } /* Extension */
|
||||||
|
code span.fl { color: #40a070; } /* Float */
|
||||||
|
code span.fu { color: #06287e; } /* Function */
|
||||||
|
code span.im { } /* Import */
|
||||||
|
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
||||||
|
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
||||||
|
code span.op { color: #666666; } /* Operator */
|
||||||
|
code span.ot { color: #007020; } /* Other */
|
||||||
|
code span.pp { color: #bc7a00; } /* Preprocessor */
|
||||||
|
code span.sc { color: #4070a0; } /* SpecialChar */
|
||||||
|
code span.ss { color: #bb6688; } /* SpecialString */
|
||||||
|
code span.st { color: #4070a0; } /* String */
|
||||||
|
code span.va { color: #19177c; } /* Variable */
|
||||||
|
code span.vs { color: #4070a0; } /* VerbatimString */
|
||||||
|
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 id="l-system">L-System</h1>
|
||||||
|
<p>W tej części zajęć skupimy się na tworzeniu L-Systemów i wykorzystaniu ich do reprezentacji zjawisk przyrodniczych.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Przypomnienie</strong> <strong>L-System</strong> to system przepisywania i gramatyka formalna. Składa się z: symboli, które tworzą ciągi znaków; reguł produkcyjnych, które opisują na co należy przepisać dany znak; aksjomatu, czyli początkowego ciągu znaków; i mechanizmu, który tłumaczy ciąg znaków na reprezentacje geometryczną</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>Bazą dla tych zajęć jest książka Algorithmic Beauty of Plants dostępna za darmo pod <a href="http://algorithmicbotany.org/papers/abop/abop.lowquality.pdf">linkiem</a> lub <a href="http://algorithmicbotany.org/papers/abop/abop.pdf">w wyższej jakości</a></p>
|
||||||
|
<h2 id="składnia-l-systemów">Składnia L-Systemów</h2>
|
||||||
|
<p>Projekt zawiera bibliotekę, która interpretuje L-Systemy. Ich definicję pobiera z oddzielnego pliku. Ich składnie opisuję definicja L-Systemu opisującego rozwój bakterii Anabaena znajduje się w projekcie pod ścieżką <code>Assets\LSystem\Anabaena.txt</code> i wygląda następująco:</p>
|
||||||
|
<pre><code>#axiom
|
||||||
|
L
|
||||||
|
#rules
|
||||||
|
L->lR
|
||||||
|
R->Lr
|
||||||
|
l->L
|
||||||
|
r->R
|
||||||
|
#end rules</code></pre>
|
||||||
|
<p>Plik należy zacząć od linii <code>#axiom</code>, następnie w następnej linii zamieścić ciąg początkowy. Później pomiędzy liniami <code>#rules</code> i <code>#end rules</code> umieścić instrukcje przepisywania według zasady: <code><znak przepisywany>-><wynik przepisania></code> każdy znak przed strzałką i po strzałce (z wyjątkiem reguł o których później) jest traktowany jako następny symbol. W przypadku kilku reguł, które dotyczą tego samego symbolu wykona się ta, która jest wyżej w pliku. Między reguły można dodawać komentarze, znakiem komentującym jest <code>#</code>. Jeżeli znak nie posiada żadnej reguły, która by go opisywała, to nie jest on zmieniany.</p>
|
||||||
|
<p>Odpal scenę <strong>LSystemFromFile</strong>, zaznacz <strong>LSystemController</strong> w panelu po prawej. Po lewej w polu <strong>L System Path</strong> wpisz <code>Assets\LSystem\Anabaena.txt</code> kliknij <strong>Load File</strong>, by załadować LSystem. Następnie Evaluate, by wykonać przepisanie. W scenie wyświetlą się obiekty reprezentujące symbole a w konsoli wyświetli się wynik przepisania.</p>
|
||||||
|
<p>Składnia wszystkich rozszerzeń jest zaprezentowana w pliku <code>SampleLSystem.txt</code> w tej chwili niektóre reguły mogą byc niezrozumiałe, ale może się on przydać później jako wzorzec.</p>
|
||||||
|
<h2 id="turtle-graphics">Turtle Graphics</h2>
|
||||||
|
<p>Turtle Graphics jest metodą tworzenia grafiki komputerowej, wykorzystuje kursor (tytułowego żółwia) wykonujący instrukcje w przestrzeni lokalnej.</p>
|
||||||
|
<figure>
|
||||||
|
<img src="Turtle-animation-20210313143359379.gif" alt="https://en.wikipedia.org/wiki/Turtle_graphics" /><figcaption aria-hidden="true">https://en.wikipedia.org/wiki/Turtle_graphics</figcaption>
|
||||||
|
</figure>
|
||||||
|
<p>L-Systemy można interpretować za pomocą Turtle Graphics, poprzez przypisanie każdemu symbolowi instrukcji jaką ma wykonać żółw. Następnie żółw będzie wykonywał kolejne instrukcje czytając napis od lewej do prawej.</p>
|
||||||
|
<p>Na początek zaczniemy od prostej reprezentacji, gdzie <code>+</code> będzie oznaczał w kierunku zgodnym z ruchem wskazówek zegara o wskazany kąt, natomiast <code>-</code> w przeciwnym. Kąt zwyczajowo oznacza się grecką literą <span class="math inline">\(\delta\)</span>. Każdy inny symbol będzie oznaczał idź prosto o 1.</p>
|
||||||
|
<p>Odpal Scenę LSystem2D, załaduj plik <code>Sierpinski.txt</code>, ustaw kąt na 60 stopni i wykonaj kilka kroków.</p>
|
||||||
|
<h3 id="zadanie">Zadanie</h3>
|
||||||
|
<p>napisz Lsystem, który będzie rysował gwiazdkę kocha</p>
|
||||||
|
<ol type="1">
|
||||||
|
<li><h4 id="krzywa-kocha">Krzywa kocha:</h4></li>
|
||||||
|
</ol>
|
||||||
|
<p><img src="../../../../Downloads/Wirtualne Światy treść zadań/Kochsim.gif" /></p>
|
||||||
|
<p><img src="../../../../Downloads/Wirtualne Światy treść zadań/RPReplay_Final1615641331.gif" style="zoom:50%;" /></p>
|
||||||
|
<p>Opis:</p>
|
||||||
|
<ol type="1">
|
||||||
|
<li>Podziel linię na 3 równę części</li>
|
||||||
|
<li>Przy środkowej części narysuj równoboczny trójkąt zwrócony na zewnątrz</li>
|
||||||
|
<li>Usuń środkową część pierwotnej lini</li>
|
||||||
|
</ol>
|
||||||
|
<p>Musimy z jednej lini zrobić 4 nowe, z czego pierwsza i ostatnia idą w tym samym kierunku, a dwie środkowe idą pod innym kątem (podpowiedź: dając dwa razy + lub - możesz zwiększyć kąt)</p>
|
||||||
|
<ol start="2" type="1">
|
||||||
|
<li><h4 id="w-pierwszym-kroku-l-systemu-utwórz-trójkąt">W pierwszym kroku L-Systemu utwórz trójkąt</h4>
|
||||||
|
<img src="Von_Koch_curve.gif" /></li>
|
||||||
|
</ol>
|
||||||
|
<h2 id="bracketed-l-systems">Bracketed L-systems</h2>
|
||||||
|
<p>W podstawowej wersji L-Systemy są pojedyńczym ciągiem znaków, by uzyskać możliwość tworzenia rozgałęzień wprowadzamy dwa specjalne znaki <code>[</code> oraz <code>]</code> pierwszy mówi, żeby zapamiętać obecny stan, drugi oznacza by wrócić do stanu zapamiętanym przy ostatnim znaku <code>[</code>. Przykładowo ciąg symboli <code>F[+FFF][-F]FF</code> dla <span class="math inline">\(\delta=90\)</span> będzie reprezentowany następująco <img src="im_bracketed-5642437.jpg" alt="obraz" /></p>
|
||||||
|
<h3 id="zadanie-1">Zadanie</h3>
|
||||||
|
<p>Wyświetl poniższe L-Systemy. Zmodyfikuj definicję drugiego, by dodstać asymetryczną roślinę.</p>
|
||||||
|
<p><img src="bracketed zad 1.JPG" alt="Screenshot 2021-03-13 at 14.29.06" /> <img src="Screenshot%202021-03-13%20at%2014.29.10.png" alt="Screenshot 2021-03-13 at 14.29.10" /></p>
|
||||||
|
<h2 id="pisanie-własnej-interpretacji-lsystemów">Pisanie własnej interpretacji LSystemów</h2>
|
||||||
|
<p>Wróćmy do sceny LSystemFromFile W tej scenie zamiast kresek pojawiają się figury reprezentujące komórki (czerwona lewa, zielona prawa, niska młoda, wysoka dorosła). Otwórz skrypt AnabeanaTurtle.cs, który odpowiada za rysowanie. Zawiera on klasę <code>AnabeanaTurtle</code> dziedziczącą po <code>TurtleLSystem</code>. <code>TurtleLSystem</code> jest klasą abstrakcyjną, wymaga zdefiniowania funkcji <code>initLiteralInterpretation</code>, w której należy opisać jak interpretować symbole.</p>
|
||||||
|
<div class="sourceCode" id="cb2"><pre class="sourceCode cs"><code class="sourceCode cs"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a> <span class="kw">protected</span> <span class="kw">override</span> <span class="dt">void</span> <span class="fu">initLiteralInterpretation</span>() {</span>
|
||||||
|
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> turtleInterpretation = <span class="kw">new</span> Dictionary<<span class="dt">string</span>, Func<<span class="dt">float</span>[], Tuple<GameObject, Matrix4x4>>>();</span>
|
||||||
|
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="co">//turtleInterpretation</span></span>
|
||||||
|
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">var</span> transformation = Matrix4x4.<span class="fu">Translate</span>(<span class="kw">new</span> <span class="fu">Vector3</span>(<span class="fl">0.0f</span>, <span class="fl">0.1f</span>, <span class="dv">0</span>)) * Matrix4x4.<span class="fu">Scale</span>(<span class="kw">new</span> <span class="fu">Vector3</span> (<span class="fl">0.05f</span>, <span class="fl">0.1f</span>, <span class="fl">0.05f</span>));</span>
|
||||||
|
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
|
||||||
|
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> turtleInterpretation.<span class="fu">Add</span>(<span class="st">"+"</span>, (<span class="dt">float</span>[] args) => <span class="kw">new</span> Tuple<GameObject, Matrix4x4>(<span class="kw">null</span>, Matrix4x4.<span class="fu">Rotate</span>(Quaternion.<span class="fu">Euler</span>(<span class="dv">0</span>, <span class="dv">0</span>, -angle))));</span>
|
||||||
|
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> turtleInterpretation.<span class="fu">Add</span>(<span class="st">"-"</span>, (<span class="dt">float</span>[] args) => <span class="kw">new</span> Tuple<GameObject, Matrix4x4>(<span class="kw">null</span>, Matrix4x4.<span class="fu">Rotate</span>(Quaternion.<span class="fu">Euler</span>(<span class="dv">0</span>, <span class="dv">0</span>, angle))));</span>
|
||||||
|
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
|
||||||
|
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> <span class="co">//Wildcard how to represent any other symbol</span></span>
|
||||||
|
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a> turtleInterpretation.<span class="fu">Add</span>(<span class="st">"*.*"</span>, (<span class="dt">float</span>[] args) => <span class="kw">new</span> Tuple<GameObject, Matrix4x4>(obj, transformation));</span>
|
||||||
|
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a> }</span></code></pre></div>
|
||||||
|
<p>Żeby tego dokonać należy uzupełnić słownik <code>turtleInterpretation</code>, którego kluczami są opisywane symbole jako stringi. Natomiast wartościami są funkcje, które przyjmują jako argument tablicę parametrów danego symbolu (o tym później) a zwracają Krotkę, której pierwszym elementem jest rysowany obiekt, natomiast drugim transformacja, jaką wykona żółw. Powyższym przykładzie obiekty są czytane z modeli a transformacja zawsze jest taka sama, czyli translacja o wektor (0.1,0,0) i skalowanie o wektor (0.1,0.1,0.1). (Skalowania nie są pamiętane przez żółwia)</p>
|
||||||
|
<p>Te funkcje są wykorzystywane przez żółwia do interpretacji ciągu symboli. Przykładowo <code>LRr</code> zostanie zinterpretowany następująco:</p>
|
||||||
|
<ul>
|
||||||
|
<li>żółw przesuwa się o 0.1 w osi X umieszcza bigL w punkcie (0.1,0,0)</li>
|
||||||
|
<li>żółw przesuwa się o 0.1 w osi X umieszcza bigR w punkcie (0.2,0,0) (ponieważ (0.1,0,0)+(0.1,0,0)=(0.2,0,0) )</li>
|
||||||
|
<li>żółw przesuwa się o 0.1 w osi X umieszcza bigL w punkcie (0.3,0,0)</li>
|
||||||
|
</ul>
|
||||||
|
<h3 id="zadanie-2">Zadanie</h3>
|
||||||
|
<p>Jak wyszukasz w internecie obrazki Anabaeny, zobaczysz, że są one często powykręcane, dodaj do macierz przekształceń obroty w osi Y o losowy kąt pomiędzy -20 a 20 stopni.</p>
|
||||||
|
<h2 id="parametryczne-l-systemy">Parametryczne L-Systemy</h2>
|
||||||
|
<p>Parametryczne L-Systemy operują na symbolach parametrycznych znakach, czyli takich, które posiadają 0 lub więcej parametrów rzeczywistych. Pozwala to przechowywać różne wewnętrzne stany obiektów. Przykładowo dla modelu Anabeany powyżej rozróżniamy tylko 2 stany, młody i dorosły. Dzięki parametrycznym L-Systemom możemy opisać wiek w sposób bardziej ciągły. Przykładowo poniższy L-System komórki która rośnie i jak osiągnie odpowiedni wiek rozdziela się na dwie młode komórki</p>
|
||||||
|
<pre><code>#axiom
|
||||||
|
B(1)
|
||||||
|
#rules
|
||||||
|
B(a) : a<2 -> B(a+0.1)
|
||||||
|
B(a) : a>=2 -> B(1)B(1)
|
||||||
|
#end rules</code></pre>
|
||||||
|
<p>Parametry zapisuje się wewnątrz nawiasów po przecinku. W aksjomacie muszą one mieć wartości liczbowe. Po lewej stronie trzeba nadać parametrom nazwy (mogą mieć one więcej niż jeden znak). Symbole są identyfikowane po nazwie i liczbie znaków. Po dwukropku można podać warunki logiczne jakie musi spełnić symbol. można w tym umieszczać operacje matematyczne, dozwolone jest mnożenie, dzielenie, dodawanie i odejmowanie. podobnie w parametrach po prawej stronie</p>
|
||||||
|
<h3 id="zadanie-3">Zadanie</h3>
|
||||||
|
<p>Napisz dla parametrycznej wersji Anabeny taką interpretację, żeby komórki rosły wraz z wiekiem.</p>
|
||||||
|
<h2 id="stochastyczne-l-systemy">Stochastyczne L-Systemy</h2>
|
||||||
|
<p>Niektóre procesy biologiczne są zbyt skomplikowane albo niedostatecznie zbadane, żeby można je było je zasymulować lub zwyczajnie nie mamy potrzeby symulować mechanizmów tak dokładnie. Zamiast tego możemy skorzystać z losowości, która przybliży zachowanie natury.</p>
|
||||||
|
<p>Przykładowo możemy losowo decydować czy w roślinie wyrośnie boczna gałąź czy nie. Co realizuje poniższy L-System (znajduje się on także w pliku <code>stochastic.txt</code>)</p>
|
||||||
|
<pre><code>#axiom
|
||||||
|
B
|
||||||
|
#rules
|
||||||
|
B -> #stochastic
|
||||||
|
p=3 FB
|
||||||
|
p=1 [+FB]FB
|
||||||
|
p=1 [-FB]FB
|
||||||
|
p=1 F
|
||||||
|
#stochastic end
|
||||||
|
#rules end
|
||||||
|
</code></pre>
|
||||||
|
<p>W powyższym przypadku mamy symbol B, który symbolizuje merystem (część rośliny zdolną do rozwoju); F oznacza rozwiniętą gałąź. B może rozwinąć łodygę, wytworzyć gałąź po prawej, wytworzyć gałąź po lewej lub zaprzestać rozwój.</p>
|
||||||
|
<p>Odpal scenę <code>LSystem2D</code> załaduj <code>stochastic.txt</code> i odpal kilka razy od początku (żeby zresetować, kliknij <em>Load File</em>).</p>
|
||||||
|
<p>Reguły stochastyczne należy zacząć od słowa <code>#stochastic</code>. Następnie po linijce wypisać wyniki, poprzedzając je frazą <code>p=W</code>, gdzie <code>W</code> to waga danego wyniku. Wagi mogą być dowolną dodatnią liczbą rzeczywistą. Interpreter na podstawie wag przydzieli prawdopodobieństwo kolejnym wynikom. Przykładowo w powyższym L-Systemie reguły zostaną wykonane następująco:</p>
|
||||||
|
<ul>
|
||||||
|
<li>FB z prawdopodobieństwem <span class="math inline">\(\frac{3}{6}\)</span></li>
|
||||||
|
<li>[+FB]FB z prawdopodobieństwem <span class="math inline">\(\frac{1}{6}\)</span></li>
|
||||||
|
<li>[+FB]FB z prawdopodobieństwem <span class="math inline">\(\frac{1}{6}\)</span></li>
|
||||||
|
<li>F z prawdopodobieństwem <span class="math inline">\(\frac{1}{6}\)</span></li>
|
||||||
|
</ul>
|
||||||
|
<p><img src="Screenshot 2021-03-14 at 07.32.36.png" alt="Screenshot 2021-03-14 at 07.32.36" style="zoom:33%;" /><img src="Screenshot 2021-03-14 at 07.32.56.png" alt="Screenshot 2021-03-14 at 07.32.56" style="zoom:33%;" /> <img src="Screenshot 2021-03-14 at 07.33.17.png" alt="Screenshot 2021-03-14 at 07.33.17" style="zoom:33%;" /></p>
|
||||||
|
<h3 id="zadanie-4">zadanie</h3>
|
||||||
|
<p>Obecnie zdarza się tak, że L-System wchodzi w ostatnią regułę na samym początku i nic nie wyrasta. Innym razem wyrasta bardzo dużo odgałęzień i całość wymyka się spod kontroli a na pewno przestaje przypominać roślinę. Pomyśl jak można zaradzić tym dwóm problemom, zmodyfikuj L-System tak, by ich uniknąć. Możesz dodać nowe symbole lub/i wykorzystać symbole parametryczne.</p>
|
||||||
|
<h2 id="zadanie-domowe">Zadanie domowe</h2>
|
||||||
|
<p>Scena <code>LSystem3D</code> jest kopią sceny <code>LSystem2D</code>, korzysta ona ze skryptu <code>Turtle3D</code> zamiast <code>Turtle2D</code> (chociaż są one na razie identyczne). Dodaj do <code>Turtle3D</code> obsługę obrotów w trzech wymiarach za pomocą znaków:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>&</code> obrót do góry (pitch), czyli obrót względem osi X o kąt <span class="math inline">\(\delta\)</span></li>
|
||||||
|
<li><code>^</code> obrót do góry (pitch), czyli obrót względem osi X o kąt <span class="math inline">\(-\delta\)</span></li>
|
||||||
|
<li><code>\</code> obrót do obrót w prawo (roll), czyli obrót względem osi Y o kąt <span class="math inline">\(-\delta\)</span></li>
|
||||||
|
<li><code>/</code> obrót do obrót w lewo (roll), czyli obrót względem osi Y o kąt <span class="math inline">\(\delta\)</span></li>
|
||||||
|
</ul>
|
||||||
|
<p>Poza tym dla symboli <code>L</code> i <code>F</code> dodaj interpretacje kolejno jako liść i kwiat. W folderze Models są gotowe modele, ale możesz ściągnąć własne.</p>
|
||||||
|
<p>Wykorzystaj dotychczasową wiedzę i powyższą interpretację, by stworzyć L-System generujący roślinę polną jak poniższy chaber.</p>
|
||||||
|
<figure>
|
||||||
|
<img src="7_Centaurea_cyanus.jpg" alt="rysunek chabra z wikipedii" /><figcaption aria-hidden="true">rysunek chabra z wikipedii</figcaption>
|
||||||
|
</figure>
|
||||||
|
</body>
|
||||||
|
</html>
|
178
cw1 p2/cw1.md
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
# L-System
|
||||||
|
|
||||||
|
W tej części zajęć skupimy się na tworzeniu L-Systemów i wykorzystaniu ich do reprezentacji zjawisk przyrodniczych.
|
||||||
|
|
||||||
|
> **Przypomnienie**
|
||||||
|
> **L-System** to system przepisywania i gramatyka formalna. Składa się z: symboli, które tworzą ciągi znaków; reguł produkcyjnych, które opisują na co należy przepisać dany znak; aksjomatu, czyli początkowego ciągu znaków; i mechanizmu, który tłumaczy ciąg znaków na reprezentacje geometryczną
|
||||||
|
|
||||||
|
Bazą dla tych zajęć jest książka Algorithmic Beauty of Plants dostępna za darmo pod [linkiem](http://algorithmicbotany.org/papers/abop/abop.lowquality.pdf) lub [w wyższej jakości](http://algorithmicbotany.org/papers/abop/abop.pdf)
|
||||||
|
|
||||||
|
## Składnia L-Systemów
|
||||||
|
|
||||||
|
Projekt zawiera bibliotekę, która interpretuje L-Systemy. Ich definicję pobiera z oddzielnego pliku. Ich składnie opisuję definicja L-Systemu opisującego rozwój bakterii Anabaena znajduje się w projekcie pod ścieżką `Assets\LSystem\Anabaena.txt` i wygląda następująco:
|
||||||
|
|
||||||
|
```
|
||||||
|
#axiom
|
||||||
|
L
|
||||||
|
#rules
|
||||||
|
L->lR
|
||||||
|
R->Lr
|
||||||
|
l->L
|
||||||
|
r->R
|
||||||
|
#end rules
|
||||||
|
```
|
||||||
|
|
||||||
|
Plik należy zacząć od linii `#axiom`, następnie w następnej linii zamieścić ciąg początkowy. Później pomiędzy liniami `#rules` i `#end rules` umieścić instrukcje przepisywania według zasady:
|
||||||
|
```<znak przepisywany>-><wynik przepisania> ```
|
||||||
|
każdy znak przed strzałką i po strzałce (z wyjątkiem reguł o których później) jest traktowany jako następny symbol. W przypadku kilku reguł, które dotyczą tego samego symbolu wykona się ta, która jest wyżej w pliku. Między reguły można dodawać komentarze, znakiem komentującym jest `#`. Jeżeli znak nie posiada żadnej reguły, która by go opisywała, to nie jest on zmieniany.
|
||||||
|
|
||||||
|
Odpal scenę **LSystemFromFile**, zaznacz **LSystemController** w panelu po prawej. Po lewej w polu **L System Path** wpisz `Assets\LSystem\Anabaena.txt` kliknij **Load File**, by załadować LSystem. Następnie Evaluate, by wykonać przepisanie. W scenie wyświetlą się obiekty reprezentujące symbole a w konsoli wyświetli się wynik przepisania.
|
||||||
|
|
||||||
|
Składnia wszystkich rozszerzeń jest zaprezentowana w pliku `SampleLSystem.txt` w tej chwili niektóre reguły mogą byc niezrozumiałe, ale może się on przydać później jako wzorzec.
|
||||||
|
|
||||||
|
## Turtle Graphics
|
||||||
|
|
||||||
|
Turtle Graphics jest metodą tworzenia grafiki komputerowej, wykorzystuje kursor (tytułowego żółwia) wykonujący instrukcje w przestrzeni lokalnej.
|
||||||
|
|
||||||
|
![https://en.wikipedia.org/wiki/Turtle_graphics](Turtle-animation-20210313143359379.gif)
|
||||||
|
|
||||||
|
L-Systemy można interpretować za pomocą Turtle Graphics, poprzez przypisanie każdemu symbolowi instrukcji jaką ma wykonać żółw. Następnie żółw będzie wykonywał kolejne instrukcje czytając napis od lewej do prawej.
|
||||||
|
|
||||||
|
Na początek zaczniemy od prostej reprezentacji, gdzie `+` będzie oznaczał w kierunku zgodnym z ruchem wskazówek zegara o wskazany kąt, natomiast `-` w przeciwnym. Kąt zwyczajowo oznacza się grecką literą $\delta$. Każdy inny symbol będzie oznaczał idź prosto o 1.
|
||||||
|
|
||||||
|
Odpal Scenę LSystem2D, załaduj plik `Sierpinski.txt`, ustaw kąt na 60 stopni i wykonaj kilka kroków.
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
napisz Lsystem, który będzie rysował gwiazdkę kocha
|
||||||
|
|
||||||
|
1. #### Krzywa kocha:
|
||||||
|
|
||||||
|
<img src="../../../../Downloads/Wirtualne Światy treść zadań/Kochsim.gif" />
|
||||||
|
|
||||||
|
<img src="../../../../Downloads/Wirtualne Światy treść zadań/RPReplay_Final1615641331.gif" style="zoom:50%;" />
|
||||||
|
|
||||||
|
Opis:
|
||||||
|
|
||||||
|
1. Podziel linię na 3 równę części
|
||||||
|
2. Przy środkowej części narysuj równoboczny trójkąt zwrócony na zewnątrz
|
||||||
|
3. Usuń środkową część pierwotnej lini
|
||||||
|
|
||||||
|
Musimy z jednej lini zrobić 4 nowe, z czego pierwsza i ostatnia idą w tym samym kierunku, a dwie środkowe idą pod innym kątem (podpowiedź: dając dwa razy + lub - możesz zwiększyć kąt)
|
||||||
|
|
||||||
|
2. #### W pierwszym kroku L-Systemu utwórz trójkąt
|
||||||
|
|
||||||
|
![](Von_Koch_curve.gif)
|
||||||
|
|
||||||
|
## Bracketed L-systems
|
||||||
|
|
||||||
|
W podstawowej wersji L-Systemy są pojedyńczym ciągiem znaków, by uzyskać możliwość tworzenia rozgałęzień wprowadzamy dwa specjalne znaki `[` oraz `]` pierwszy mówi, żeby zapamiętać obecny stan, drugi oznacza by wrócić do stanu zapamiętanym przy ostatnim znaku `[`. Przykładowo ciąg symboli `F[+FFF][-F]FF` dla $\delta=90$ będzie reprezentowany następująco
|
||||||
|
![obraz](im_bracketed-5642437.jpg)
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
Wyświetl poniższe L-Systemy. Zmodyfikuj definicję drugiego, by dodstać asymetryczną roślinę
|
||||||
|
|
||||||
|
<img src="bracketed zad 1.JPG" alt="Screenshot 2021-03-13 at 14.29.06" /> ![Screenshot 2021-03-13 at 14.29.10](Screenshot 2021-03-13 at 14.29.10.png)
|
||||||
|
|
||||||
|
## Pisanie własnej interpretacji LSystemów
|
||||||
|
|
||||||
|
Wróćmy do sceny LSystemFromFile W tej scenie zamiast kresek pojawiają się figury reprezentujące komórki (czerwona lewa, zielona prawa, niska młoda, wysoka dorosła). Otwórz skrypt AnabeanaTurtle.cs, który odpowiada za rysowanie. Zawiera on klasę `AnabeanaTurtle` dziedziczącą po `TurtleLSystem`. `TurtleLSystem` jest klasą abstrakcyjną, wymaga zdefiniowania funkcji `initLiteralInterpretation`, w której należy opisać jak interpretować symbole.
|
||||||
|
|
||||||
|
```CS
|
||||||
|
protected override void initLiteralInterpretation() {
|
||||||
|
turtleInterpretation = new Dictionary<string, Func<float[], Tuple<GameObject, Matrix4x4>>>();
|
||||||
|
//turtleInterpretation
|
||||||
|
var transformation = Matrix4x4.Translate(new Vector3(0.0f, 0.1f, 0)) * Matrix4x4.Scale(new Vector3 (0.05f, 0.1f, 0.05f));
|
||||||
|
|
||||||
|
turtleInterpretation.Add("+", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, 0, -angle))));
|
||||||
|
turtleInterpretation.Add("-", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, 0, angle))));
|
||||||
|
|
||||||
|
//Wildcard how to represent any other symbol
|
||||||
|
turtleInterpretation.Add("*.*", (float[] args) => new Tuple<GameObject, Matrix4x4>(obj, transformation));
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Żeby tego dokonać należy uzupełnić słownik `turtleInterpretation`, którego kluczami są opisywane symbole jako stringi. Natomiast wartościami są funkcje, które przyjmują jako argument tablicę parametrów danego symbolu (o tym później) a zwracają Krotkę, której pierwszym elementem jest rysowany obiekt, natomiast drugim transformacja, jaką wykona żółw. Powyższym przykładzie obiekty są czytane z modeli a transformacja zawsze jest taka sama, czyli translacja o wektor (0.1,0,0) i skalowanie o wektor (0.1,0.1,0.1). (Skalowania nie są pamiętane przez żółwia)
|
||||||
|
|
||||||
|
Te funkcje są wykorzystywane przez żółwia do interpretacji ciągu symboli. Przykładowo `LRr` zostanie zinterpretowany następująco:
|
||||||
|
|
||||||
|
* żółw przesuwa się o 0.1 w osi X umieszcza bigL w punkcie (0.1,0,0)
|
||||||
|
* żółw przesuwa się o 0.1 w osi X umieszcza bigR w punkcie (0.2,0,0) (ponieważ (0.1,0,0)+(0.1,0,0)=(0.2,0,0) )
|
||||||
|
* żółw przesuwa się o 0.1 w osi X umieszcza bigL w punkcie (0.3,0,0)
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
Jak wyszukasz w internecie obrazki Anabaeny, zobaczysz, że są one często powykręcane, dodaj do macierz przekształceń obroty w osi Y o losowy kąt pomiędzy -20 a 20 stopni.
|
||||||
|
|
||||||
|
## Parametryczne L-Systemy
|
||||||
|
|
||||||
|
Parametryczne L-Systemy operują na symbolach parametrycznych znakach, czyli takich, które posiadają 0 lub więcej parametrów rzeczywistych. Pozwala to przechowywać różne wewnętrzne stany obiektów. Przykładowo dla modelu Anabeany powyżej rozróżniamy tylko 2 stany, młody i dorosły. Dzięki parametrycznym L-Systemom możemy opisać wiek w sposób bardziej ciągły. Przykładowo poniższy L-System komórki która rośnie i jak osiągnie odpowiedni wiek rozdziela się na dwie młode komórki
|
||||||
|
|
||||||
|
```
|
||||||
|
#axiom
|
||||||
|
B(1)
|
||||||
|
#rules
|
||||||
|
B(a) : a<2 -> B(a+0.1)
|
||||||
|
B(a) : a>=2 -> B(1)B(1)
|
||||||
|
#end rules
|
||||||
|
```
|
||||||
|
|
||||||
|
Parametry zapisuje się wewnątrz nawiasów po przecinku. W aksjomacie muszą one mieć wartości liczbowe. Po lewej stronie trzeba nadać parametrom nazwy (mogą mieć one więcej niż jeden znak). Symbole są identyfikowane po nazwie i liczbie znaków. Po dwukropku można podać warunki logiczne jakie musi spełnić symbol. można w tym umieszczać operacje matematyczne, dozwolone jest mnożenie, dzielenie, dodawanie i odejmowanie. podobnie w parametrach po prawej stronie
|
||||||
|
|
||||||
|
### Zadanie
|
||||||
|
|
||||||
|
Napisz dla parametrycznej wersji Anabeny taką interpretację, żeby komórki rosły wraz z wiekiem.
|
||||||
|
|
||||||
|
## Stochastyczne L-Systemy
|
||||||
|
|
||||||
|
Niektóre procesy biologiczne są zbyt skomplikowane albo niedostatecznie zbadane, żeby można je było je zasymulować lub zwyczajnie nie mamy potrzeby symulować mechanizmów tak dokładnie. Zamiast tego możemy skorzystać z losowości, która przybliży zachowanie natury.
|
||||||
|
|
||||||
|
Przykładowo możemy losowo decydować czy w roślinie wyrośnie boczna gałąź czy nie. Co realizuje poniższy L-System (znajduje się on także w pliku `stochastic.txt`)
|
||||||
|
|
||||||
|
```
|
||||||
|
#axiom
|
||||||
|
B
|
||||||
|
#rules
|
||||||
|
B -> #stochastic
|
||||||
|
p=3 FB
|
||||||
|
p=1 [+FB]FB
|
||||||
|
p=1 [-FB]FB
|
||||||
|
p=1 F
|
||||||
|
#stochastic end
|
||||||
|
#rules end
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
W powyższym przypadku mamy symbol B, który symbolizuje merystem (część rośliny zdolną do rozwoju); F oznacza rozwiniętą gałąź. B może rozwinąć łodygę, wytworzyć gałąź po prawej, wytworzyć gałąź po lewej lub zaprzestać rozwój.
|
||||||
|
|
||||||
|
Odpal scenę `LSystem2D` załaduj `stochastic.txt` i odpal kilka razy od początku (żeby zresetować, kliknij *Load File*).
|
||||||
|
|
||||||
|
Reguły stochastyczne należy zacząć od słowa `#stochastic`. Następnie po linijce wypisać wyniki, poprzedzając je frazą `p=W`, gdzie `W` to waga danego wyniku. Wagi mogą być dowolną dodatnią liczbą rzeczywistą. Interpreter na podstawie wag przydzieli prawdopodobieństwo kolejnym wynikom. Przykładowo w powyższym L-Systemie reguły zostaną wykonane następująco:
|
||||||
|
|
||||||
|
* FB z prawdopodobieństwem $\frac{3}{6}$
|
||||||
|
* [+FB]FB z prawdopodobieństwem $\frac{1}{6}$
|
||||||
|
* [+FB]FB z prawdopodobieństwem $\frac{1}{6}$
|
||||||
|
* F z prawdopodobieństwem $\frac{1}{6}$
|
||||||
|
|
||||||
|
<img src="Screenshot 2021-03-14 at 07.32.36.png" alt="Screenshot 2021-03-14 at 07.32.36" style="zoom:33%;" /><img src="Screenshot 2021-03-14 at 07.32.56.png" alt="Screenshot 2021-03-14 at 07.32.56" style="zoom:33%;" /> <img src="Screenshot 2021-03-14 at 07.33.17.png" alt="Screenshot 2021-03-14 at 07.33.17" style="zoom:33%;" />
|
||||||
|
|
||||||
|
### zadanie
|
||||||
|
|
||||||
|
Obecnie zdarza się tak, że L-System wchodzi w ostatnią regułę na samym początku i nic nie wyrasta. Innym razem wyrasta bardzo dużo odgałęzień i całość wymyka się spod kontroli a na pewno przestaje przypominać roślinę. Pomyśl jak można zaradzić tym dwóm problemom, zmodyfikuj L-System tak, by ich uniknąć. Możesz dodać nowe symbole lub/i wykorzystać symbole parametryczne.
|
||||||
|
|
||||||
|
## Zadanie domowe
|
||||||
|
|
||||||
|
Scena `LSystem3D` jest kopią sceny `LSystem2D`, korzysta ona ze skryptu `Turtle3D` zamiast `Turtle2D` (chociaż są one na razie identyczne). Dodaj do `Turtle3D` obsługę obrotów w trzech wymiarach za pomocą znaków:
|
||||||
|
|
||||||
|
* `&` obrót do góry (pitch), czyli obrót względem osi X o kąt $\delta$
|
||||||
|
* `^` obrót do góry (pitch), czyli obrót względem osi X o kąt $-\delta$
|
||||||
|
* `\` obrót do obrót w prawo (roll), czyli obrót względem osi Y o kąt $-\delta$
|
||||||
|
* `/` obrót do obrót w lewo (roll), czyli obrót względem osi Y o kąt $\delta$
|
||||||
|
|
||||||
|
Poza tym dla symboli `L` i `F` dodaj interpretacje kolejno jako liść i kwiat. W folderze Models są gotowe modele, ale możesz ściągnąć własne.
|
||||||
|
|
||||||
|
Wykorzystaj dotychczasową wiedzę i powyższą interpretację, by stworzyć L-System generujący roślinę polną jak poniższy chaber.
|
||||||
|
|
||||||
|
![rysunek chabra z wikipedii](7_Centaurea_cyanus.jpg)
|
BIN
cw1 p2/im_bracketed-5640616.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
cw1 p2/im_bracketed-5642437.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
cw1 p2/im_bracketed.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
cw1 p2/ph00001.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
cw1 p2/ph00002.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
cw1 p2/ph00003.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
cw1 p2/ph00004.png
Normal file
After Width: | Height: | Size: 247 KiB |
BIN
cw1 p2/ph00005.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
cw1 p2/ph00006.png
Normal file
After Width: | Height: | Size: 186 KiB |
BIN
cw1 p2/ph00007.png
Normal file
After Width: | Height: | Size: 141 KiB |
BIN
cw1 p2/ph00008.png
Normal file
After Width: | Height: | Size: 170 KiB |
BIN
cw1 p2/ph00009.png
Normal file
After Width: | Height: | Size: 234 KiB |
7
cw1 p2/render.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
rootdir = './'
|
||||||
|
for filename in os.listdir(rootdir):
|
||||||
|
if filename.endswith(".md"):
|
||||||
|
name = filename[:-3]
|
||||||
|
os.system(f'pandoc -s -o {name}.html {name}.md --mathjax --css style.css')
|
107
cw1 p2/style.css
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
|
||||||
|
|
||||||
|
body{
|
||||||
|
color:#444;
|
||||||
|
font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif;
|
||||||
|
font-size:12px;
|
||||||
|
line-height:1.5em;
|
||||||
|
padding:1em;
|
||||||
|
margin:auto;
|
||||||
|
max-width:42em;
|
||||||
|
background:#fefefe;
|
||||||
|
}
|
||||||
|
|
||||||
|
a{ color: #0645ad; text-decoration:none;}
|
||||||
|
a:visited{ color: #0b0080; }
|
||||||
|
a:hover{ color: #06e; }
|
||||||
|
a:active{ color:#faa700; }
|
||||||
|
a:focus{ outline: thin dotted; }
|
||||||
|
a:hover, a:active{ outline: 0; }
|
||||||
|
|
||||||
|
::-moz-selection{background:rgba(255,255,0,0.3);color:#000}
|
||||||
|
::selection{background:rgba(255,255,0,0.3);color:#000}
|
||||||
|
|
||||||
|
a::-moz-selection{background:rgba(255,255,0,0.3);color:#0645ad}
|
||||||
|
a::selection{background:rgba(255,255,0,0.3);color:#0645ad}
|
||||||
|
|
||||||
|
p{
|
||||||
|
margin:1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img{
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
font-weight:normal;
|
||||||
|
color:#111;
|
||||||
|
line-height:1em;
|
||||||
|
}
|
||||||
|
h4,h5,h6{ font-weight: bold; }
|
||||||
|
h1{ font-size:2.5em; }
|
||||||
|
h2{ font-size:2em; }
|
||||||
|
h3{ font-size:1.5em; }
|
||||||
|
h4{ font-size:1.2em; }
|
||||||
|
h5{ font-size:1em; }
|
||||||
|
h6{ font-size:0.9em; }
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
color:#666666;
|
||||||
|
margin:0;
|
||||||
|
padding-left: 3em;
|
||||||
|
border-left: 0.5em #EEE solid;
|
||||||
|
}
|
||||||
|
hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }
|
||||||
|
pre, code, kbd, samp { color: #000; font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 0.98em; }
|
||||||
|
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||||
|
|
||||||
|
b, strong { font-weight: bold; }
|
||||||
|
|
||||||
|
dfn { font-style: italic; }
|
||||||
|
|
||||||
|
ins { background: #ff9; color: #000; text-decoration: none; }
|
||||||
|
|
||||||
|
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
|
||||||
|
|
||||||
|
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||||
|
sup { top: -0.5em; }
|
||||||
|
sub { bottom: -0.25em; }
|
||||||
|
|
||||||
|
ul, ol { margin: 1em 0; padding: 0 0 0 2em; }
|
||||||
|
li p:last-child { margin:0 }
|
||||||
|
dd { margin: 0 0 0 2em; }
|
||||||
|
|
||||||
|
img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
th { border-bottom: 1px solid black; }
|
||||||
|
td { vertical-align: top; }
|
||||||
|
|
||||||
|
@media only screen and (min-width: 480px) {
|
||||||
|
body{font-size:14px;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 768px) {
|
||||||
|
body{font-size:16px;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
* { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; }
|
||||||
|
body{font-size:12pt; max-width:100%;}
|
||||||
|
a, a:visited { text-decoration: underline; }
|
||||||
|
hr { height: 1px; border:0; border-bottom:1px solid black; }
|
||||||
|
a[href]:after { content: " (" attr(href) ")"; }
|
||||||
|
abbr[title]:after { content: " (" attr(title) ")"; }
|
||||||
|
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
|
||||||
|
pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; }
|
||||||
|
tr, img { page-break-inside: avoid; }
|
||||||
|
img { max-width: 100% !important; }
|
||||||
|
@page :left { margin: 15mm 20mm 15mm 10mm; }
|
||||||
|
@page :right { margin: 15mm 10mm 15mm 20mm; }
|
||||||
|
p, h2, h3 { orphans: 3; widows: 3; }
|
||||||
|
h2, h3 { page-break-after: avoid; }
|
||||||
|
}
|
BIN
im_bracketed-5640616.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
im_bracketed-5642437.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
im_bracketed.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
materiałyHelloWorld/.DS_Store
vendored
Normal file
BIN
materiałyHelloWorld/Grass-025.jpg
Normal file
After Width: | Height: | Size: 18 MiB |
After Width: | Height: | Size: 681 KiB |
BIN
materiałyHelloWorld/Gravel020_1K-JPG/Gravel020_1K_Color.jpg
Normal file
After Width: | Height: | Size: 886 KiB |
After Width: | Height: | Size: 487 KiB |
BIN
materiałyHelloWorld/Gravel020_1K-JPG/Gravel020_1K_IdMask.jpg
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
materiałyHelloWorld/Gravel020_1K-JPG/Gravel020_1K_Normal.jpg
Normal file
After Width: | Height: | Size: 2.0 MiB |
BIN
materiałyHelloWorld/Gravel020_1K-JPG/Gravel020_1K_Roughness.jpg
Normal file
After Width: | Height: | Size: 653 KiB |
After Width: | Height: | Size: 786 KiB |
BIN
materiałyHelloWorld/Ground019_1K-JPG/Ground019_1K_Color.jpg
Normal file
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 568 KiB |
BIN
materiałyHelloWorld/Ground019_1K-JPG/Ground019_1K_Normal.jpg
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
materiałyHelloWorld/Ground019_1K-JPG/Ground019_1K_Roughness.jpg
Normal file
After Width: | Height: | Size: 702 KiB |
After Width: | Height: | Size: 641 KiB |
BIN
materiałyHelloWorld/Ground037_1K-JPG/Ground037_1K_Color.jpg
Normal file
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 489 KiB |
BIN
materiałyHelloWorld/Ground037_1K-JPG/Ground037_1K_Normal.jpg
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
materiałyHelloWorld/Ground037_1K-JPG/Ground037_1K_Roughness.jpg
Normal file
After Width: | Height: | Size: 726 KiB |
After Width: | Height: | Size: 867 KiB |
BIN
materiałyHelloWorld/Ground042_1K-JPG/Ground042_1K_Color.jpg
Normal file
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 607 KiB |
BIN
materiałyHelloWorld/Ground042_1K-JPG/Ground042_1K_Normal.jpg
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
materiałyHelloWorld/Ground042_1K-JPG/Ground042_1K_Roughness.jpg
Normal file
After Width: | Height: | Size: 603 KiB |
After Width: | Height: | Size: 927 KiB |
BIN
materiałyHelloWorld/Moss002_1K-JPG/Moss002_1K_Color.jpg
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
materiałyHelloWorld/Moss002_1K-JPG/Moss002_1K_Displacement.jpg
Normal file
After Width: | Height: | Size: 615 KiB |
BIN
materiałyHelloWorld/Moss002_1K-JPG/Moss002_1K_Normal.jpg
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
materiałyHelloWorld/Moss002_1K-JPG/Moss002_1K_Roughness.jpg
Normal file
After Width: | Height: | Size: 758 KiB |
BIN
materiałyHelloWorld/clock.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
ph00001.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
ph00002.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
ph00003.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
ph00004.png
Normal file
After Width: | Height: | Size: 247 KiB |
BIN
ph00005.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
ph00006.png
Normal file
After Width: | Height: | Size: 186 KiB |
BIN
ph00007.png
Normal file
After Width: | Height: | Size: 141 KiB |
BIN
ph00008.png
Normal file
After Width: | Height: | Size: 170 KiB |
BIN
ph00009.png
Normal file
After Width: | Height: | Size: 234 KiB |
BIN
unity_artifitial_world-st/.DS_Store
vendored
Normal file
BIN
unity_artifitial_world-st/Assets/.DS_Store
vendored
Normal file
8
unity_artifitial_world-st/Assets/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 329ec9409c534054d896e1b927a1b71c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
31
unity_artifitial_world-st/Assets/Editor/TurtleEditor.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
[CustomEditor(typeof(TurtleLSystem),true)]
|
||||||
|
public class TurtleEditor : Editor
|
||||||
|
{
|
||||||
|
TurtleLSystem turtleLSystem;
|
||||||
|
|
||||||
|
|
||||||
|
public override void OnInspectorGUI() {
|
||||||
|
DrawDefaultInspector();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Load file")) {
|
||||||
|
turtleLSystem.loadFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Evaluate")) {
|
||||||
|
turtleLSystem.evaluateAndPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void OnEnable() {
|
||||||
|
turtleLSystem = (TurtleLSystem)target;
|
||||||
|
Tools.hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable() {
|
||||||
|
Tools.hidden = false;
|
||||||
|
}
|
||||||
|
}
|
11
unity_artifitial_world-st/Assets/Editor/TurtleEditor.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5805e7212a5b20b4da42e342c1edaf04
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
unity_artifitial_world-st/Assets/LSystem.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 53a6756541318784f8b822a4dd8564c2
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
unity_artifitial_world-st/Assets/LSystem/Anabaena.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#axiom
|
||||||
|
L
|
||||||
|
#rules
|
||||||
|
L->lR
|
||||||
|
R->Lr
|
||||||
|
l->L
|
||||||
|
r->R
|
||||||
|
#end rules
|
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: da39d102803271748a23bdcc7d8431f8
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|