"""Kippmodell Kratzbaum, Fassung 3 — Stand 24.09.2026 (Rechenweg mit einer ebenen Starrkörper-Simulation nachgerechnet). Quelle: https://pawlosso.com/ratgeber/kratzbaum-maine-coon-grosse-katzen Kernzahl ohne Annahmen über Sprünge (statische Kippschwelle): F_kipp = (M + m)·g·B / (2·H) Diese waagerechte Kraft an der obersten Liegefläche (Höhe H) hebt einen Baum (Masse M, Katze m mittig darauf, kürzere Plattenseite B) an. In „kg Zug" ausgedrückt: (M + m)·B / (2·H). Dynamik (Fassung 3; mit einer ebenen Starrkörper-Simulation unter denselben Annahmen nachgerechnet): * Baum starr: Bodenplatte 18 mm Spanplatte (650 kg/m³), Rest gleichmäßig über die Höhe verteilt. * Die Katze drückt über die Kontaktzeit Δt mit einem Halbsinus-Kraftverlauf; die Drehung um die Kippkante wird Schritt für Schritt mitgerechnet (Hebel abhängig vom Winkel). * Landung: waagerechte Geschwindigkeit v_h, senkrechte v_v = v_h (45°-Bahn), Δt = 0,05 s (Wu et al. 2019: Abfederzeit Vorderbeine 46–49 ms — gemessen beim senkrechten Sprung hinab). Danach ruht die Katze auf der Liegefläche (Drehimpuls um die Kante erhalten). * Absprung: waagerecht mit v_h, Δt = 0,15 s (Zajac et al. 1981: Absprungphase „etwa 150 ms" — gemessen bei Hochsprüngen). Danach ist die Katze weg. * Senkrechte Pfotenkraft mittig über der Platte (Parameter e verschiebt sie). Grenzen: keine Dämpfung (Verbindungen, Stämme, Teppich) — das senkt real; flachere Sprünge, Landung am Rand, über die Platte ragende Liegeflächen — das erhöht real. Unsicherheit mindestens Faktor 2 in beide Richtungen. Ergebnis daher nur als Stufe verwenden, nicht als Gradzahl. """ from math import sqrt, sin, cos, pi, atan, degrees G = 9.81 RHO, T = 650.0, 0.018 DT_LANDUNG, DT_ABSPRUNG = 0.05, 0.15 SPRUNG = {"ruhig": 1.5, "normal": 2.2, "kräftig": 2.7} # waagerechte Geschwindigkeit in m/s def kippschwelle_kg(m, H, B, M): """waagerechter Zug in kg an der obersten Liegefläche, der die Platte anhebt""" return (M + m) * B / (2 * H) def _teile(B, M, H): Ht = H + 0.1 Mp = min(RHO * B * B * T, 0.8 * M) Ms = M - Mp return Mp * B * B / 3 + Ms * ((B / 2) ** 2 + Ht * Ht / 3), (Mp * T / 2 + Ms * Ht / 2) / M def fall(m, H, B, M, vh, art, e=0.0, h=1e-4): I, yS = _teile(B, M, H) xS, xq = B / 2, B / 2 + e if art == "landung": dt, Jh, Jv = DT_LANDUNG, m * vh, m * vh else: dt, Jh, Jv = DT_ABSPRUNG, m * vh, 0.0 th = w = t = thmax = 0.0 Mg, mit = M * G, False while True: c, s = cos(th), sin(th) tau = -Mg * (xS * c - yS * s) if t < dt: f = (pi / 2) * sin(pi * t / dt) / dt Fh, Fv = Jh * f, m * G + Jv * f tau += Fh * (xq * s + H * c) - Fv * (xq * c - H * s) elif art == "landung" and not mit: Ik = m * (xq * xq + H * H); w = w * I / (I + Ik); I += Ik xS, yS = (M * xS + m * xq) / (M + m), (M * yS + m * H) / (M + m) Mg, mit = (M + m) * G, True if th <= 0 and w <= 0 and tau <= 0: th = w = 0.0 else: w += tau / I * h; th += w * h thmax = max(thmax, th) if th >= atan(xS / yS): return dict(kippt=True, anteil=1.0, anhub_cm=None, winkel=None) t += h if t > dt and (w < 0 or (th <= 0 and w <= 0)): break r = sqrt(xS * xS + yS * yS) return dict(kippt=False, anteil=(xS * sin(thmax) + yS * cos(thmax) - yS) / (r - yS), anhub_cm=100 * B * sin(thmax), winkel=degrees(thmax)) def rechne(m, H, B, M, vh): a, b = fall(m, H, B, M, vh, "landung"), fall(m, H, B, M, vh, "absprung") return (a | {"fall": "Landung"}) if a["anteil"] >= b["anteil"] else (b | {"fall": "Absprung"}) def stufe(r): if r["kippt"]: return "kippt um" if r["anteil"] >= 0.5: return "nahe an der Kippgrenze" if r["anhub_cm"] >= 1.0: return "hebt spürbar ab" if r["anhub_cm"] >= 0.1: return "hebt kaum ab" return "steht ruhig" if __name__ == "__main__": for args in ((8, 1.5, 0.6, 25), (9, 1.5, 0.6, 30), (5, 1.5, 0.6, 25), (7, 1.5, 1.0, 40), (6, 1.2, 0.5, 20)): m, H, B, M = args print(args, f"Kippschwelle {kippschwelle_kg(*args):.1f} kg Zug", {k: stufe(rechne(m, H, B, M, v)) + f" ({100*rechne(m,H,B,M,v)['anteil']:.0f} %)" for k, v in SPRUNG.items()})