diff --git a/src/matrixmania/compute.py b/src/matrixmania/compute.py index d0cff61..df581c8 100644 --- a/src/matrixmania/compute.py +++ b/src/matrixmania/compute.py @@ -148,6 +148,15 @@ def project_ortho( return x * scale, y * scale +def project_perspective(point: tuple[float, float, float], + focal_length: float = 1.0, + scale: float = 1.0, + camera_distance: float = 4.0) -> tuple[float, float]: + x, y, z = point + return (((x * focal_length) / z + camera_distance) * scale, + ((y * focal_length) / z + camera_distance) * scale) + + def test_functions() -> None: """Testet die mathematischen Hilfsfunktionen für Matrixoperationen.""" a1 = [ diff --git a/test/test_matrixmania/test_projection.py b/test/test_matrixmania/test_projection.py index 2242f34..44bbf94 100644 --- a/test/test_matrixmania/test_projection.py +++ b/test/test_matrixmania/test_projection.py @@ -1,6 +1,8 @@ -"""Unit-Tests für orthogonale Projektionen in compute.py.""" +"""Unit-Tests für Projektionen in compute.py.""" -from matrixmania.compute import project_ortho +import math + +from matrixmania.compute import project_ortho, project_perspective def test_project_ortho_default_scale() -> None: @@ -26,3 +28,33 @@ def test_project_ortho_scaled() -> None: # Assert assert result == (100.0, 200.0) + + +def test_project_perspective_scale_and_focal_length_one() -> None: + """Testet die perspektivische Projektion mit scale=1 und focal_length=1.""" + # Arrange + point = (1.0, 2.0, 3.0) + scale = 1 + focal_length = 1 + + # Act + result = project_perspective(point, scale=scale, focal_length=focal_length) + + # Assert + assert math.isclose(result[0], 13.0 / 3.0, abs_tol=1e-9) + assert math.isclose(result[1], 14.0 / 3.0, abs_tol=1e-9) + + +def test_project_perspective_scale_100_focal_length_2() -> None: + """Testet die perspektivische Projektion mit scale=100 und focal_length=2.""" + # Arrange + point = (1.0, 2.0, 3.0) + scale = 100 + focal_length = 2 + + # Act + result = project_perspective(point, scale=scale, focal_length=focal_length) + + # Assert + assert math.isclose(result[0], 1400.0 / 3.0, abs_tol=1e-9) + assert math.isclose(result[1], 1600.0 / 3.0, abs_tol=1e-9)