diff --git a/.idea/Masterprojekt-Campusnetz.iml b/.idea/Masterprojekt-Campusnetz.iml
index 1d2fcdf..89b2bd1 100644
--- a/.idea/Masterprojekt-Campusnetz.iml
+++ b/.idea/Masterprojekt-Campusnetz.iml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index ba45cb8..590a59e 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/Netzqualität_Genauigkeit.py b/Netzqualität_Genauigkeit.py
new file mode 100644
index 0000000..c939eab
--- /dev/null
+++ b/Netzqualität_Genauigkeit.py
@@ -0,0 +1,149 @@
+from dataclasses import dataclass
+from typing import Sequence, List, Dict
+import sympy as sp
+import numpy as np
+import matplotlib.pyplot as plt
+
+
+@dataclass
+class Genauigkeitsmaße:
+
+
+ def helmertscher_punktfehler_3D(self, sigma_x: float, sigma_y: float, sigma_z: float) -> float:
+ sx = sp.sympify(sigma_x)
+ sy = sp.sympify(sigma_y)
+ sz = sp.sympify(sigma_z)
+
+ helmert_pf_3D = sp.sqrt(sx**2 + sy**2 + sz**2)
+ return float(helmert_pf_3D)
+
+
+ def helmertscher_punktfehler_3D_alle(
+ self,
+ sigma_x_list: Sequence[float],
+ sigma_y_list: Sequence[float],
+ sigma_z_list: Sequence[float],
+ ) -> List[float]:
+ if not (
+ len(sigma_x_list) == len(sigma_y_list) == len(sigma_z_list)
+ ):
+ raise ValueError("Listen sigma_x, sigma_y, sigma_z müssen gleich lang sein.")
+
+ return [
+ self.helmertscher_punktfehler_3D(sx, sy, sz)
+ for sx, sy, sz in zip(sigma_x_list, sigma_y_list, sigma_z_list)
+ ]
+
+
+ def fehlerellipse_standard_2D(
+ self,
+ Q_xx: float,
+ Q_yy: float,
+ Q_xy: float,
+ sigma_0: float,
+ ) -> Dict[str, float]:
+
+ Q_xx_s = sp.sympify(Q_xx)
+ Q_yy_s = sp.sympify(Q_yy)
+ Q_xy_s = sp.sympify(Q_xy)
+ sigma0_s = sp.sympify(sigma_0)
+
+ k = sp.sqrt((Q_xx_s - Q_yy_s)**2 + 4 * Q_xy_s**2)
+
+ Q_dmax = sp.Rational(1, 2) * (Q_xx_s + Q_yy_s + k)
+ Q_dmin = sp.Rational(1, 2) * (Q_xx_s + Q_yy_s - k)
+
+ s_max = sigma0_s * sp.sqrt(Q_dmax)
+ s_min = sigma0_s * sp.sqrt(Q_dmin)
+
+ theta_rad = sp.Rational(1, 2) * sp.atan2(2 * Q_xy_s, Q_xx_s - Q_yy_s)
+ theta_gon = theta_rad * 200 / sp.pi
+
+ return {
+ "Q_dmax": float(Q_dmax),
+ "Q_dmin": float(Q_dmin),
+ "s_max": float(s_max),
+ "s_min": float(s_min),
+ "theta_rad": float(theta_rad),
+ "theta_gon": float(theta_gon),
+ }
+
+
+
+ def fehlerellipse_konfidenz_2D(
+ self,
+ s_max: float,
+ s_min: float,
+ scale_value: float,
+ ) -> Dict[str, float]:
+
+ s_max_s = sp.sympify(s_max)
+ s_min_s = sp.sympify(s_min)
+ scale_s = sp.sympify(scale_value)
+
+ faktor = sp.sqrt(scale_s)
+
+ A_K = faktor * s_max_s
+ B_K = faktor * s_min_s
+
+ return {
+ "A_K": float(A_K),
+ "B_K": float(B_K),
+ }
+
+
+
+ def plot_ellipsen_alle(
+ self,
+ x_list: Sequence[float],
+ y_list: Sequence[float],
+ Q_xx_list: Sequence[float],
+ Q_yy_list: Sequence[float],
+ Q_xy_list: Sequence[float],
+ sigma_0: float,
+ scale_value: float | None = None, # None = Standardellipse, sonst Konfidenzellipse
+ ) -> plt.Axes:
+
+ n = len(x_list)
+ if not (
+ n == len(y_list) == len(Q_xx_list) == len(Q_yy_list) == len(Q_xy_list)
+ ):
+ raise ValueError("Alle Listen müssen gleich lang sein (ein Eintrag pro Punkt).")
+
+ fig, ax = plt.subplots()
+
+ for i in range(n):
+ std = self.fehlerellipse_standard_2D(
+ Q_xx_list[i], Q_yy_list[i], Q_xy_list[i], sigma_0
+ )
+ s_max = std["s_max"]
+ s_min = std["s_min"]
+ theta = std["theta_rad"]
+
+ # ggf. Konfidenzellipse statt Standardellipse
+ if scale_value is not None:
+ konf = self.fehlerellipse_konfidenz_2D(s_max, s_min, scale_value)
+ A = konf["A_K"]
+ B = konf["B_K"]
+ else:
+ A = s_max
+ B = s_min
+
+ t = np.linspace(0, 2 * np.pi, 200)
+ ct = np.cos(theta)
+ st = np.sin(theta)
+
+ x_local = A * np.cos(t)
+ y_local = B * np.sin(t)
+
+ x_ell = x_list[i] + ct * x_local - st * y_local
+ y_ell = y_list[i] + st * x_local + ct * y_local
+
+ ax.plot(x_ell, y_ell, linewidth=0.8)
+ ax.plot(x_list[i], y_list[i], marker=".", color="k", markersize=3)
+
+ ax.set_aspect("equal", "box")
+ ax.grid(True)
+ ax.set_xlabel("x")
+ ax.set_ylabel("y")
+ return ax
\ No newline at end of file