package viz import ( "bspviz/internal/bsp" "bytes" "fmt" "os" "os/exec" ) // EmitDOT serialisiert den BSP-Baum mit Wurzel root und schreibt ihn als DOT-Datei nach path. func EmitDOT(root *bsp.Node, path string) error { // buf sammelt den DOT-Text, bevor wir ihn speichern. var buf bytes.Buffer buf.WriteString("digraph BSP {\n") buf.WriteString(" node [fontname=\"Helvetica\"];\n") // id vergibt fortlaufende Nummern für alle ausgegebenen Knoten. id := 0 var walk func(*bsp.Node) int // walk läuft den Baum in Tiefe-zuerst-Reihenfolge ab und liefert die DOT-Knoten-ID zurück. walk = func(n *bsp.Node) int { my := id id++ if n.Leaf != nil { fmt.Fprintf(&buf, " n%d [label=\"Leaf\\nSegs=%d\", shape=ellipse, style=filled, fillcolor=lightgray];\n", my, len(n.Leaf.Segs)) return my } fmt.Fprintf(&buf, " n%d [label=\"Split\\nO=(%.0f,%.0f) D=(%.0f,%.0f)\"];\n", my, n.O.X, n.O.Y, n.D.X, n.D.Y) l := walk(n.Left) r := walk(n.Right) fmt.Fprintf(&buf, " n%d -> n%d [label=\"L\"];\n", my, l) fmt.Fprintf(&buf, " n%d -> n%d [label=\"R\"];\n", my, r) return my } walk(root) buf.WriteString("}\n") return os.WriteFile(path, buf.Bytes(), 0644) } func RunGraphviz(dotFile, pngFile string) error { cmd := exec.Command("dot", "-Tpng", dotFile, "-o", pngFile) out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("graphviz failed: %v\n%s", err, string(out)) } return nil }