From 01beaa369a6e89a303652679f03b2059a663b224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Fri, 6 Jun 2025 22:32:10 +0200 Subject: [PATCH] Setup the docs framework I did various changes and updates, using the question 8 (modelovani a projekce) as my lab rat. It's a pretty good case, containing images, plenty of math, footnotes, everything. I now feel it looks pretty good, I'll try to import more content. --- astro.config.mjs | 40 +- package.json | 7 +- pnpm-lock.yaml | 118 ++++ src/assets/fi_16.png | Bin 0 -> 187 bytes src/content/docs/guides/example.md | 11 - src/content/docs/index.md | 11 + src/content/docs/index.mdx | 36 -- .../docs/reference/{example.md => frfr.md} | 2 +- src/content/docs/reference/index.md | 4 + src/content/docs/szmgr.md | 6 + .../docs/szmgr/SZP08_modelovani_a_projekce.md | 513 ++++++++++++++++++ src/plugins/custom-footnote.ts | 25 + src/styles/footnotes-fix.css | 9 + src/styles/pixelated-logo.css | 3 + src/styles/theme.css | 32 ++ 15 files changed, 758 insertions(+), 59 deletions(-) create mode 100644 src/assets/fi_16.png delete mode 100644 src/content/docs/guides/example.md create mode 100644 src/content/docs/index.md delete mode 100644 src/content/docs/index.mdx rename src/content/docs/reference/{example.md => frfr.md} (94%) create mode 100644 src/content/docs/reference/index.md create mode 100644 src/content/docs/szmgr.md create mode 100644 src/content/docs/szmgr/SZP08_modelovani_a_projekce.md create mode 100644 src/plugins/custom-footnote.ts create mode 100644 src/styles/footnotes-fix.css create mode 100644 src/styles/pixelated-logo.css create mode 100644 src/styles/theme.css diff --git a/astro.config.mjs b/astro.config.mjs index 9a25601..c1d786b 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,25 +1,45 @@ // @ts-check import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; +import remarkGithubAlerts from 'remark-github-alerts'; +import remarkMath from 'remark-math'; +import rehypeKatex from 'rehype-katex'; +import rehypeCustomFootnotes from './src/plugins/custom-footnote'; + + + // https://astro.build/config export default defineConfig({ + markdown: { + + remarkPlugins: [remarkGithubAlerts, remarkMath], + rehypePlugins: [rehypeKatex, rehypeCustomFootnotes] + }, integrations: [ starlight({ - title: 'My Docs', + title: 'SZMGR', + logo: { + src: "./src/assets/fi_16.png" + }, social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' }], + customCss: [ + "remark-github-alerts/styles/github-colors-light.css", + "remark-github-alerts/styles/github-colors-dark-class.css", + "remark-github-alerts/styles/github-base.css", + "katex/dist/katex.min.css", + "./src/styles/theme.css", + "./src/styles/footnotes-fix.css", + "./src/styles/pixelated-logo.css", + ], sidebar: [ { - label: 'Guides', - items: [ - // Each item here is one entry in the navigation menu. - { label: 'Example Guide', slug: 'guides/example' }, - ], - }, - { - label: 'Reference', - autogenerate: { directory: 'reference' }, + label: 'SZMGR', + autogenerate: { + directory: "szmgr" + } }, + ], }), ], diff --git a/package.json b/package.json index f3ae82c..c4fe1b9 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,11 @@ "dependencies": { "@astrojs/starlight": "^0.34.3", "astro": "^5.6.1", - "sharp": "^0.32.5" + "katex": "^0.16.22", + "rehype-katex": "^7.0.1", + "remark-github-alerts": "^0.1.1", + "remark-math": "^6.0.0", + "sharp": "^0.32.5", + "unist-util-visit": "^5.0.0" } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 181be5c..4941031 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,24 @@ importers: astro: specifier: ^5.6.1 version: 5.9.0(@types/node@22.15.30)(rollup@4.42.0)(typescript@5.8.3) + katex: + specifier: ^0.16.22 + version: 0.16.22 + rehype-katex: + specifier: ^7.0.1 + version: 7.0.1 + remark-github-alerts: + specifier: ^0.1.1 + version: 0.1.1(@types/mdast@4.0.4)(unified@11.0.5) + remark-math: + specifier: ^6.0.0 + version: 6.0.0 sharp: specifier: ^0.32.5 version: 0.32.6 + unist-util-visit: + specifier: ^5.0.0 + version: 5.0.0 packages: @@ -540,6 +555,9 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -763,6 +781,10 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + common-ancestor-path@1.0.1: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} @@ -972,6 +994,12 @@ packages: hast-util-format@1.1.0: resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + hast-util-from-html@2.0.3: resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} @@ -1100,6 +1128,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + katex@0.16.22: + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} + hasBin: true + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -1161,6 +1193,9 @@ packages: mdast-util-gfm@3.1.0: resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + mdast-util-mdx-expression@2.0.1: resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} @@ -1215,6 +1250,9 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + micromark-extension-mdx-expression@3.0.1: resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} @@ -1492,6 +1530,9 @@ packages: rehype-format@5.0.1: resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + rehype-parse@9.0.1: resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} @@ -1513,6 +1554,15 @@ packages: remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + remark-github-alerts@0.1.1: + resolution: {integrity: sha512-A0NLfeAuu76ymiGIoEoBcHmqlPcdLFq+FoCGiWlzu8vkyhscyDv+pAkMA9paGr+OHpzpFflZKnsqOCvMESG/Uw==} + peerDependencies: + '@types/mdast': ^4.0.0 + unified: ^11.0.0 + + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + remark-mdx@3.1.0: resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} @@ -2423,6 +2473,8 @@ snapshots: '@types/js-yaml@4.0.9': {} + '@types/katex@0.16.7': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -2708,6 +2760,8 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@8.3.0: {} + common-ancestor-path@1.0.1: {} cookie-es@1.2.2: {} @@ -2944,6 +2998,19 @@ snapshots: html-whitespace-sensitive-tag-names: 3.0.1 unist-util-visit-parents: 6.0.1 + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + hast-util-from-html@2.0.3: dependencies: '@types/hast': 3.0.4 @@ -3173,6 +3240,10 @@ snapshots: dependencies: argparse: 2.0.1 + katex@0.16.22: + dependencies: + commander: 8.3.0 + kleur@3.0.3: {} kleur@4.1.5: {} @@ -3298,6 +3369,18 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 @@ -3469,6 +3552,16 @@ snapshots: micromark-util-combine-extensions: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.7 + devlop: 1.1.0 + katex: 0.16.22 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-extension-mdx-expression@3.0.1: dependencies: '@types/estree': 1.0.8 @@ -3881,6 +3974,16 @@ snapshots: '@types/hast': 3.0.4 hast-util-format: 1.1.0 + rehype-katex@7.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/katex': 0.16.7 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + katex: 0.16.22 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.3 + rehype-parse@9.0.1: dependencies: '@types/hast': 3.0.4 @@ -3934,6 +4037,21 @@ snapshots: transitivePeerDependencies: - supports-color + remark-github-alerts@0.1.1(@types/mdast@4.0.4)(unified@11.0.5): + dependencies: + '@types/mdast': 4.0.4 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + remark-math@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-mdx@3.1.0: dependencies: mdast-util-mdx: 3.0.0 diff --git a/src/assets/fi_16.png b/src/assets/fi_16.png new file mode 100644 index 0000000000000000000000000000000000000000..abe948efa0d6151dfefa75831e9a30600c4a6758 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~o&cW^S0D`p zpRU9_*&=OXWupz`u#^P(1vC8r|9`WtLkE!W>*?YcA~7{}f;S(7A%|1oyZYyW7hm?b z9_m)~W$a5(Y_LmWO6<&gX5GM$<>qX?R^t(WQTgnm=2C;ar{YuYf97ubaN_G7<_G6a b_)qxBut9>6f4+k6KajPau6{1-oD!M<@o_vi literal 0 HcmV?d00001 diff --git a/src/content/docs/guides/example.md b/src/content/docs/guides/example.md deleted file mode 100644 index ebd0f3b..0000000 --- a/src/content/docs/guides/example.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Example Guide -description: A guide in my new Starlight docs site. ---- - -Guides lead a user through a specific task they want to accomplish, often with a sequence of steps. -Writing a good guide requires thinking about what your users are trying to do. - -## Further reading - -- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework diff --git a/src/content/docs/index.md b/src/content/docs/index.md new file mode 100644 index 0000000..5b88cd8 --- /dev/null +++ b/src/content/docs/index.md @@ -0,0 +1,11 @@ +--- +title: FI Notes +description: Notes (mostly in Czech) from the Faculty of Informatics of Masaryk University in Brno. +--- + +Notes (mostly in Czech) from the [Faculty of Informatics of Masaryk University](https://www.fi.muni.cz) in Brno. Source files are available on GitHub. Contributions are welcome! + +## Thesis Checklist + +> [!TIP] +> If [I](https://is.muni.cz/auth/osoba/469242) happen to be your supervisor, please see [**this checklist**](https://docs.google.com/document/d/1wIaeUFpwKeShIW506U5qVkw9odoWXO78XcynmEGr7tQ/edit?usp=sharing) for requirements, recommendations, tips, and common mistakes. You may find it useful even if your supervisor is someone else. diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx deleted file mode 100644 index 664b681..0000000 --- a/src/content/docs/index.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Welcome to Starlight -description: Get started building your docs site with Starlight. -template: splash -hero: - tagline: Congrats on setting up a new Starlight project! - image: - file: ../../assets/houston.webp - actions: - - text: Example Guide - link: /guides/example/ - icon: right-arrow - - text: Read the Starlight docs - link: https://starlight.astro.build - icon: external - variant: minimal ---- - -import { Card, CardGrid } from '@astrojs/starlight/components'; - -## Next steps - - - - Edit `src/content/docs/index.mdx` to see this page change. - - - Add Markdown or MDX files to `src/content/docs` to create new pages. - - - Edit your `sidebar` and other config in `astro.config.mjs`. - - - Learn more in [the Starlight Docs](https://starlight.astro.build/). - - diff --git a/src/content/docs/reference/example.md b/src/content/docs/reference/frfr.md similarity index 94% rename from src/content/docs/reference/example.md rename to src/content/docs/reference/frfr.md index 0224f09..d281912 100644 --- a/src/content/docs/reference/example.md +++ b/src/content/docs/reference/frfr.md @@ -1,5 +1,5 @@ --- -title: Example Reference +title: For real for real description: A reference page in my new Starlight docs site. --- diff --git a/src/content/docs/reference/index.md b/src/content/docs/reference/index.md new file mode 100644 index 0000000..c741a3b --- /dev/null +++ b/src/content/docs/reference/index.md @@ -0,0 +1,4 @@ +--- +title: For real for real +description: A reference page in my new Starlight docs site. +--- diff --git a/src/content/docs/szmgr.md b/src/content/docs/szmgr.md new file mode 100644 index 0000000..0940489 --- /dev/null +++ b/src/content/docs/szmgr.md @@ -0,0 +1,6 @@ +--- +title: MGR State exam +description: A reference page in my new Starlight docs site. +--- + +# SZMGR \ No newline at end of file diff --git a/src/content/docs/szmgr/SZP08_modelovani_a_projekce.md b/src/content/docs/szmgr/SZP08_modelovani_a_projekce.md new file mode 100644 index 0000000..8eb9ab3 --- /dev/null +++ b/src/content/docs/szmgr/SZP08_modelovani_a_projekce.md @@ -0,0 +1,513 @@ +--- +title: 8. Modelování a projekce +description: A guide in my new Starlight docs site. +--- + +> [!NOTE] +> Homogenní souřadnice, modelovací, pohledová a projekční matice, perspektivní a ortografická projekce. Základní afinní transformace. +> +> _PV189, PV112_ + +## Souřadnicové systémy + +- **Right-hand rule** + Mnemotechnická pomůcka pro určení orientace os v kartézské soustavě souřadnic. Taky se používá pro určení směru vektorového součinu. + + ![Right-hand rule](./img/szp08_right_hand_rule.svg) + + > [!TIP] + > Osa X je dána ukazováčkem, osa Y prostředníčkem, osa Z palcem. Pokud Y míří nahoru, pak ano, člověk si u toho může vykroutit ruku, ale alespoň si to zapamatuje. + +- **Kartézská soustava souřadnic** + Right-handed systém definován třemi kolmými osami. Ve 2D jsou to $x$ a $y$. Ve 3D jsou to $x$, $y$ a $z$. Jsou na sebe v zájemně kolmé. Počátek je v bodě, kde se protínají všechny osy, označovaném jako $0$. +- **Homogenní souřadnice** + Hack, kdy reprezentujeme souřadnici v 3D prostoru pomocí 4 čísel, abychom mohli zapsat translaci pomocí matice. Využívá se v projektivní geometrii, pro projekci 3D scén na 2D plochu. + + Převod z kartézských na homogenní souřadnice: $(x, y, z) \to (x, y, z, 1)$. + + Převod z homogenních na kartézské souřadnice: $(x, y, z, w) \to (\frac{x}{w}, \frac{y}{w}, \frac{z}{w})$. + + Body, kde $w = 0$ jsou body v nekonečnu. Využívá se pro popis pohybu k nekonečnu, který se v kartézských souřadnicích nedá popsat. + +## MVP matice + +> [!IMPORTANT] +> Pro implementaci v OpenGL viz [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/). + +> [!WARNING] +> Při zápisu matic bacha na to, jestli jsou row-major nebo column-major. Třeba v OpenGL to znamená, že se všechny matice píší v transponované podobě, jelikož OpenGL je column-major a v takovém pořádí jsou i parametery `mat2`, `mat3` a `mat4` V GLSL. + +- **Modelovací matice $M$** + Převádí souřadnice z prostoru objektu (local space) do prostoru světa (world space). Využívá se pro rotaci ($R$), škálování ($S$) a translaci ($T$) objektu. + + ```math + M = T \cdot R \cdot S + ``` + +- **Pohledová matice / view matrix $V$**\ + Převádí souřadnice z prostoru světa (world space) do prostoru před kamerou (camera space). Otáčí světem, aby kamera byla jeho středem.[^camera] + + ```math + V = \begin{bmatrix} + \color{red}{R_x} & \color{red}{R_y} & \color{red}{R_z} & 0 \\ + \color{green}{U_x} & \color{green}{U_y} & \color{green}{U_z} & 0 \\ + \color{blue}{D_x} & \color{blue}{D_y} & \color{blue}{D_z} & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + \cdot + \begin{bmatrix} + 1 & 0 & 0 & -\color{purple}{P_x} \\ + 0 & 1 & 0 & -\color{purple}{P_y} \\ + 0 & 0 & 1 & -\color{purple}{P_z} \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + kde: + + - $\color{red}{R}$ je vektor, který ukazuje doprava od kamery. + - $\color{green}{U}$ je vektor, který ukazuje nahoru od kamery. + - $\color{blue}{D}$ je vektor, který ukazuje dopředu od kamery. + - $\color{purple}{P}$ je pozice kamery. + + > [!NOTE] + > Všimni si, že levá matice je transponovaná a poziční vektor v pravé matici je negovaný. Je to proto, že otáčíme a posouváme celým světem tak, aby kamera byla v počátku, musíme proto provést inverzní operace vůči těm, které chceme provést s kamerou. [^camera] + +- **Frustum** + Část 3D tělesa (nejčastěji pyramidy nebo jehlanu) mezi dvěma rovnoběžnými rovinami. Doslovný překlad je _"komolý jehlan"_ +- **Projekční matice / projection matrix $P$** + Převádí souřadnice z prostoru před kamerou (camera space) do clip space. + + Používá se zejména ortografická projekce ($P_\text{ortho}$) a perspektivní projekce ($P_\text{persp}$). + +- **MVP matice** + Pro převod modelu z jeho lokálního prostoru do clip space použijeme: + + ```math + \vec{v}_\text{clip} = P \cdot V \cdot M \cdot \vec{v}_\text{local} + ``` + +## Projekce + +### Ortografická projekce + +Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [camera](#camera) + +![width=500](./img/szp08_orthographic_projection.png) + +Je dána 6 parametry: + +- $\text{left}$ - levá hranice (X), +- $\text{right}$ - pravá hranice (X), +- $\text{bottom}$ - spodní hranice (Y), +- $\text{top}$ - horní hranice (Y), +- $\text{near}$ - blízká hranice (Z), +- $\text{far}$ - daleká hranice (Z). + +Společně definují boxík, kde je $(\text{left}, \text{bottom}, -\text{near})$ levý spodní roh a $(\text{right}, \text{top}, -\text{far})$ pravý horní roh. Úkolem matice $P_\text{ortho}$ je nasoukat tento boxík do krychle $(-1, -1, -1) \to (1, 1, 1)$ (a navíc flipnou Z, protože OpenGL mění handedness). + +```math +\begin{aligned} + +P_\text{ortho} &= C \cdot S \cdot T \\ + +&= + +\begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & -1 & 0 \\ + 0 & 0 & 0 & 1 \\ +\end{bmatrix} +\cdot +\begin{bmatrix} + \frac{2}{\text{right-left}} & 0 & 0 & 0 \\ + 0 & \frac{2}{\text{top-bottom}} & 0 & 0 \\ + 0 & 0 & \frac{2}{\text{far-near}} & 0 \\ + 0 & 0 & 0 & 1 \\ +\end{bmatrix} +\cdot +\begin{bmatrix} + 1 & 0 & 0 & -\frac{\text{right+left}}{2} \\ + 0 & 1 & 0 & -\frac{\text{top+bottom}}{2} \\ + 0 & 0 & 1 & -\frac{\text{far+near}}{2} \\ + 0 & 0 & 0 & 1 \\ +\end{bmatrix} \\ +&= + +\begin{bmatrix} + \frac{2}{\text{right}-\text{left}} & 0 & 0 & -\frac{\text{right}+\text{left}}{\text{right}-\text{left}} \\ + 0 & \frac{2}{\text{top}-\text{bottom}} & 0 & -\frac{\text{top}+\text{bottom}}{\text{top}-\text{bottom}} \\ + 0 & 0 & -\frac{2}{\text{far}-\text{near}} & -\frac{\text{far}+\text{near}}{\text{far}-\text{near}} \\ + 0 & 0 & 0 & 1 \\ +\end{bmatrix} + +\end{aligned} +``` + +kde: + +- $C$ obrací osu Z, kvůli přechodu z right-handed do left-handed (týká se OpenGL [^ortho]), +- $S$ definuje velikost kvádru, který se vleze do clip space, +- $T$ posouvá počátek doprostřed kvádru. + +### Perspektivní projekce + +Zmenšuje objekty, které jsou dále od kamery. [^camera] + +![width=500](./img/szp08_perspective_projection.png) + +Je definována 4 parametry: + +- $\text{FOV}_y$ - field of view (úhel zorného pole) v ose Y, +- $\text{aspect}$ - poměr šířky a výšky okna, +- $\text{near}$ - blízká hranice, +- $\text{far}$ - daleká hranice. + +V matici $P_\text{persp}$ se vyskytují následující mezihodnoty: + +- $\text{top} = \text{near} \cdot \tan \left( \frac{\text{FOV}_y}{2} \right)$, +- $\text{bottom} = -\text{top}$, +- $\text{right} = \text{top} \cdot \text{aspect}$, +- $\text{left} = -\text{right}$. + +- **Translace frustumu** + Posouváme špičku frustumu do počátku souřadného systému. [^perspective] + + ```math + T = + \begin{bmatrix} + 1 & 0 & 0 & -\frac{\text{left} + \text{right}}{2} \\ + 0 & 1 & 0 & -\frac{\text{bottom} + \text{top}}{2} \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + > [!NOTE] + > Všimni si, že. Pokud používáme 4-parametrickou verzi, tak je to matice identity a tím pádem není potřeba. + +- **Perspective divide** + Objekty blíže k rovině $\text{near}$ budou větší než objekty dále. Rovina $\text{near}$ reprezentuje plochu obrazovky, na kterou jsou všechny body promítány. + + **Perspective divide** [^perspective] + + ![width=500](./img/szp08_perspective_divide.png) + + V obrázku výše je bod $(x, y, z)$ promítnut na rovinu $\text{near}$ jako $(x', y', near)$. Vznikají tak dva trojúhelníky, které jsou si sobě podobné a proto mají stejné poměry stran. Platí tedy $\frac{y'}{\text{near}} = \frac{y}{z}$. Pak $y' = \frac{y \cdot \text{near}}{z}$. Chceme tedy, aby platilo: + + ```math + \begin{aligned} + x' = \frac{x \cdot \text{near}}{z} \\ + y' = \frac{y \cdot \text{near}}{z} + \end{aligned} + ``` + + Což můžeme vyjádřit v homogenních souřadnicích vyjadřít dělením $w$ jako: + + ```math + D = \begin{bmatrix} + \text{near} & 0 & 0 & 0 \\ + 0 & \text{near} & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & \color{red}{-1} & \color{red}{0} \\ + \end{bmatrix} + ``` + +- **Velikost okna** + Šířka a výška okna dána pomocí $\text{left}, \text{right}, \text{bottom}, \text{top}$ se musí vlézt do intervalu $(-1.0, 1.0)$, proto je potřeba provést škálování: + + ```math + S = \begin{bmatrix} + \frac{2}{\text{right} - \text{left}} & 0 & 0 & 0 \\ + 0 & \frac{2}{\text{top} - \text{bottom}} & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 \\ + \end{bmatrix} + ``` + +- **Přemapování hloubky** + Chceme zachovat tu schopnost souřadnice $z$ nám říct, že něco je před něčím jiným. Potřebujeme proto přemapovat interval $(-\text{near}, -\text{far})$ na $(-1.0, 1.0)$. Jelikož desetinná čísla mají tendenci vytvářet artefakty, chceme aby toto mapování bylo nelineární tak, aby bylo přesnější blíže $\text{near}$. Použijeme $\frac{c_1}{-z} + c_2$, kde $c_1$ a $c_2$ jsou konstanty zvoleny pomocí: + + > [!NOTE] + > Interval $(-\text{near}, -\text{far})$ obsahuje negace, neboť kamera se dívá do -Z osy, ale tyto hodnoty zadáváme jako kladná čísla. + + > [!NOTE] + > $-z$ v rovnici výše je zodpovědné za přepnutí mezi right-handed a left-handed systémem souřadnic v OpenGL. + + **Depth mapping [^perspective]** + + ![width=500](./img/szp08_depth_mapping.png) + + ```math + \begin{aligned} + -1.0 &= \frac{c_1}{-(-\text{near})} + c_2 \\ + 1.0 &= \frac{c_1}{-(-\text{far})} + c_2 + \end{aligned} + ``` + + Tedy: + + ```math + \begin{aligned} + c_1 &= \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ + c_2 &= \frac{\text{far} + \text{near}}{\text{far} - \text{near}} + \end{aligned} + ``` + + Pokud $\frac{c_1}{-z} + c_2$ přepíšeme jako $\frac{(c_1 + c_2 \cdot (-z))}{-z} = \frac{(-c_2 \cdot z + c_1)}{-z}$, můžeme opět použít homogenní souřadnice a dělení $w$ a získáme: + + ```math + M_\text{depth} = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & -c_2 & c_1 \\ + 0 & 0 & -1 & 0 \\ + \end{bmatrix} + = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ + 0 & 0 & -1 & 0 \\ + \end{bmatrix} + ``` + +--- + +Výsledná matice je: + +```math +P_\text{persp} = M_\text{depth} \cdot S \cdot D \cdot T = + +\begin{bmatrix} + \textcolor{green}{\frac{2 \cdot \text{near}}{\text{right} - \text{left}}} + & 0 + & 0 + & \textcolor{purple}{-\text{near} \cdot \frac{\text{right} + \text{left}}{\text{right} - \text{left}}} \\ + + 0 + & \textcolor{blue}{\frac{2 \cdot \text{near}}{\text{top} - \text{bottom}}} + & 0 + & \textcolor{#F56FA1}{-\text{near} \cdot \frac{\text{top} + \text{bottom}}{\text{top} - \text{bottom}}} \\ + % Nika: použij cyklamenovou farbu + + 0 + & 0 + & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} + & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ + + 0 & 0 & -1 & 0 \\ +\end{bmatrix} +``` + +Tahle matice funguje pro obecné frustum dané parametry $\text{left}, \text{right}, \text{bottom}, \text{top}, \text{near}, \text{far}$. Pokud dosadíme původní parametry za mezihodnoty: + +```math +\begin{aligned} + +\textcolor{green}{\frac{2 \cdot \text{near}}{\text{right} - \text{left}}} +&= \frac{\textcolor{red}{2} \cdot \text{near}}{\textcolor{red}{2} \cdot \text{right}} += \frac{\text{near}}{\text{top} \cdot \text{aspect}} += \frac{\textcolor{red}{\text{near}}}{\textcolor{red}{\text{near}} \cdot \tan \left( \frac{\text{FOV}_y}{2} \right) \cdot \text{aspect}} += \textcolor{green}{\frac{\cot \left( \frac{\text{FOV}_y}{2} \right)}{\text{aspect}}} \\ + +\textcolor{blue}{\frac{2 \cdot \text{near}}{\text{top} - \text{bottom}}} +&= \frac{\textcolor{red}{2} \cdot \text{near}}{\textcolor{red}{2} \cdot \text{top}} += \frac{\textcolor{red}{\text{near}}}{\textcolor{red}{\text{near}} \cdot \tan \left( \frac{\text{FOV}_y}{2} \right)} += \textcolor{blue}{\cot \left( \frac{\text{FOV}_y}{2} \right)} \\ + +\textcolor{purple}{-\text{near} \cdot \frac{\text{right} + \text{left}}{\text{right} - \text{left}}} +&= -\text{near} \cdot \frac{\color{red} \text{right} - \text{right}}{2 \cdot \text{right}} += \textcolor{purple}{0} \\ + +\textcolor{#F56FA1}{-\text{near} \cdot \frac{\text{top} + \text{bottom}}{\text{top} - \text{bottom}}} +&= -\text{near} \cdot \frac{\color{red} \text{top} - \text{top}}{2 \cdot \text{top}} += \textcolor{#F56FA1}{0} + +\end{aligned} +``` + +dostaneme matici, na kterou se trochu lépe kouká: [^gluperspective] + +```math +P_\text{persp} = \begin{bmatrix} + \textcolor{green}{\frac{\cot \left( \frac{\text{FOV}_y}{2} \right)}{\text{aspect}}} + & 0 + & 0 + & \textcolor{purple}{0} \\ + + 0 + & \textcolor{blue}{\cot \left( \frac{\text{FOV}_y}{2} \right)} + & 0 + & \textcolor{#F56FA1}{0} \\ + + 0 + & 0 + & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} + & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ + + 0 & 0 & -1 & 0 \\ +\end{bmatrix} +``` + +## Základní afinní transformace + +Opakování z [Lineární algebry II](../../szb/linearni-algebra-ii/): + +- **Afinní prostor $\mathcal{A}$**\ + Trojice $(A, V, \oplus)$, kde $A$ je množina bodů, $V$ je vektorový prostor (zaměření) a $\oplus$ je binární funkce $\oplus : A \times V \to A$. +- **Standardní afinní prostor $\mathcal{A}_n$**\ + Je afinní prostor $(\mathbb{R}^n, \mathbb{R}^n, +)$. +- **Afinní kombinace bodů**\ + Výrazy tvaru $t_0 \cdot a_0 + t_1 \cdot a_1 + ... + t_n \cdot a_n$, kde $t_i \in \mathbb{R}, a_i \in \mathcal{A}$ a $\sum_{i=0}^n t_i = 1$. +- **Afinní zobrazení**\ + Zobrazení $f : \mathcal{A} \to \mathcal{A}$, které zachovává afinní kombinace bodů. + + Složení nějakého lineárního zobrazení a translace. + +- **Translace $T$**\ + Pro posun v 2D prostoru podél osy $(x, y)$: + + ```math + T = \begin{bmatrix} + 1 & 0 & x \\ + 0 & 1 & y \\ + 0 & 0 & 1 + \end{bmatrix} + ``` + + Pro posun ve 3D prostoru podél osy $(x, y, z)$: + + ```math + T = \begin{bmatrix} + 1 & 0 & 0 & x \\ + 0 & 1 & 0 & y \\ + 0 & 0 & 1 & z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +- **Rotace $R$**\ + Pro rotaci v 2D prostoru o úhel $\theta$: + + ```math + R = \begin{bmatrix} + \cos \theta & -\sin \theta & 0 \\ + \sin \theta & \cos \theta & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + Pro rotaci ve 3D prostoru o úhel $\theta$: + + - Kolem osy $X$: + + ```math + R = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & \cos \theta & -\sin \theta & 0 \\ + 0 & \sin \theta & \cos \theta & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + - Kolem osy $Y$: + + ```math + R = \begin{bmatrix} + \cos \theta & 0 & \sin \theta & 0 \\ + 0 & 1 & 0 & 0 \\ + -\sin \theta & 0 & \cos \theta & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + - Kolem osy $Z$: + + ```math + R = \begin{bmatrix} + \cos \theta & -\sin \theta & 0 & 0 \\ + \sin \theta & \cos \theta & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +- **Škálování / scale $S$** + Pro škálování v 2D prostoru: + + ```math + S = \begin{bmatrix} + x & 0 & 0 \\ + 0 & y & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + Pro škálování ve 3D prostoru: + + ```math + S = \begin{bmatrix} + x & 0 & 0 & 0 \\ + 0 & y & 0 & 0 \\ + 0 & 0 & z & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +- **Zkosení / shear (asi taky $S$)** + Pro zkosení v 2D prostoru vektorem $(x, y)$: + + ```math + S = \begin{bmatrix} + 1 & x & 0 \\ + y & 1 & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + Pro zkosení ve 3D prostoru podél plochy $YZ$: + + ```math + S = \begin{bmatrix} + 1 & Y & Z & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + Podél plochy $XZ$: + + ```math + S = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + X & 1 & Z & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + Podél plochy $XY$: + + ```math + S = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + X & Y & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +## Další zdroje + +- [`glm::ortho`](https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_clip_space.inl#L55) +- [`glm::perspective`](https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_clip_space.inl#L249) +- [`glm::lookAt`](https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_transform.inl#L153) + +--- + +[^camera]: [LearnOpenGL: Camera](https://learnopengl.com/Getting-started/Camera) +[^ortho]: [LearnWebGL: Orthographic Projection](http://learnwebgl.brown37.net/08_projections/projections_ortho.html) +[^perspective]: [LearnWebGL: Perspective Projection](http://learnwebgl.brown37.net/08_projections/projections_perspective.html) +[^gluperspective]: [`gluPerspective`](https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml) diff --git a/src/plugins/custom-footnote.ts b/src/plugins/custom-footnote.ts new file mode 100644 index 0000000..c091b80 --- /dev/null +++ b/src/plugins/custom-footnote.ts @@ -0,0 +1,25 @@ +import { visit } from 'unist-util-visit'; + +export default function rehypeCustomFootnotes() { + return (tree: any) => { + visit(tree, 'element', (node) => { + + if ( + node.tagName === 'h2' && + node.properties?.id === 'footnote-label' + ) { + node.children[0].value = 'Zdroje'; // Change heading text + } + + if ( + node.tagName === 'span' && + node.properties?.className?.includes('sr-only') && + node.children?.[0]?.value?.startsWith('Section titled') + ) { + node.children[0].remove; + } + }); + }; +} + + diff --git a/src/styles/footnotes-fix.css b/src/styles/footnotes-fix.css new file mode 100644 index 0000000..030da6e --- /dev/null +++ b/src/styles/footnotes-fix.css @@ -0,0 +1,9 @@ +/* +Astro's markdown engine hides the footnotes heading completely with `.sr-only` +*/ +section.footnotes h2.sr-only { + position: relative; + width: auto; + height: auto; + clip: unset; +} \ No newline at end of file diff --git a/src/styles/pixelated-logo.css b/src/styles/pixelated-logo.css new file mode 100644 index 0000000..d8075fa --- /dev/null +++ b/src/styles/pixelated-logo.css @@ -0,0 +1,3 @@ +.site-title img { + image-rendering: pixelated; +} \ No newline at end of file diff --git a/src/styles/theme.css b/src/styles/theme.css new file mode 100644 index 0000000..471e202 --- /dev/null +++ b/src/styles/theme.css @@ -0,0 +1,32 @@ +/* https://starlight.astro.build/guides/css-and-tailwind/#color-theme-editor */ + +/* Dark mode colors. */ +:root { + --sl-color-accent-low: #351e00; + --sl-color-accent: #925c00; + --sl-color-accent-high: #efbf88; + --sl-color-white: #ffffff; + --sl-color-gray-1: #eceef2; + --sl-color-gray-2: #c0c2c7; + --sl-color-gray-3: #888b96; + --sl-color-gray-4: #545861; + --sl-color-gray-5: #353841; + --sl-color-gray-6: #24272f; + --sl-color-black: #17181c; +} + +/* Light mode colors. */ +:root[data-theme='light'] { + --sl-color-accent-low: #f4d0a7; + --sl-color-accent: #955e00; + --sl-color-accent-high: #482b00; + --sl-color-white: #17181c; + --sl-color-gray-1: #24272f; + --sl-color-gray-2: #353841; + --sl-color-gray-3: #545861; + --sl-color-gray-4: #888b96; + --sl-color-gray-5: #c0c2c7; + --sl-color-gray-6: #eceef2; + --sl-color-gray-7: #f5f6f8; + --sl-color-black: #ffffff; +} \ No newline at end of file