import math # Konstanten für die Schulbuch-Projektion WINKEL_X1_GRAD = 135 # 135 Grad im mathematisch positiven Drehsinn (nach unten-links) VERKUERZUNG_X1 = 1.0 / math.sqrt(2) # ca. 0.7071 def projiziere_3d_auf_2d( x1: float, x2: float, x3: float, skalierung: float = 40.0 ) -> tuple[float, float]: """ Rechnet eine 3D-Koordinate (x1, x2, x3) in eine relative 2D-Ebene um. :param x1: Koordinate nach vorne-links :param x2: Koordinate nach rechts :param x3: Koordinate nach oben :param skalierung: Multiplikator, wie viele Pixel eine Längeneinheit (LE) groß ist (z.B. 40px = 1cm). :return: (x_relativ, y_relativ) bezogen auf den mathematischen Ursprung (0,0). """ # Winkel in Bogenmaß umrechnen # Da wir nach unten-links wollen, nutzen wir den Winkel direkt. winkel_rad = math.radians(WINKEL_X1_GRAD) # 1. Berechnung des x-Werts auf dem Papier (relativ zum Ursprung): # x2 geht direkt nach rechts (+). # x1 geht nach links (-), das ist im cos(135°) bereits mathematisch korrekt enthalten. x_2d = x2 + (x1 * VERKUERZUNG_X1 * math.cos(winkel_rad)) # 2. Berechnung des y-Werts auf dem Papier (relativ zum Ursprung): # x3 geht nach oben (+). # x1 geht nach unten (-), das ist im sin(135°) positiv, aber da im SVG 'unten' positiv ist, # müssen wir die mathematische Richtung umkehren. # Mathematisch: y = x3 + x1 * verkürzung * sin(135°) # Für SVG (da y nach unten wächst): Wir negieren den gesamten mathematischen y-Wert. y_2d = (x1 * VERKUERZUNG_X1 * math.sin(winkel_rad)) - x3 # Mit dem Skalierungsfaktor (Pixel pro Längeneinheit) multiplizieren return x_2d * skalierung, y_2d * skalierung