File: //opt/kw-schueler.bak.21032025/create_radar_model.py
#!/usr/bin/env python3
"""
Dieses Skript erstellt ein 3D-Modell eines Radar-/Spinnendiagramms
für die Visualisierung eines Kompetenzprofils.
Das Modell wird als OBJ-Datei gespeichert.
"""
import os
import math
import numpy as np
# Kompetenzdaten (Demo)
STUDENT_NAME = "Demo"
COMPETENCIES = [
{"name": "Inhalt", "value": 8},
{"name": "Struktur", "value": 5},
{"name": "Sprache", "value": 7},
{"name": "Argumentation", "value": 6},
{"name": "Kreativität", "value": 9},
{"name": "Quellenbezug", "value": 4}
]
# Konfiguration
OUTPUT_DIR = "static"
OUTPUT_FILE = os.path.join(OUTPUT_DIR, "radar_model.obj")
# Funktion zum Erzeugen des Radar-Diagramms als 3D-Modell
def create_radar_model(competencies, filename):
"""Erstellt ein 3D-Radar-Diagramm und speichert es als OBJ-Datei."""
# Sicherstellen, dass der Ausgabeordner existiert
os.makedirs(os.path.dirname(filename), exist_ok=True)
# Anzahl der Kompetenzen
num_competencies = len(competencies)
# Punktelisten für das Modell
vertices = []
faces = []
# Zentrum des Diagramms
vertices.append((0, 0, 0)) # Punkt 1: Zentrum
# Basis-Radius für das Diagramm
base_radius = 1.0
# Punkte für die Achsen der Kompetenzen
for i, comp in enumerate(competencies):
# Normalisierter Wert (0-1)
value = comp["value"] / 10.0
# Winkel für diese Kompetenz
angle = 2 * math.pi * i / num_competencies
# Punkt auf dem Umfang mit voller Stärke
x = base_radius * math.cos(angle)
z = base_radius * math.sin(angle)
vertices.append((x, 0, z)) # Punkt für den Achsenendpunkt
# Punkt für den Datenpunkt (skaliert mit dem Wert)
x_value = base_radius * value * math.cos(angle)
z_value = base_radius * value * math.sin(angle)
vertices.append((x_value, 0, z_value)) # Punkt für den Datenwert
# Erstelle Dreiecke für die Radarform
for i in range(num_competencies):
# Indizes für die aktuellen und nächsten Datenpunkte
current_value_idx = 2 * i + 2
next_value_idx = 2 * ((i + 1) % num_competencies) + 2
# Dreiecke von Zentrum zu den Datenpunkten
faces.append((1, current_value_idx, next_value_idx))
# Erstelle die OBJ-Datei
with open(filename, 'w') as f:
# Kommentar mit Metadaten
f.write(f"# Radar-Diagramm für {STUDENT_NAME}\n")
f.write(f"# Erstellt mit create_radar_model.py\n\n")
# Schreibe Materialdefinition
f.write("mtllib radar.mtl\n\n")
# Objektname
f.write(f"o Radar_{STUDENT_NAME}\n\n")
# Vertizes schreiben (OBJ-Format: v x y z)
for v in vertices:
f.write(f"v {v[0]:.6f} {v[1]:.6f} {v[2]:.6f}\n")
f.write("\n# Texturkoordinaten\n")
for _ in range(len(vertices)):
f.write(f"vt 0.0 0.0\n")
f.write("\n# Normalen\n")
f.write("vn 0.0 1.0 0.0\n") # Oberfläche zeigt nach oben
f.write("\n# Materialzuweisung\n")
f.write("usemtl RadarMaterial\n")
f.write("s off\n\n")
# Flächen schreiben (OBJ-Format: f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3)
for face in faces:
f.write(f"f {face[0]}/{face[0]}/1 {face[1]}/{face[1]}/1 {face[2]}/{face[2]}/1\n")
# Erstelle eine einfache MTL-Datei
with open(os.path.join(OUTPUT_DIR, "radar.mtl"), 'w') as f:
f.write("# Radar Material\n\n")
f.write("newmtl RadarMaterial\n")
f.write("Ns 225.000000\n")
f.write("Ka 1.000000 1.000000 1.000000\n")
f.write("Kd 0.000000 0.400000 0.800000\n") # Blau
f.write("Ks 0.500000 0.500000 0.500000\n")
f.write("Ke 0.000000 0.000000 0.000000\n")
f.write("Ni 1.450000\n")
f.write("d 0.600000\n") # Etwas transparent
f.write("illum 2\n")
print(f"3D-Modell erstellt: {filename}")
print(f"Materialdatei erstellt: {os.path.join(OUTPUT_DIR, 'radar.mtl')}")
return filename
if __name__ == "__main__":
# Erstelle das Modell
obj_file = create_radar_model(COMPETENCIES, OUTPUT_FILE)
# Konvertierungsinstruktionen anzeigen
print("\nUm dieses Modell in USDZ zu konvertieren, führen Sie folgende Schritte aus:")
print("1. Installieren Sie Apple's USDZ Converter Tool (benötigt macOS)")
print("2. Führen Sie folgenden Befehl aus:")
print(f" xcrun usdz_converter {obj_file} {os.path.dirname(obj_file)}/radar_placeholder.usdz -v")
print("\nAlternativ können Sie auch einen Online-Konverter verwenden.")