Compare commits

..

1 Commits

Author SHA1 Message Date
Anton Pogrebnjak
422ba01b31 Some old drafts 2025-09-09 20:59:03 +02:00
19 changed files with 705 additions and 5168 deletions

View File

@@ -4,7 +4,6 @@ import mdx from '@astrojs/mdx';
import remarkMath from 'remark-math' import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex' import rehypeKatex from 'rehype-katex'
import sitemap from '@astrojs/sitemap'; import sitemap from '@astrojs/sitemap';
import { typst } from 'astro-typst';
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
@@ -16,5 +15,5 @@ export default defineConfig({
integrations: [mdx({ integrations: [mdx({
syntaxHighlight: 'shiki', syntaxHighlight: 'shiki',
shikiConfig: { theme: "dracula" }, shikiConfig: { theme: "dracula" },
}), sitemap(), typst()], }), sitemap()],
}); });

2229
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,12 +9,11 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^4.3.13", "@astrojs/mdx": "^4.3.5",
"@astrojs/rss": "^4.0.15", "@astrojs/rss": "^4.0.12",
"@astrojs/sitemap": "^3.7.0", "@astrojs/sitemap": "^3.5.1",
"@astrojs/vue": "^5.1.4", "@astrojs/vue": "^5.1.1",
"astro": "^5.17.3", "astro": "^5.13.7",
"astro-typst": "^0.12.1",
"rehype-katex": "^7.0.1", "rehype-katex": "^7.0.1",
"remark-math": "^6.0.0" "remark-math": "^6.0.0"
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

View File

