From f54fc5d4efb7904b7be727313a2f8380cb15d8fd Mon Sep 17 00:00:00 2001 From: layannaif Date: Mon, 26 Oct 2026 13:31:58 +0100 Subject: [PATCH] Hausaufgabe perspektivische Projektion und Tests --- matrixmania/compute.py | 37 ++++++++++++++++++++++++ test/test_matrixmania/test_projection.py | 28 +++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/matrixmania/compute.py b/matrixmania/compute.py index 4477bff..31d873b 100644 --- a/matrixmania/compute.py +++ b/matrixmania/compute.py @@ -53,6 +53,35 @@ def project_ortho( return (x * scale, y * scale) +# ============================================================ +# NEU: HAUSAUFGABE – PERSPEKTIVISCHE PROJEKTION +# ============================================================ + +def project_perspective( + point: tuple[float, float, float], + focal_length: float = 1, + camera_distance: float = 4.0 , + scale: float = 1, +) -> tuple[float, float]: + """Projiziert einen 3D-Punkt perspektivisch auf die 2D-Ebene.""" + + x, y, z = point # NEU: 3D-Koordinaten auslesen + + distance = z + camera_distance # NEU: Entfernung berechnen + + if distance == 0: # NEU: Division durch null verhindern + raise ValueError("Der Punkt liegt auf der Kameraebene.") + + x_new = (x * focal_length / distance) * scale # NEU: x projizieren + y_new = (y * focal_length / distance) * scale # NEU: y projizieren + + return (x_new, y_new) # NEU: 2D-Koordinaten zurückgeben + +# ============================================================ +# ENDE DER NEUEN HAUSAUFGABE +# ============================================================ + + def matmul( a: list[list[float | int]], b: list[list[float | int]], @@ -137,3 +166,11 @@ if __name__ == "__main__": print("\n3D-Rotation um die Z-Achse:") print(tabulate(rot_3D(math.pi / 2, "z"))) + + # NEU: HAUSAUFGABE – Perspektivische Projektion testen + print("\nPerspektivische Projektion:") + print(project_perspective((1.0, 2.0, 3.0))) + + # NEU: HAUSAUFGABE – Perspektivische Projektion mit Skalierung testen + print("\nPerspektivische Projektion mit Skalierung 100:") + print(project_perspective((1.0, 2.0, 3.0), scale=100)) diff --git a/test/test_matrixmania/test_projection.py b/test/test_matrixmania/test_projection.py index 57d94dc..f82ece7 100644 --- a/test/test_matrixmania/test_projection.py +++ b/test/test_matrixmania/test_projection.py @@ -1,5 +1,7 @@ -from matrixmania.compute import project_ortho +import pytest + +from matrixmania.compute import project_ortho, project_perspective def test_project_ortho_default(): @@ -24,3 +26,27 @@ def test_project_ortho_scale_100(): # Assert assert result == expected + + +def test_project_perspective_default(): + # Arrange + point = (1.0, 2.0, 3.0) + expected = (1.0 / 7.0, 2.0 / 7.0) + + # Act + result = project_perspective(point) + + # Assert + assert result == pytest.approx(expected) + + +def test_project_perspective_focal_length_2_scale_100(): + # Arrange + point = (1.0, 2.0, 3.0) + expected = ((1.0 * 2.0 / 7.0) * 100, (2.0 * 2.0 / 7.0) * 100) + + # Act + result = project_perspective(point, focal_length=2.0, scale=100) + + # Assert + assert result == pytest.approx(expected)