From 02147e7d251077ddecc6c5d36bf0a52f5a460d0e Mon Sep 17 00:00:00 2001
From: Hong-Phuc Bui <hong-phuc.bui@htwsaar.de>
Date: Fri, 16 Oct 2026 19:17:49 +0200
Subject: [PATCH] Commit Datum: 2026-10-16T19:17:49+02:00
---
codeberg.page/kurswinkel/deploy.sh | 20 ++++++
codeberg.page/kurswinkel/division.c | 7 ++
codeberg.page/kurswinkel/division.py | 0
codeberg.page/kurswinkel/tangente.js | 117 +++++++++++++++++++++++++++++++++++++++
01-intro-url-path/index.html | 2
codeberg.page/kurswinkel/index.html | 16 +++++
01-intro-url-path/tangente.js | 12 ++-
7 files changed, 168 insertions(+), 6 deletions(-)
diff --git a/01-intro-url-path/index.html b/01-intro-url-path/index.html
index 6aced1d..049caf9 100644
--- a/01-intro-url-path/index.html
+++ b/01-intro-url-path/index.html
@@ -9,7 +9,7 @@
</head>
<body>
-<h1>Fluglinien mit Kurzwinkel</h1>
+<h1>Fluglinien mit Kurswinkel</h1>
<div id="box" class="jxgbox" style="width:950px; aspect-ratio: 1/1;"></div>
<script src="tangente.js"></script>
</body>
diff --git a/01-intro-url-path/tangente.js b/01-intro-url-path/tangente.js
index 8bb5d5c..8aae1d3 100644
--- a/01-intro-url-path/tangente.js
+++ b/01-intro-url-path/tangente.js
@@ -1,6 +1,3 @@
-const RADIUS = 6;
-const BOARD_SIZE = 14;
-
const toXYZ = (longitude, latitude) => {
const lon = (longitude * Math.PI) / 180;
const lat = (latitude * Math.PI) / 180;
@@ -49,6 +46,10 @@
}
+// board commands
+const RADIUS = 6;
+const BOARD_SIZE = 14;
+
const board = JXG.JSXGraph.initBoard(
'box', {
boundingbox: [-BOARD_SIZE, BOARD_SIZE, BOARD_SIZE, -BOARD_SIZE],
@@ -56,7 +57,7 @@
});
const bound = [-10, 10];
const view = board.create('view3d',
- [[-8, -8], [15, 15],
+ [[-10, -10], [19, 19],
[bound, bound, bound]],
{
axesPosition: 'none',
@@ -112,4 +113,5 @@
const meridianNormalVector = normalVector(TANGENT_COORDINATE, NORTH_POLE);
const meridianPlan = view.create('circle3d', [origin, meridianNormalVector, RADIUS]);
-const projectionLine = view.create('line3d', [targetPoint, toXYZ(...TANGENT_COORDINATE), [-Infinity, Infinity] ]);
\ No newline at end of file
+const projectionLine = view.create('line3d', [targetPoint, toXYZ(...TANGENT_COORDINATE), [0, Infinity] ]);
+const ot = view.create('line3d', [origin, tangentPoint])
\ No newline at end of file
diff --git a/codeberg.page/kurswinkel/deploy.sh b/codeberg.page/kurswinkel/deploy.sh
new file mode 100755
index 0000000..1eabed6
--- /dev/null
+++ b/codeberg.page/kurswinkel/deploy.sh
@@ -0,0 +1,20 @@
+sync_git() {
+ SRC=$1
+ DEST=$2
+ mkdir -p $DEST
+ rsync -aHAXxv --numeric-ids --delete --progress --exclude='.git' \
+ --exclude='.gitignore' \
+ --exclude='*/target' \
+ --exclude='abgabe.sh' \
+ --exclude='.venv' \
+ --exclude='site' \
+ --exclude="'${abgabe_zip}.zip'" \
+ $SRC $DEST
+
+ git -C $DEST add .
+ git -C $DEST commit -a -m "Commit Datum: $(date --iso-8601=seconds)"
+ git -C $DEST push origin main
+
+}
+
+sync_git ./ ../codeberg.page/kurswinkel
\ No newline at end of file
diff --git a/codeberg.page/kurswinkel/division.c b/codeberg.page/kurswinkel/division.c
new file mode 100644
index 0000000..451130c
--- /dev/null
+++ b/codeberg.page/kurswinkel/division.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main() {
+ int x = 11 / (-7);
+ printf("%d\n",x);
+ return 0;
+}
diff --git a/codeberg.page/kurswinkel/division.py b/codeberg.page/kurswinkel/division.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/codeberg.page/kurswinkel/division.py
diff --git a/codeberg.page/kurswinkel/index.html b/codeberg.page/kurswinkel/index.html
new file mode 100644
index 0000000..049caf9
--- /dev/null
+++ b/codeberg.page/kurswinkel/index.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Index</title>
+ <script src="https://cdn.jsdelivr.net/npm/jsxgraph/distrib/jsxgraphcore.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="https://cdn.jsdelivr.net/npm/jsxgraph/distrib/jsxgraph.css">
+
+</head>
+<body>
+<h1>Fluglinien mit Kurswinkel</h1>
+<div id="box" class="jxgbox" style="width:950px; aspect-ratio: 1/1;"></div>
+<script src="tangente.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/codeberg.page/kurswinkel/tangente.js b/codeberg.page/kurswinkel/tangente.js
new file mode 100644
index 0000000..8aae1d3
--- /dev/null
+++ b/codeberg.page/kurswinkel/tangente.js
@@ -0,0 +1,117 @@
+const toXYZ = (longitude, latitude) => {
+ const lon = (longitude * Math.PI) / 180;
+ const lat = (latitude * Math.PI) / 180;
+
+ const x = RADIUS * Math.cos(lat) * Math.cos(lon);
+ const y = RADIUS * Math.cos(lat) * Math.sin(lon);
+ const z = RADIUS * Math.sin(lat);
+
+ return [x, y, z];
+};
+
+const toHomogeneousXYZ = (longitude, latitude) => {
+ const xyz = toXYZ(longitude, latitude);
+ xyz.unshift(0);
+ return xyz;
+}
+
+const toLonLat = (x, y, z) => {
+ const R = Math.hypot(x, y, z);
+ const longitude = (Math.atan2(y, x) * 180) / Math.PI; // [-180, 180]
+ const latitude = (Math.asin(Math.max(-1, Math.min(1, z / R))) * 180) / Math.PI; // [-90, 90]
+ return [longitude, latitude];
+};
+
+
+const cross = (a, b) => [
+ a[1] * b[2] - a[2] * b[1],
+ a[2] * b[0] - a[0] * b[2],
+ a[0] * b[1] - a[1] * b[0],
+];
+
+const normalVector = ([lon1, lat1], [lon2, lat2], normalize = false) => {
+ const n = cross(toXYZ(lon1, lat1), toXYZ(lon2, lat2));
+ if (!normalize) return n;
+
+ const len = Math.hypot(...n);
+ if (len < 1e-12) return null; // points are parallel or antipodal: no unique normal
+ const m = n.map(c => c / len);
+ m.unshift(0)
+ return m;
+}
+
+
+const toGeographicLabel = (lon, lat) => {
+ return `${ lon.toFixed(1) }°|${ lat.toFixed(1)}°`;
+}
+
+
+// board commands
+const RADIUS = 6;
+const BOARD_SIZE = 14;
+
+const board = JXG.JSXGraph.initBoard(
+ 'box', {
+ boundingbox: [-BOARD_SIZE, BOARD_SIZE, BOARD_SIZE, -BOARD_SIZE],
+ //axis: true
+ });
+const bound = [-10, 10];
+const view = board.create('view3d',
+ [[-10, -10], [19, 19],
+ [bound, bound, bound]],
+ {
+ axesPosition: 'none',
+ xPlaneRear: {visible: true},
+ yPlaneRear: {visible: true},
+ zPlaneRear: {visible: true},
+ //
+ az: { slider: { visible: true } },
+ el: { slider: { visible: true } },
+ bank: { slider: { visible: true } },
+ }
+);
+
+const origin = view.create('point3d', [0,0,0], {name:"O", fixed: true});
+const earth = view.create('sphere3d', [origin, RADIUS]);
+
+const NORTH_POLE = [0, 90];
+const north_pole = toHomogeneousXYZ(...NORTH_POLE);
+const equator = view.create('circle3d', [origin, north_pole, RADIUS], {
+ strokeColor:"red", fixed: true
+});
+const northPoint = view.create('point3d', [toXYZ(...NORTH_POLE)], {
+ name:'N', fixed: true, highlight: true, showInfobox: false,
+});
+
+
+const prime_meridian_normal = toHomogeneousXYZ(90, 0)
+const prime_meridian = view.create('circle3d', [origin, prime_meridian_normal, RADIUS], {
+ strokeColor: "blue",
+ fixed: true
+});
+
+const TANGENT_COORDINATE = [-30, 60]
+const tangentPoint = view.create('point3d', [toXYZ(...TANGENT_COORDINATE)], {
+ id:'T', fixed: true, highlight: true, showInfobox: false,
+});
+tangentPoint.element2D.label.setText( () => "T = " + toGeographicLabel( ...toLonLat(tangentPoint.X(),tangentPoint.Y(), tangentPoint.Z() ) ) );
+
+const tangentPlan = view.create('circle3d',
+ [tangentPoint, () => [0, tangentPoint.X(), tangentPoint.Y(), tangentPoint.Z()], RADIUS],
+ {fillColor:"red", fillOpacity:0.25, fixed: true}
+);
+
+const TARGET_COORDINATE = [120, 0];
+const targetPoint = view.create('point3d', [toXYZ(...TARGET_COORDINATE)], {
+ id: 't', name:toGeographicLabel(...TARGET_COORDINATE), fixed: true, highlight: true, showInfobox: false,
+});
+
+
+const routeNormalVector = normalVector(TANGENT_COORDINATE, TARGET_COORDINATE);
+const route = view.create('circle3d', [origin, routeNormalVector, RADIUS] );
+
+const meridianNormalVector = normalVector(TANGENT_COORDINATE, NORTH_POLE);
+const meridianPlan = view.create('circle3d', [origin, meridianNormalVector, RADIUS]);
+
+const projectionLine = view.create('line3d', [targetPoint, toXYZ(...TANGENT_COORDINATE), [0, Infinity] ]);
+const ot = view.create('line3d', [origin, tangentPoint])
\ No newline at end of file
--
Gitblit v1.10.0