@@ -1,11 +1,25 @@
--- ---
const today = new Date(); const today = new Date();
import Socials from "./Socials.astro";
--- ---
<footer> <footer>
&copy; {today.getFullYear()} <a href="/about">Anton</a>. All rights reserved. &copy; {today.getFullYear()} <a href="/about">Anton Pogrebnjak</a>. All rights reserved.
<Socials /> <div class="social-links">
<a href="https://github.com/Pantonius" target="_blank">
<span class="sr-only">Go to my GitHub repo</span>
<svg
viewBox="0 0 16 16"
aria-hidden="true"
width="32"
height="32"
astro-icon="social/github"
><path
fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
></path></svg
>
</a>
</div>
</footer> </footer>
<style> <style>
footer { footer {
@@ -14,6 +28,12 @@ import Socials from "./Socials.astro";
width: 100%; width: 100%;
} }
.social-links {
display: flex;
justify-content: center;
gap: 1em;
margin-top: 1em;
}
.social-links a { .social-links a {
text-decoration: none; text-decoration: none;
color: var(--text); color: var(--text);

View File

@@ -1,25 +0,0 @@
<div id="map" style="height: 400px;">
</div>
<script>
let map = L.map('map').setView([47.689749, 9.187857], 16);
L.tileLayer('https://sgx.geodatenzentrum.de/wmts_basemapde/tile/1.0.0/de_basemapde_web_raster_grau/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png', {
minZoom: 0,
maxZoom: 20,
attribution: 'Map data: &copy; <a href="http://www.govdata.de/dl-de/by-2-0">dl-de/by-2-0</a>',
ext: 'png'
}).addTo(map);
let geojson = await fetch('/geojson/freiraum/uni_konstanz.geojson', {
method: 'GET',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json());
let geoLayer = L.geoJson(geojson, {
style: { fillColor: 'rgba(18, 174, 225, .2)', fillOpacity: 1, stroke: true, color: 'rgba(18, 174, 225, .6)' },
}).addTo(map);
</script>

View File

@@ -1,7 +1,6 @@
--- ---
import { ClientRouter } from "astro:transitions"; import { ClientRouter } from "astro:transitions";
import HeaderLink from "./HeaderLink.astro"; import HeaderLink from "./HeaderLink.astro";
import Socials from "./Socials.astro";
--- ---
<header> <header>
@@ -13,8 +12,22 @@ import Socials from "./Socials.astro";
<HeaderLink href="/">Home</HeaderLink> <HeaderLink href="/">Home</HeaderLink>
<HeaderLink href="/projects">Projects</HeaderLink> <HeaderLink href="/projects">Projects</HeaderLink>
<HeaderLink href="/blog">Blog</HeaderLink> <HeaderLink href="/blog">Blog</HeaderLink>
</div> </div>
<Socials /> <div class="social-links">
<a href="https://github.com/Pantonius" target="_blank">
<span class="sr-only">Go to my GitHub repo</span>
<svg
viewBox="0 0 16 16"
aria-hidden="true"
width="32"
height="32"
><path
fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
></path></svg
>
</a>
</div>
</nav> </nav>
</header> </header>
@@ -59,6 +72,10 @@ import Socials from "./Socials.astro";
border-bottom-color: var(--primary); border-bottom-color: var(--primary);
} }
.social-links,
.social-links a {
display: flex;
}
@media (max-width: 720px) { @media (max-width: 720px) {
header .logo img { header .logo img {

View File

@@ -28,7 +28,6 @@ import { ClientRouter } from "astro:transitions";
document.addEventListener("mousemove", (e) => { document.addEventListener("mousemove", (e) => {
mouse.x = e.clientX; mouse.x = e.clientX;
mouse.y = e.clientY; mouse.y = e.clientY;
draw();
}); });
let distanceThreshold = .2; let distanceThreshold = .2;
@@ -67,5 +66,7 @@ import { ClientRouter } from "astro:transitions";
} }
}; };
draw(); setInterval(() => {
draw();
}, 1000 / 60);
</script> </script>

View File

@@ -78,7 +78,6 @@ const color = Astro.props.color || 'var(--text)';
margin: 0; margin: 0;
color: var(--color); color: var(--color);
line-height: 1; line-height: 1;
font-variant-caps: small-caps;
} }
.date { .date {
margin: 0; margin: 0;

View File

@@ -1,28 +0,0 @@
<div class="social-links">
<a href="https://github.com/Pantonius" target="_blank">
<span class="sr-only">Go to my GitHub repo</span>
<svg
viewBox="0 0 16 16"
aria-hidden="true"
width="32"
height="32"
><path
fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
></path></svg>
</a>
<a href="https://mastodon.social/@pantonius" target="_blank">
<span class="sr-only">Go to my Mastodon profile</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" width="46" height="46"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path fill="currentColor" d="M529 243.1C529 145.9 465.3 117.4 465.3 117.4C402.8 88.7 236.7 89 174.8 117.4C174.8 117.4 111.1 145.9 111.1 243.1C111.1 358.8 104.5 502.5 216.7 532.2C257.2 542.9 292 545.2 320 543.6C370.8 540.8 399.3 525.5 399.3 525.5L397.6 488.6C397.6 488.6 361.3 500 320.5 498.7C280.1 497.3 237.5 494.3 230.9 444.7C230.3 440.1 230 435.4 230 430.8C315.6 451.7 388.7 439.9 408.7 437.5C464.8 430.8 513.7 396.2 519.9 364.6C529.7 314.8 528.9 243.1 528.9 243.1zM453.9 368.3L407.3 368.3L407.3 254.1C407.3 204.4 343.3 202.5 343.3 261L343.3 323.5L297 323.5L297 261C297 202.5 233 204.4 233 254.1L233 368.3L186.3 368.3C186.3 246.2 181.1 220.4 204.7 193.3C230.6 164.4 284.5 162.5 308.5 199.4L320.1 218.9L331.7 199.4C355.8 162.3 409.8 164.6 435.5 193.3C459.2 220.6 453.9 246.3 453.9 368.3L453.9 368.3z"/></svg>
</a>
</div>
<style>
.social-links,
.social-links a {
display: flex;
justify-content: center;
align-items: center;
color: var(--text);
}
</style>

View File

@@ -1,21 +1,6 @@
import { glob } from 'astro/loaders'; import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content'; import { defineCollection, z } from 'astro:content';
const bachelor = defineCollection({
// Load Markdown and MDX files in the `src/content/blog/` directory.
loader: glob({ base: './src/content/bachelor', pattern: '**/*.{md,mdx}' }),
// Type-check frontmatter using a schema
schema: z.object({
title: z.string(),
description: z.string(),
part: z.number(),
// Transform string to Date object
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
}),
});
const blog = defineCollection({ const blog = defineCollection({
// Load Markdown and MDX files in the `src/content/blog/` directory. // Load Markdown and MDX files in the `src/content/blog/` directory.
loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }), loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
@@ -31,7 +16,7 @@ const blog = defineCollection({
}); });
const projects = defineCollection({ const projects = defineCollection({
// Load Markdown and MDX files in the `src/content/projects/` directory. // Load Markdown and MDX files in the `src/content/blog/` directory.
loader: glob({ loader: glob({
base: './src/content/projects', pattern: '**/*.{md,mdx}' base: './src/content/projects', pattern: '**/*.{md,mdx}'
}), }),
@@ -46,4 +31,4 @@ const projects = defineCollection({
}), }),
}); });
export const collections = { bachelor, blog, projects }; export const collections = { blog, projects };

View File

