Hong-Phuc Bui
2026-10-16 02147e7d251077ddecc6c5d36bf0a52f5a460d0e
Commit Datum: 2026-10-16T19:17:49+02:00
5 files added
2 files modified
174 ■■■■■ changed files
01-intro-url-path/index.html 2 ●●●●● patch | view | raw | blame | history
01-intro-url-path/tangente.js 12 ●●●●● patch | view | raw | blame | history
codeberg.page/kurswinkel/deploy.sh 20 ●●●●● patch | view | raw | blame | history
codeberg.page/kurswinkel/division.c 7 ●●●●● patch | view | raw | blame | history
codeberg.page/kurswinkel/division.py patch | view | raw | blame | history
codeberg.page/kurswinkel/index.html 16 ●●●●● patch | view | raw | blame | history
codeberg.page/kurswinkel/tangente.js 117 ●●●●● patch | view | raw | blame | history
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>
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] ]);
const projectionLine = view.create('line3d', [targetPoint, toXYZ(...TANGENT_COORDINATE),  [0, Infinity] ]);
const ot = view.create('line3d', [origin, tangentPoint])
codeberg.page/kurswinkel/deploy.sh
New file
@@ -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
codeberg.page/kurswinkel/division.c
New file
@@ -0,0 +1,7 @@
#include <stdio.h>
int main() {
    int x = 11 / (-7);
    printf("%d\n",x);
    return 0;
}
codeberg.page/kurswinkel/division.py
codeberg.page/kurswinkel/index.html
New file
@@ -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>
codeberg.page/kurswinkel/tangente.js
New file
@@ -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])