diff --git a/rhino/elemente.py b/rhino/elemente.py index 8b3ff78..b03684a 100644 --- a/rhino/elemente.py +++ b/rhino/elemente.py @@ -6421,36 +6421,38 @@ def _lauflinie_l(axis_polyline, n_stufen, z, arrow_style="klassisch", doc=None, def _aussen_l_polygon(axis_polyline, breite, referenz, z): - """Sauberes L-Polygon: 6-Punkt-Outline, die beiden Laeufe schliessen - sich an der Ecke an (Outer/Inner via Linien-Schnitt). Returnt eine - Polyline ODER None bei Singularitaet (parallele Schenkel).""" - ok, poly = axis_polyline.TryGetPolyline() - if not ok or poly is None or poly.Count != 3: return None - p0 = rg.Point3d(poly[0].X, poly[0].Y, z) - pc = rg.Point3d(poly[1].X, poly[1].Y, z) - p1 = rg.Point3d(poly[2].X, poly[2].Y, z) - L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5 - L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5 - if L1 < 1e-6 or L2 < 1e-6: return None - u1 = rg.Vector3d((pc.X - p0.X) / L1, (pc.Y - p0.Y) / L1, 0) - u2 = rg.Vector3d((p1.X - pc.X) / L2, (p1.Y - pc.Y) / L2, 0) - # perp 90° CCW - pp1 = (-u1.Y, u1.X) - pp2 = (-u2.Y, u2.X) - off_l, off_r = _treppe_2d_side_offsets(breite, referenz) - def _off(pt, perp, d): - return rg.Point3d(pt.X + perp[0] * d, pt.Y + perp[1] * d, z) - # Lauf1 Seiten (start + corner) - p0_l = _off(p0, pp1, off_l); p0_r = _off(p0, pp1, off_r) - pc_l1 = _off(pc, pp1, off_l); pc_r1 = _off(pc, pp1, off_r) - # Lauf2 Seiten (corner + end) - pc_l2 = _off(pc, pp2, off_l); pc_r2 = _off(pc, pp2, off_r) - p1_l = _off(p1, pp2, off_l); p1_r = _off(p1, pp2, off_r) - # Ecken-Schnitte: linker Schenkel intersect, rechter Schenkel intersect - corner_l = _line_intersect_xy(p0_l, u1, p1_l, u2) or pc_l1 - corner_r = _line_intersect_xy(p0_r, u1, p1_r, u2) or pc_r1 - pts = [p0_l, p0_r, corner_r, p1_r, p1_l, corner_l, p0_l] - return rg.PolylineCurve(rg.Polyline(pts)) + """Sauberes L-Polygon: 6-Punkt-Outline mit Outer/Inner-Ecken via + Linien-Schnitt. Returnt PolylineCurve oder None bei Singularitaet/ + Fehler — Caller faellt dann auf 2-Rechteck-Variante zurueck.""" + try: + ok, poly = axis_polyline.TryGetPolyline() + if not ok or poly is None or poly.Count != 3: return None + p0 = rg.Point3d(poly[0].X, poly[0].Y, z) + pc = rg.Point3d(poly[1].X, poly[1].Y, z) + p1 = rg.Point3d(poly[2].X, poly[2].Y, z) + L1 = ((pc.X - p0.X) ** 2 + (pc.Y - p0.Y) ** 2) ** 0.5 + L2 = ((p1.X - pc.X) ** 2 + (p1.Y - pc.Y) ** 2) ** 0.5 + if L1 < 1e-6 or L2 < 1e-6: return None + u1 = rg.Vector3d((pc.X - p0.X) / L1, (pc.Y - p0.Y) / L1, 0) + u2 = rg.Vector3d((p1.X - pc.X) / L2, (p1.Y - pc.Y) / L2, 0) + pp1 = (-u1.Y, u1.X) + pp2 = (-u2.Y, u2.X) + off_l, off_r = _treppe_2d_side_offsets(breite, referenz) + def _off(pt, perp, d): + return rg.Point3d(pt.X + perp[0] * d, pt.Y + perp[1] * d, z) + p0_l = _off(p0, pp1, off_l); p0_r = _off(p0, pp1, off_r) + pc_l1 = _off(pc, pp1, off_l); pc_r1 = _off(pc, pp1, off_r) + p1_l = _off(p1, pp2, off_l); p1_r = _off(p1, pp2, off_r) + # Ecken-Schnitte — Z auf z setzen (Helper liefert Z=0) + def _at_z(p, fallback): + return rg.Point3d(p.X, p.Y, z) if p is not None else fallback + corner_l = _at_z(_line_intersect_xy(p0_l, u1, p1_l, u2), pc_l1) + corner_r = _at_z(_line_intersect_xy(p0_r, u1, p1_r, u2), pc_r1) + pts = [p0_l, p0_r, corner_r, p1_r, p1_l, corner_l, p0_l] + return rg.PolylineCurve(rg.Polyline(pts)) + except Exception as ex: + print("[ELEMENTE] _aussen_l_polygon:", ex) + return None def _aussen_l(axis_polyline, breite, referenz, z,