@@ -0,0 +1,105 @@
---
title: Computer Graphics - An Overview
pubDate: 2025-02-06T19:00:00Z
description: A brief overview of Computer Graphics
---
# Basics
Before we dive into the details of computer graphics, let us talk about some basic concepts all around light.
## Plenoptic Function
The plenoptic function describes all light rays at all points in space at any point in time.
![Plenoptic Function](/images/posts/computer-graphics/plenoptic_function.svg)
It operates in a 6-dimensional space consisting of
- Position: $V_x, V_y, V_z$
- Direction: $\Phi, \Theta$
- Time: $t$
In photography and film the time is fixed at each frame and the position is either fixed or follows from the time. Computer graphics often simulates that.
So the problem is reduced to a 2-dimensional space consisting simply of the directions $\Theta$ and $\Phi$.
## Global Illumination
$$
L(x, \omega) = L_e(x, \omega) + \int_\Omega f_r(x, \omega', \omega) L(x', \omega') cos(\omega', n) d\omega'
$$
- $L(x, \omega)$
: describes the light from an object $x$ in direction $\omega$
- $L_e(x, \omega)$
: light emission if x is a light source
- $f_r(x, \omega', \omega)$
: reflection function given an object $x$ and an incoming angle $\omega'$ and outgoing angle $\omega$.
- $cos(\omega', n)$ weakening factor; the greater the distance between the incident angle $\omega'$ away from the surface normal $n$, the greater the area that is lit and the weaker the light at a particular point
# Graphics Pipeline
# Geometry
We build geometry out of two distinct constructs: **points** and **vectors**.
![Points and Vectors](/images/posts/computer-graphics/points_vectors.svg)
**Points** are coordinates with respect to a coordinate origin
**Vectors** are movement statements from a point P to a point Q
## Vector Space $\mathbb{R}^n$
Contains **scalars** and **vectors** with...
### Vector Addition
$$
\begin{bmatrix}
v_1 \\
v_2 \\
\vdots \\
v_n
\end{bmatrix}
+
\begin{bmatrix}
w_1 \\
w_2 \\
\vdots \\
w_n
\end{bmatrix}
=
\begin{bmatrix}
v_1 + w_1 \\
v_2 + w_2 \\
\vdots \\
v_n + w_n
\end{bmatrix}
$$
### Scalar Multiplication
$$
a \cdot \begin{bmatrix}
v_1 \\
v_2 \\
\vdots \\
v_n
\end{bmatrix}
=
\begin{bmatrix}
a \cdot v_1 \\
a \cdot v_2 \\
\vdots \\
a \cdot v_n
\end{bmatrix}
$$
<br/>
<br/>
We encounter the following problems:
- there are **no coordinates**
- there are **no distances** or the like
## Affine Space $A^n$
Contains **scalars**, **vectors** and **points**.
For each pair of points $(P, Q)$ with $P, Q \in A^n$ there is a vector $v \in V^n$ such that $v$ points from $P$ to $Q$.
Elements of $A^n$ are **points**.
$0$ is the coordinate origin and $v = (OP)$ is the location vector for $P \in A^n$.
**Problem:** We still have no concept of lengths.

View File

@@ -1,75 +0,0 @@
---
title: Freiraum
pubDate: 2026-02-23T12:00:00Z
description: Freiraum is a room availability checker developed for the students of the University of Konstanz
heroImage: /images/posts/freiraum/homepage.png
---
import UKNMap from '../../components/Freiraum/UKNMap.astro';
Freiraum is a room availability checker developed for the students of the University of Konstanz. Much like the [Frag Wahltraut tool](../frag-wahltraut), it runs entirely on the client side. Meaning, the server has no real knowledge of any rooms in the university or their status. Instead, the client code fetches the data from a server, that is only available from within the university network.
# Background
During the lecture and exam periods, students are in need of viable working areas. Both for silent and group work. While the library is readily available for silent work, even its vast space can at times (in exam periods) reach full capacity. On the front of working areas for groups, the library is short on rooms that are sound isolated.
Thankfully, the university itself is much more than its library. Many rooms, that are used throughout the day will occassionally have some free spots, in which students can freely occupy the space and even use it effectively for group work without disturbing others.
While the university has been working on accommodating the students' need for working spaces, a real long-term solution hasn't left the planning phase (atleast that I am aware of).
However, anyone within the university network has access to a certain web service, providing the full planned occupancy of many rooms within the university.
# The Idea
The current occupancy tool is very inaccessible:
- it's only reachable via an IP-address
- its UI is very dense and hard to navigate
- if you are searching for any vacancies on a given time and day, you're out of luck -- you have to go through each room by hand and check its availability at that time
While a replacement is on its way, the student representation decided to leverage the current endpoint and build a tool that:
- is easy to navigate
- and provides the students with exactly the information they need:
<q>Which rooms are available throughout the day?</q>
# The Implementation
Freiraum mainly uses a timetable format with the rooms indicated by rows and the hours by columns. A vertical red indicator shows the current time over each row.
![](/images/posts/freiraum/homepage.png)
While lectures and other occupancies appear grayed-out, the computed free spots inbetween are rendered in a light blue shade, making current and future availabilities tangible at a single glance.
Each room and event can be clicked for a more detailed overview.
## Room Details
- the **kind of room** (auditorium, seminar, etc.),
- **its building**
- **its designation**
- **its capacity**
- other details like the availability of a projector, HDMI or VGA connection, blackboard, etc.
## Event Details
- the **kind of event** (lecture, seminar, etc.),
- **its title**,
- **the person that booked the slot**.
<br/>
The entire HTML of the timetable is generated via client-side javascript, which leads to pretty involved code, but gets the job done.
# Future Work / Other Ideas
An initial proof of concept also included a map view intended to give a visual queue of where the room is located. I later dismissed the idea for the time being because obtaining the shape and geo data for each room would have entaled a lot of manual work.
However, I learned that germany, and in fact the european union as well, provides some basic geo data for buildings, their area and roof shape, which is how I extracted this wonderful geojson shape data for each of the university buildings:
<UKNMap />
If anyone feels like it, some kind of navigation system might be fun to implement. Though I have heard that many have tried and failed miserably already.
Sticking with the timetable view, there is still room for filters and search. Possible queries could restrict the displayed rooms to only those of a certain size or kind (who actually wants to study in an auditorium when there is no lecture there?). Even the availability of a projector or blackboard could be filtered for or made directly visible through the use of icons (while trying not to overload the initial overview of the rooms).
# Final Notes
Apart from that, I am content with Freiraum in its current form. Part of its charme for me is its simplicity, though I am certain some people would disaggree. The code base is fairly easy to maintain, despite it being written in vanilla javascript (I seem to have a knack for that -- call me a masochist I guess). Often times I can quickly swoop in and change aspects of the UI or logic, without having to search all too long. Granted, I wrote the hecking thing. But the generation code for the actual HTML timetable is the only aspect that feels convoluted to me. All things considered, I feel certain that anyone can pick the code and adapt it to their will. In terms of performance and reliablity it seems to be robust enough that nobody has thrown tomatoes in my face -- yet.
The actual data endpoint for the room occupancy will move to the university's e-learning platform soon. As of now I have no clue wether the new version on the e-learning platform will provide a similarly accessible view of vacant rooms for students (I highly doubt it). Nor do I know if there is a similar API endpoint, that Freiraum can be attached to; Unless the IT department of the university provides one themselves, Freiraum will probably not be able to exist in its current way.
Whatever the future may hold, I am happy to have seen that it found use both by students and university employees. It turns out that the simplest of tools can make quite a difference :)

View File

@@ -32,8 +32,6 @@ const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05"
crossorigin="anonymous" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script> onload="renderMathInElement(document.body);"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<style> <style>
article { article {
width: 100%; width: 100%;

View File

@@ -14,7 +14,7 @@ import { SITE_TITLE, SITE_DESCRIPTION } from "../consts";
<body> <body>
<Header /> <Header />
<Main> <Main>
<h1>Anton</h1> <h1>Anton Pogrebnjak</h1>
<div style="max-width: 40rem"> <div style="max-width: 40rem">
<p> <p>
Really, I don't have much to tell you about myself. Just look at the amazing stuff I've done and written about. That should suffice. Really, I don't have much to tell you about myself. Just look at the amazing stuff I've done and written about. That should suffice.

View File

@@ -23,8 +23,8 @@ const posts: Post[] = (await getCollection("projects"))
<Main> <Main>
<section id="welcome"> <section id="welcome">
<h1>Hi &#128075;, my name is <a href="/about">Anton</a></h1> <h1>Hi &#128075;, my name is <a href="/about">Anton</a></h1>
<h2 class="typeout"> <h2 class="typeout">
Welcome to my realm! and I am passionate about a whole bunch of things
</h2> </h2>
<h3 class="buttons"> <h3 class="buttons">

View File

@@ -27,7 +27,6 @@
:root { :root {
--text: #ffffff; --text: #ffffff;
--text-soft: #ddd; --text-soft: #ddd;
--text-softer: #aaa;
--background: #121212; --background: #121212;
--background-soft: #212121; --background-soft: #212121;
--primary: #2df598; --primary: #2df598;
@@ -183,20 +182,6 @@ blockquote {
font-size: 1.333em; font-size: 1.333em;
} }
q {
display: block;
text-align: center;
font-weight: bold;
font-size: 1.7rem;
font-style: oblique;
margin: 2rem 0;
quotes: initial;
border: 2px solid var(--primary);
padding: 8px;
}
hr { hr {
border: none; border: none;
border-top: 1px solid var(--primary); border-top: 1px solid var(--primary);