{"id":1927,"date":"2026-04-13T06:48:34","date_gmt":"2026-04-13T04:48:34","guid":{"rendered":"https:\/\/cad-kompass.de\/?p=1927"},"modified":"2026-06-26T17:48:26","modified_gmt":"2026-06-26T15:48:26","slug":"klothoiden-explainer","status":"publish","type":"post","link":"https:\/\/cad-kompass.de\/?p=1927","title":{"rendered":"Klothoiden-Explainer"},"content":{"rendered":"\n<style>\n    .kl-box {\n        --kl-primary: #3f5f75;\n        --kl-primary-dark: #2c4a5e;\n        --kl-primary-deep: #1e3548;\n        --kl-accent: #e8913a;\n        --kl-arc: #059669;\n        --kl-ink: #1e293b;\n        --kl-text: #334155;\n        --kl-muted: #64748b;\n        --kl-faint: #94a3b8;\n        --kl-border: #c8d6e0;\n        --kl-surface: #f7f9fb;\n        border: 3px solid var(--kl-primary);\n        border-radius: 8px;\n        margin: 28px 0;\n        overflow: hidden;\n        font-family: inherit;\n        color: var(--kl-text);\n        line-height: 1.55;\n    }\n    .kl-box *, .kl-box *::before, .kl-box *::after { box-sizing: border-box; }\n\n    .kl-header {\n        background: linear-gradient(135deg, var(--kl-primary-deep) 0%, var(--kl-primary-dark) 100%);\n        padding: 20px 28px 18px;\n        position: relative;\n    }\n    .kl-header::after {\n        content: '';\n        position: absolute;\n        left: 0; right: 0; bottom: 0;\n        height: 3px;\n        background: repeating-linear-gradient(90deg, var(--kl-primary) 0px, var(--kl-primary) 8px, transparent 8px, transparent 12px);\n    }\n    .kl-header-top { display: flex; align-items: center; gap: 14px; }\n    .kl-header-icon { width: 36px; height: 36px; flex-shrink: 0; }\n    .kl-box-title { font-size: 1.15rem; color: #fff; font-weight: 700; margin: 0; }\n    .kl-box-desc { font-size: 0.85rem; color: rgba(255,255,255,0.65); margin: 6px 0 0; }\n\n    .kl-body { padding: 22px 28px 24px; }\n\n    .kl-privacy {\n        background: #f0fdf4;\n        border: 1px solid #bbf7d0;\n        border-radius: 4px;\n        padding: 10px 16px 10px 40px;\n        margin-bottom: 20px;\n        font-size: 0.82rem;\n        color: #15803d;\n        position: relative;\n    }\n    .kl-privacy::before {\n        content: '\\1F512';\n        position: absolute; left: 14px; top: 50%; transform: translateY(-50%);\n        font-size: 1rem;\n    }\n\n    .kl-controls {\n        display: grid;\n        grid-template-columns: 1fr 1fr;\n        gap: 16px 22px;\n        padding: 16px 18px;\n        background: var(--kl-surface);\n        border: 1px solid var(--kl-border);\n        border-radius: 4px;\n        margin-bottom: 18px;\n    }\n    .kl-control label { display: block; font-size: 0.82rem; font-weight: 600; color: var(--kl-primary); margin-bottom: 6px; }\n    .kl-box .kl-control input[type=\"range\"] {\n        -webkit-appearance: none !important;\n        -moz-appearance: none !important;\n        appearance: none !important;\n        width: 100% !important;\n        height: 6px !important;\n        padding: 0 !important;\n        margin: 10px 0 !important;\n        background: #dbe4ec !important;\n        border: 0 !important;\n        border-radius: 3px !important;\n        outline: none !important;\n        box-shadow: none !important;\n        box-sizing: border-box !important;\n    }\n    .kl-box .kl-control input[type=\"range\"]::-webkit-slider-runnable-track {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        height: 6px !important;\n        background: transparent !important;\n        border: 0 !important;\n        box-shadow: none !important;\n    }\n    .kl-box .kl-control input[type=\"range\"]::-webkit-slider-thumb {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        width: 18px !important;\n        height: 18px !important;\n        border-radius: 50% !important;\n        background: #3f5f75 !important;\n        border: 2px solid #fff !important;\n        box-shadow: 0 1px 3px rgba(0,0,0,0.2) !important;\n        margin-top: -6px !important;\n        cursor: pointer !important;\n    }\n    .kl-box .kl-control input[type=\"range\"]::-moz-range-track {\n        height: 6px !important;\n        background: transparent !important;\n        border: 0 !important;\n        box-shadow: none !important;\n    }\n    .kl-box .kl-control input[type=\"range\"]::-moz-range-thumb {\n        -moz-appearance: none !important;\n        appearance: none !important;\n        width: 18px !important;\n        height: 18px !important;\n        border-radius: 50% !important;\n        background: #3f5f75 !important;\n        border: 2px solid #fff !important;\n        box-shadow: 0 1px 3px rgba(0,0,0,0.2) !important;\n        cursor: pointer !important;\n    }\n    .kl-box .kl-control input[type=\"range\"]::-moz-focus-outer { border: 0 !important; }\n    .kl-control .kl-value { font-size: 0.78rem; color: var(--kl-muted); text-align: right; margin-top: 2px; }\n    .kl-input-row {\n        display: flex;\n        align-items: center;\n        justify-content: flex-end;\n        gap: 6px;\n        margin-top: 4px;\n    }\n    .kl-input-label { font-size: 0.82rem; color: var(--kl-muted); font-weight: 600; }\n    .kl-input-unit { font-size: 0.82rem; color: var(--kl-muted); }\n    .kl-input-row input[type=\"number\"] {\n        width: 80px;\n        padding: 5px 6px 5px 10px;\n        font-size: 0.88rem;\n        font-family: inherit;\n        color: var(--kl-ink);\n        background: #fff;\n        border: 1px solid var(--kl-border);\n        border-radius: 3px;\n        text-align: right;\n        box-sizing: border-box;\n    }\n    .kl-input-row input[type=\"number\"]:focus {\n        outline: none;\n        border-color: var(--kl-primary);\n        box-shadow: 0 0 0 2px rgba(63, 95, 117, 0.15);\n    }\n\n    .kl-stage-title {\n        font-size: 0.78rem;\n        font-weight: 700;\n        color: var(--kl-muted);\n        text-transform: uppercase;\n        letter-spacing: 0.06em;\n        margin: 4px 0 8px;\n    }\n\n    .kl-canvas-wrap {\n        border: 1px solid var(--kl-border);\n        border-radius: 4px;\n        background: #fff;\n        overflow: hidden;\n    }\n    .kl-canvas-wrap.kl-main { aspect-ratio: 2 \/ 1; }\n    .kl-canvas-wrap.kl-curv { aspect-ratio: 10 \/ 3; }\n    .kl-canvas-wrap canvas { width: 100%; height: 100%; display: block; }\n\n    .kl-legend {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 8px;\n        padding: 12px 0 4px;\n    }\n    .kl-legend-btn {\n        display: inline-flex;\n        align-items: center;\n        gap: 10px;\n        padding: 7px 12px;\n        border: 1px solid var(--kl-border);\n        border-radius: 4px;\n        background: #fff;\n        cursor: pointer;\n        user-select: none;\n        transition: background 0.15s, border-color 0.15s, opacity 0.15s;\n        font-size: 0.82rem;\n        font-family: inherit;\n        color: var(--kl-text);\n    }\n    .kl-legend-btn:hover { border-color: var(--kl-primary); background: #fafbfc; }\n    .kl-legend-btn.off { opacity: 0.38; }\n    .kl-legend-btn::before {\n        content: '';\n        display: inline-block;\n        width: 12px;\n        height: 12px;\n        border: 1.5px solid var(--kl-primary);\n        border-radius: 2px;\n        background: var(--kl-primary);\n        flex-shrink: 0;\n        position: relative;\n    }\n    .kl-legend-btn.off::before {\n        background: #fff;\n    }\n    .kl-sw {\n        display: inline-block;\n        width: 26px;\n        height: 3px;\n        border-radius: 2px;\n        flex-shrink: 0;\n    }\n    .kl-sw-gerade { background: #3f5f75; }\n    .kl-sw-kloth  { background: #e8913a; }\n    .kl-sw-arc    { background: #059669; }\n    .kl-sw.dashed {\n        background: transparent;\n        border-top: 3px dashed currentColor;\n        height: 0;\n    }\n    .kl-sw-knick { color: #dc2626; }\n    .kl-sw-bigr  { color: #7c3aed; }\n    .kl-legend-name { font-weight: 600; color: var(--kl-ink); }\n    .kl-legend-val { color: var(--kl-muted); font-size: 0.76rem; white-space: nowrap; }\n    .kl-legend-section {\n        font-size: 0.72rem;\n        font-weight: 700;\n        color: var(--kl-muted);\n        text-transform: uppercase;\n        letter-spacing: 0.06em;\n        width: 100%;\n        margin: 10px 0 2px;\n    }\n    .kl-legend-section:first-child { margin-top: 0; }\n\n    .kl-formula {\n        background: #fff7ed;\n        border: 1px solid #fed7aa;\n        border-left: 3px solid var(--kl-accent);\n        border-radius: 4px;\n        padding: 12px 18px;\n        margin: 18px 0 20px;\n        font-size: 0.92rem;\n        text-align: center;\n        color: var(--kl-ink);\n    }\n    .kl-formula strong { color: var(--kl-accent); }\n\n    .kl-info h3 { font-size: 0.95rem; font-weight: 700; color: var(--kl-ink); margin: 22px 0 8px; }\n    .kl-info p { font-size: 0.88rem; line-height: 1.75; color: var(--kl-text); margin: 0 0 12px; }\n\n    @media (max-width: 900px) {\n        .kl-header { padding: 16px 18px 14px; }\n        .kl-body { padding: 18px 16px 20px; }\n        .kl-controls { grid-template-columns: 1fr; gap: 14px; }\n    }\n<\/style>\n\n<div class=\"kl-box\">\n\n    <div class=\"kl-header\">\n        <div class=\"kl-header-top\">\n            <svg class=\"kl-header-icon\" viewBox=\"0 0 36 36\" fill=\"none\">\n                <line x1=\"3\" y1=\"26\" x2=\"12\" y2=\"26\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\n                <path d=\"M12 26 C 18 26, 22 22, 24 14\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-dasharray=\"3 2\"\/>\n                <path d=\"M24 14 Q 28 6, 33 5\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\"\/>\n                <circle cx=\"12\" cy=\"26\" r=\"1.8\" fill=\"rgba(255,255,255,0.9)\"\/>\n                <circle cx=\"24\" cy=\"14\" r=\"1.8\" fill=\"rgba(255,255,255,0.9)\"\/>\n            <\/svg>\n            <div>\n                <h2 class=\"kl-box-title\">Klothoiden-Explainer<\/h2>\n                <div class=\"kl-box-desc\">Interaktiver &Uuml;bergangsbogen zwischen Gerade und Kreisbogen &ndash; mit A-Parameter, Radius, Kr&uuml;mmungsband und Vergleichsgeometrien zum An- und Abschalten.<\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div class=\"kl-body\">\n\n        <div class=\"kl-privacy\">Dieses Tool l&auml;uft komplett im Browser. Keine Daten werden gesendet.<\/div>\n\n        <div class=\"kl-controls\">\n            <div class=\"kl-control\">\n                <label>A-Parameter (Klothoidenparameter)<\/label>\n                <input type=\"range\" id=\"klParamA\" min=\"20\" max=\"300\" value=\"100\">\n                <div class=\"kl-input-row\">\n                    <span class=\"kl-input-label\">A =<\/span>\n                    <input type=\"number\" id=\"klInputA\" min=\"10\" max=\"1000\" step=\"1\" value=\"100\">\n                <\/div>\n            <\/div>\n            <div class=\"kl-control\">\n                <label>Radius R (Kreisbogen, in Metern)<\/label>\n                <input type=\"range\" id=\"klParamR\" min=\"50\" max=\"500\" value=\"200\">\n                <div class=\"kl-input-row\">\n                    <span class=\"kl-input-label\">R =<\/span>\n                    <input type=\"number\" id=\"klInputR\" min=\"10\" max=\"3000\" step=\"1\" value=\"200\">\n                    <span class=\"kl-input-unit\">m<\/span>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"kl-stage-title\">Geometrie in der Draufsicht<\/div>\n        <div class=\"kl-canvas-wrap kl-main\">\n            <canvas id=\"klCanvas\" width=\"800\" height=\"400\"><\/canvas>\n        <\/div>\n\n        <div class=\"kl-legend\">\n            <div class=\"kl-legend-section\">Grundgeometrie<\/div>\n            <button type=\"button\" class=\"kl-legend-btn\" data-id=\"gerade\">\n                <span class=\"kl-sw kl-sw-gerade\"><\/span>\n                <span class=\"kl-legend-name\">Gerade<\/span>\n                <span class=\"kl-legend-val\">R = &infin;<\/span>\n            <\/button>\n            <button type=\"button\" class=\"kl-legend-btn\" data-id=\"kloth\">\n                <span class=\"kl-sw kl-sw-kloth\"><\/span>\n                <span class=\"kl-legend-name\">Klothoide<\/span>\n                <span class=\"kl-legend-val\" id=\"klValL\">L = 50,0 m<\/span>\n            <\/button>\n            <button type=\"button\" class=\"kl-legend-btn\" data-id=\"arc\">\n                <span class=\"kl-sw kl-sw-arc\"><\/span>\n                <span class=\"kl-legend-name\">Kreisbogen<\/span>\n                <span class=\"kl-legend-val\" id=\"klValR2\">R = 200 m<\/span>\n            <\/button>\n\n            <div class=\"kl-legend-section\">Vergleichsgeometrie (optional)<\/div>\n            <button type=\"button\" class=\"kl-legend-btn off\" data-id=\"knick\">\n                <span class=\"kl-sw dashed kl-sw-knick\"><\/span>\n                <span class=\"kl-legend-name\">Ohne &Uuml;bergang (Knick)<\/span>\n                <span class=\"kl-legend-val\">Gerade direkt in Kreisbogen<\/span>\n            <\/button>\n            <button type=\"button\" class=\"kl-legend-btn off\" data-id=\"bigr\">\n                <span class=\"kl-sw dashed kl-sw-bigr\"><\/span>\n                <span class=\"kl-legend-name\">Nur gr&ouml;&szlig;erer Radius<\/span>\n                <span class=\"kl-legend-val\">1,5&times;R statt Klothoide<\/span>\n            <\/button>\n        <\/div>\n\n        <div class=\"kl-formula\" id=\"klFormula\">\n            <strong>A&sup2; = R &times; L<\/strong> &nbsp;&rarr;&nbsp; 100&sup2; = 200 &times; 50,0 &nbsp;&rarr;&nbsp; L = <strong>50,0 m<\/strong>\n        <\/div>\n\n        <div class=\"kl-stage-title\">Kr&uuml;mmungsband (1\/R &uuml;ber Bogenl&auml;nge)<\/div>\n        <div class=\"kl-canvas-wrap kl-curv\">\n            <canvas id=\"klCurvature\" width=\"800\" height=\"240\"><\/canvas>\n        <\/div>\n\n        <div class=\"kl-info\">\n            <h3>Was ist eine Klothoide?<\/h3>\n            <p>Eine Klothoide ist eine Spiralkurve, deren Kr&uuml;mmung linear mit der Bogenl&auml;nge zunimmt. Im Stra&szlig;enbau wird sie als &Uuml;bergangsbogen zwischen einer Geraden (Kr&uuml;mmung = 0) und einem Kreisbogen (Kr&uuml;mmung = 1\/R) eingesetzt. Der Fahrer erlebt dadurch einen gleichm&auml;&szlig;igen Lenkeinschlag statt eines abrupten Richtungswechsels.<\/p>\n\n            <h3>Was bedeutet der A-Parameter?<\/h3>\n            <p>Der A-Parameter (auch Klothoidenparameter) beschreibt, wie schnell die Kr&uuml;mmung zunimmt. Gro&szlig;es A: langsamer Kr&uuml;mmungsanstieg, langer &Uuml;bergangsbogen, sanfter &Uuml;bergang. Kleines A: schneller Kr&uuml;mmungsanstieg, kurzer &Uuml;bergangsbogen, strafferer &Uuml;bergang. Die Beziehung lautet A&sup2; = R &times; L, wobei R der Radius am Ende der Klothoide und L die Bogenl&auml;nge ist.<\/p>\n\n            <h3>Warum &Uuml;bergangsb&ouml;gen?<\/h3>\n            <p>Ohne &Uuml;bergangsbogen springt die Kr&uuml;mmung an der Verbindungsstelle von Gerade und Kreisbogen schlagartig von 0 auf 1\/R. Fahrdynamisch bedeutet das eine pl&ouml;tzliche Querbeschleunigung. Das Fahrzeug &bdquo;reisst&ldquo; in die Kurve. Mit einer Klothoide steigt die Kr&uuml;mmung linear an &ndash; das Kr&uuml;mmungsband unten zeigt den Unterschied direkt, wenn man den Vergleich <em>Ohne &Uuml;bergang<\/em> aktiviert: eine Stufe statt einer Rampe.<\/p>\n        <\/div>\n\n    <\/div>\n<\/div>\n\n<script>\n(function() {\n    var state = { gerade: true, kloth: true, arc: true, knick: false, bigr: false };\n    var COLORS = {\n        gerade: '#3f5f75',\n        kloth:  '#e8913a',\n        arc:    '#059669',\n        knick:  '#dc2626',\n        bigr:   '#7c3aed'\n    };\n    var MAX_CURV = 1 \/ 50; \/\/ feste y-Skala im Kr\u00fcmmungsband (engster m\u00f6glicher R)\n\n    var canvas = document.getElementById('klCanvas');\n    var ctx = canvas.getContext('2d');\n    var curvCanvas = document.getElementById('klCurvature');\n    var ctxC = curvCanvas.getContext('2d');\n\n    function fitCanvas(cnv) {\n        var rect = cnv.getBoundingClientRect();\n        if (rect.width < 10 || rect.height < 10) return false;\n        var dw = Math.round(rect.width);\n        var dh = Math.round(rect.height);\n        if (cnv.width !== dw) cnv.width = dw;\n        if (cnv.height !== dh) cnv.height = dh;\n        return true;\n    }\n\n    function getA() {\n        var v = parseFloat(document.getElementById('klInputA').value);\n        return (isNaN(v) || v <= 0) ? 100 : v;\n    }\n    function getR() {\n        var v = parseFloat(document.getElementById('klInputR').value);\n        return (isNaN(v) || v <= 0) ? 200 : v;\n    }\n\n    function clothoidPoints(A, R, steps) {\n        var L = (A * A) \/ R;\n        var pts = [];\n        var x = 0, y = 0, theta = 0;\n        var ds = L \/ steps;\n        for (var i = 0; i <= steps; i++) {\n            pts.push({ x: x, y: y });\n            var curvature = (i * ds) \/ (A * A);\n            theta += curvature * ds;\n            x += Math.cos(theta) * ds;\n            y += Math.sin(theta) * ds;\n        }\n        return { pts: pts, L: L, endTheta: theta, endX: x, endY: y };\n    }\n\n    function arcPoints(cx, cy, r, startAngle, sweep, steps) {\n        var pts = [];\n        for (var i = 0; i <= steps; i++) {\n            var a = startAngle + sweep * (i \/ steps);\n            pts.push({ x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) });\n        }\n        return pts;\n    }\n\n    function polyBounds(allPolys) {\n        var minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n        for (var p = 0; p < allPolys.length; p++) {\n            for (var i = 0; i < allPolys[p].length; i++) {\n                var pt = allPolys[p][i];\n                if (pt.x < minX) minX = pt.x;\n                if (pt.x > maxX) maxX = pt.x;\n                if (pt.y < minY) minY = pt.y;\n                if (pt.y > maxY) maxY = pt.y;\n            }\n        }\n        return { minX: minX, maxX: maxX, minY: minY, maxY: maxY };\n    }\n\n    function drawMain() {\n        fitCanvas(canvas);\n        var w = canvas.width, h = canvas.height;\n        var A = getA(), R = getR();\n        var cloth = clothoidPoints(A, R, 200);\n        var L = cloth.L;\n\n        \/\/ Hauptbogen: Anschluss an Klothoidenende, selber Tangentenwinkel\n        var mainArcLen = Math.max(L * 0.7, 40);\n        var mainArcSweep = mainArcLen \/ R;\n        var mainArcCx = cloth.endX - R * Math.sin(cloth.endTheta);\n        var mainArcCy = cloth.endY + R * Math.cos(cloth.endTheta);\n        var mainArcStart = cloth.endTheta - Math.PI \/ 2;\n        var mainArc = arcPoints(mainArcCx, mainArcCy, R, mainArcStart, mainArcSweep, 60);\n\n        \/\/ Gerade vor der Klothoide\n        var straightLen = Math.max(L * 0.4, 30);\n        var geradePts = [{ x: -straightLen, y: 0 }, { x: 0, y: 0 }];\n\n        \/\/ Knick-Alternative: Gerade + Kreisbogen direkt (ohne Klothoide), selber R\n        var knickArc = arcPoints(0, R, R, -Math.PI \/ 2, mainArcSweep * 1.2, 60);\n\n        \/\/ BigR-Alternative: Gerade + gr\u00f6\u00dferer Bogen (1,5\u00d7R), ohne Klothoide\n        var bigR = R * 1.5;\n        var bigArc = arcPoints(0, bigR, bigR, -Math.PI \/ 2, (mainArcLen \/ bigR), 60);\n\n        \/\/ Bounding box \u00fcber ALLE m\u00f6glichen Polylinien (auch ausgeschaltete),\n        \/\/ damit sich die Ansicht beim Toggeln nicht verschiebt.\n        var b = polyBounds([geradePts, cloth.pts, mainArc, knickArc, bigArc]);\n\n        var margin = 38;\n        var sceneW = (b.maxX - b.minX) || 1;\n        var sceneH = (b.maxY - b.minY) || 1;\n        var scale = Math.min((w - 2 * margin) \/ sceneW, (h - 2 * margin) \/ sceneH);\n        var padX = (w - sceneW * scale) \/ 2;\n        var padY = (h - sceneH * scale) \/ 2;\n\n        function X(wx) { return padX + (wx - b.minX) * scale; }\n        function Y(wy) { return h - padY - (wy - b.minY) * scale; }\n\n        \/\/ Hintergrund\n        ctx.clearRect(0, 0, w, h);\n        ctx.strokeStyle = '#f1f5f9';\n        ctx.lineWidth = 1;\n        for (var gx = 0; gx < w; gx += 40) { ctx.beginPath(); ctx.moveTo(gx, 0); ctx.lineTo(gx, h); ctx.stroke(); }\n        for (var gy = 0; gy < h; gy += 40) { ctx.beginPath(); ctx.moveTo(0, gy); ctx.lineTo(w, gy); ctx.stroke(); }\n\n        function strokePoly(pts, color, width, dashed) {\n            if (!pts || pts.length < 2) return;\n            ctx.strokeStyle = color;\n            ctx.lineWidth = width;\n            ctx.lineCap = 'round';\n            ctx.lineJoin = 'round';\n            ctx.setLineDash(dashed ? [7, 5] : []);\n            ctx.beginPath();\n            for (var i = 0; i < pts.length; i++) {\n                var sx = X(pts[i].x), sy = Y(pts[i].y);\n                if (i === 0) ctx.moveTo(sx, sy);\n                else ctx.lineTo(sx, sy);\n            }\n            ctx.stroke();\n            ctx.setLineDash([]);\n        }\n\n        \/\/ Reihenfolge: Alternativen zuerst (damit die Hauptkurve dar\u00fcber liegt)\n        if (state.knick) {\n            strokePoly(geradePts, COLORS.knick, 2, true);\n            strokePoly(knickArc, COLORS.knick, 2, true);\n            ctx.fillStyle = COLORS.knick;\n            ctx.beginPath(); ctx.arc(X(0), Y(0), 5, 0, Math.PI * 2); ctx.fill();\n        }\n        if (state.bigr) {\n            strokePoly(geradePts, COLORS.bigr, 2, true);\n            strokePoly(bigArc, COLORS.bigr, 2, true);\n        }\n\n        \/\/ Hauptgeometrie\n        if (state.gerade) strokePoly(geradePts, COLORS.gerade, 3, false);\n        if (state.kloth)  strokePoly(cloth.pts, COLORS.kloth, 3.5, false);\n        if (state.arc)    strokePoly(mainArc, COLORS.arc, 3.5, false);\n\n        \/\/ \u00dcbergangspunkte als kleine schwarze Kreise (nur wenn beide Nachbarn sichtbar)\n        ctx.fillStyle = '#1e293b';\n        if (state.gerade) {\n            if (state.kloth || state.knick || state.bigr) {\n                ctx.beginPath(); ctx.arc(X(0), Y(0), 4, 0, Math.PI * 2); ctx.fill();\n            }\n        }\n        if (state.kloth) {\n            if (state.arc) {\n                ctx.beginPath(); ctx.arc(X(cloth.endX), Y(cloth.endY), 4, 0, Math.PI * 2); ctx.fill();\n            }\n        }\n    }\n\n    function drawCurvature() {\n        fitCanvas(curvCanvas);\n        var w = curvCanvas.width, h = curvCanvas.height;\n        var A = getA(), R = getR();\n        var L = (A * A) \/ R;\n\n        ctxC.clearRect(0, 0, w, h);\n\n        var marginL = 78;\n        var marginR = 28;\n        var marginT = 24;\n        var marginB = 58;\n        var plotW = w - marginL - marginR;\n        var plotH = h - marginT - marginB;\n\n        \/\/ Abschnitte auf der x-Achse (proportional zur realen Bogenl\u00e4nge)\n        var straightLen = Math.max(L * 0.5, 30);\n        var arcLen = Math.max(L * 0.7, 40);\n        var totalLen = straightLen + L + arcLen;\n\n        \/\/ y-Mapping mit FIXER Skala: 0 ... MAX_CURV\n        var curv = 1 \/ R;\n        var yZero = h - marginB;\n        var yR = yZero - (curv \/ MAX_CURV) * plotH;\n        var yMax = h - marginB - plotH;\n\n        \/\/ Rahmen \/ Achsen\n        ctxC.strokeStyle = '#c8d6e0';\n        ctxC.lineWidth = 1;\n        ctxC.beginPath();\n        ctxC.moveTo(marginL, marginT);\n        ctxC.lineTo(marginL, yZero);\n        ctxC.lineTo(w - marginR, yZero);\n        ctxC.stroke();\n\n        \/\/ y-Achsen-Beschriftung\n        ctxC.font = '11px sans-serif';\n        ctxC.fillStyle = '#64748b';\n        ctxC.textBaseline = 'alphabetic';\n        ctxC.textAlign = 'left';\n        ctxC.fillText('Kr\\u00fcmmung 1\/R', marginL - 8, marginT - 8);\n        ctxC.textAlign = 'right';\n        ctxC.fillText('Bogenl\\u00e4nge s \\u2192', w - marginR, h - marginB + 42);\n        ctxC.textAlign = 'right';\n        ctxC.fillText('0', marginL - 8, yZero + 4);\n        ctxC.fillText('0,020', marginL - 8, yMax + 4);\n        ctxC.fillText('(R = 50 m)', marginL - 8, yMax + 16);\n        ctxC.textAlign = 'left';\n\n        \/\/ Referenzlinie bei Maximum (R=50)\n        ctxC.strokeStyle = '#f1f5f9';\n        ctxC.lineWidth = 1;\n        ctxC.setLineDash([3, 3]);\n        ctxC.beginPath();\n        ctxC.moveTo(marginL, yMax);\n        ctxC.lineTo(w - marginR, yMax);\n        ctxC.stroke();\n        ctxC.setLineDash([]);\n\n        function XX(s) { return marginL + (s \/ totalLen) * plotW; }\n        var x0 = XX(0);\n        var x1 = XX(straightLen);\n        var x2 = XX(straightLen + L);\n        var x3 = XX(straightLen + L + arcLen);\n\n        \/\/ Alternativen zuerst, damit Hauptkurve dar\u00fcber liegt\n        if (state.knick) {\n            ctxC.strokeStyle = COLORS.knick;\n            ctxC.lineWidth = 2;\n            ctxC.setLineDash([6, 4]);\n            ctxC.beginPath();\n            ctxC.moveTo(x0, yZero);\n            ctxC.lineTo(x1, yZero);\n            ctxC.lineTo(x1, yR);     \/\/ Sprung\n            ctxC.lineTo(x3, yR);\n            ctxC.stroke();\n            ctxC.setLineDash([]);\n        }\n        if (state.bigr) {\n            var yBigR = yZero - ((1 \/ (R * 1.5)) \/ MAX_CURV) * plotH;\n            ctxC.strokeStyle = COLORS.bigr;\n            ctxC.lineWidth = 2;\n            ctxC.setLineDash([6, 4]);\n            ctxC.beginPath();\n            ctxC.moveTo(x0, yZero);\n            ctxC.lineTo(x1, yZero);\n            ctxC.lineTo(x1, yBigR);\n            ctxC.lineTo(x3, yBigR);\n            ctxC.stroke();\n            ctxC.setLineDash([]);\n        }\n\n        \/\/ Gerade: y=0\n        if (state.gerade) {\n            ctxC.strokeStyle = COLORS.gerade;\n            ctxC.lineWidth = 3;\n            ctxC.beginPath();\n            ctxC.moveTo(x0, yZero);\n            ctxC.lineTo(x1, yZero);\n            ctxC.stroke();\n        }\n\n        \/\/ Klothoide: linearer Anstieg 0 \u2192 1\/R\n        if (state.kloth) {\n            ctxC.strokeStyle = COLORS.kloth;\n            ctxC.lineWidth = 3;\n            ctxC.beginPath();\n            ctxC.moveTo(x1, yZero);\n            ctxC.lineTo(x2, yR);\n            ctxC.stroke();\n        }\n\n        \/\/ Kreisbogen: y = 1\/R\n        if (state.arc) {\n            ctxC.strokeStyle = COLORS.arc;\n            ctxC.lineWidth = 3;\n            ctxC.beginPath();\n            ctxC.moveTo(x2, yR);\n            ctxC.lineTo(x3, yR);\n            ctxC.stroke();\n        }\n\n        \/\/ Abschnitts-Labels UNTERHALB der x-Achse (feste Zeile, keine Kollision mit Kurven)\n        var labelY = yZero + 18;\n        ctxC.font = '11px sans-serif';\n        ctxC.textBaseline = 'alphabetic';\n        ctxC.textAlign = 'center';\n        if (state.gerade) {\n            ctxC.fillStyle = COLORS.gerade;\n            ctxC.fillText('Gerade \\u00b7 R = \\u221e', (x0 + x1) \/ 2, labelY);\n        }\n        if (state.kloth) {\n            ctxC.fillStyle = COLORS.kloth;\n            ctxC.fillText('Klothoide \\u00b7 linear wachsend', (x1 + x2) \/ 2, labelY);\n        }\n        if (state.arc) {\n            ctxC.fillStyle = COLORS.arc;\n            ctxC.fillText('Kreisbogen \\u00b7 R = ' + R + ' m', (x2 + x3) \/ 2, labelY);\n        }\n        ctxC.textAlign = 'left';\n    }\n\n    function klToggle(btn) {\n        var id = btn.getAttribute('data-id');\n        var on = btn.classList.contains('off');\n        state[id] = on;\n        if (on) btn.classList.remove('off');\n        else btn.classList.add('off');\n        drawMain();\n        drawCurvature();\n    }\n\n    function klSync(which, source) {\n        var sliderId = which === 'A' ? 'klParamA' : 'klParamR';\n        var numberId = which === 'A' ? 'klInputA' : 'klInputR';\n        var slider = document.getElementById(sliderId);\n        var number = document.getElementById(numberId);\n        var smin = parseFloat(slider.min);\n        var smax = parseFloat(slider.max);\n\n        if (source === 'slider') {\n            number.value = slider.value;\n        } else {\n            if (number.value === '' || number.value === '-') return;\n            var v = parseFloat(number.value);\n            if (isNaN(v) || v <= 0) return;\n            slider.value = Math.min(smax, Math.max(smin, v));\n        }\n        klUpdate();\n    }\n\n    function klUpdate() {\n        var A = getA();\n        var R = getR();\n        var L = (A * A) \/ R;\n        document.getElementById('klValL').textContent = 'L = ' + L.toFixed(1).replace('.', ',') + ' m';\n        document.getElementById('klValR2').textContent = 'R = ' + R + ' m';\n        document.getElementById('klFormula').innerHTML =\n            '<strong>A\\u00b2 = R \\u00d7 L<\/strong> \\u00a0\\u2192\\u00a0 ' +\n            A + '\\u00b2 = ' + R + ' \\u00d7 ' + L.toFixed(1).replace('.', ',') +\n            ' \\u00a0\\u2192\\u00a0 L = <strong>' + L.toFixed(1).replace('.', ',') + ' m<\/strong>';\n        drawMain();\n        drawCurvature();\n    }\n\n    function wireEvents() {\n        var btns = document.querySelectorAll('.kl-legend-btn');\n        for (var i = 0; i < btns.length; i++) {\n            (function(btn) {\n                btn.addEventListener('click', function() { klToggle(btn); });\n            })(btns[i]);\n        }\n        document.getElementById('klParamA').addEventListener('input', function() { klSync('A', 'slider'); });\n        document.getElementById('klParamR').addEventListener('input', function() { klSync('R', 'slider'); });\n        document.getElementById('klInputA').addEventListener('input', function() { klSync('A', 'number'); });\n        document.getElementById('klInputR').addEventListener('input', function() { klSync('R', 'number'); });\n    }\n\n    function initialDraw() {\n        wireEvents();\n        klUpdate();\n        \/\/ Falls Layout beim ersten Draw noch nicht bereit war, nachreichen\n        requestAnimationFrame(function() {\n            drawMain();\n            drawCurvature();\n        });\n    }\n\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', initialDraw);\n    } else {\n        initialDraw();\n    }\n\n    var resizeTimer;\n    window.addEventListener('resize', function() {\n        clearTimeout(resizeTimer);\n        resizeTimer = setTimeout(function() {\n            drawMain();\n            drawCurvature();\n        }, 100);\n    });\n})();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Klothoiden-Explainer Interaktiver &Uuml;bergangsbogen zwischen Gerade und Kreisbogen &ndash; mit A-Parameter, Radius, Kr&uuml;mmungsband und Vergleichsgeometrien zum An- und Abschalten. Dieses Tool [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"disabled","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[39],"tags":[],"class_list":["post-1927","post","type-post","status-publish","format-standard","hentry","category-achskonstruktionen"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":false,"author_link":"https:\/\/cad-kompass.de\/?author=1"},"uagb_comment_info":0,"uagb_excerpt":"Klothoiden-Explainer Interaktiver &Uuml;bergangsbogen zwischen Gerade und Kreisbogen &ndash; mit A-Parameter, Radius, Kr&uuml;mmungsband und Vergleichsgeometrien zum An- und Abschalten. Dieses Tool [&hellip;]","_links":{"self":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/1927","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1927"}],"version-history":[{"count":8,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/1927\/revisions"}],"predecessor-version":[{"id":1957,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/1927\/revisions\/1957"}],"wp:attachment":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1927"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1927"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1927"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}