diff --git a/img.png b/img.png new file mode 100644 index 0000000..e54a81a Binary files /dev/null and b/img.png differ diff --git a/src/matrixmania/compute.py b/src/matrixmania/compute.py index 360b79c..0034f8e 100644 --- a/src/matrixmania/compute.py +++ b/src/matrixmania/compute.py @@ -233,3 +233,16 @@ if __name__ == "__main__": print(rot_2D(theta)) print(rot_2D(1.0)) +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]: + """Projiziert einen 3D-Punkt perspektivisch auf eine 2D-Ebene.""" + x, y, z = point + depth = z + camera_distance + if depth == 0: + raise ValueError("z + camera_distance darf nicht 0 sein.") + x_2d = x * focal_length / depth * scale + y_2d = y * focal_length / depth * scale + return (x_2d, y_2d) + diff --git a/test/test_matrixmania/test_projection.py b/test/test_matrixmania/test_projection.py index 1f9f534..4d6ec95 100644 --- a/test/test_matrixmania/test_projection.py +++ b/test/test_matrixmania/test_projection.py @@ -1,6 +1,6 @@ import pytest -from matrixmania.compute import project_ortho +from matrixmania.compute import project_ortho, project_perspective def test_project_ortho_default(): @@ -9,7 +9,35 @@ def test_project_ortho_default(): assert project_ortho(point) == (1.0, 2.0) -def test_project_ortho_scaled(): +def test_project_perspective_default(): + """Test project_perspective with default scale and focal_length=1""" + # Arrange + point = (1.0, 2.0, 3.0) + # Act + result = project_perspective(point) + # depth = z + camera_distance = 3 + 4 = 7 + # Expected x = 1 * 1 / 7 * 1 = 1/7 + # Expected y = 2 * 1 / 7 * 1 = 2/7 + expected = (1/7, 2/7) + # Assert + assert result == pytest.approx(expected) + + +def test_project_perspective_scaled(): + """Test project_perspective with scale=100 and focal_length=2""" + # Arrange + point = (1.0, 2.0, 3.0) + scale = 100 + focal_length = 2 + # Act + result = project_perspective(point, focal_length=focal_length, scale=scale) + # depth = 3 + 4 = 7 + # Expected x = 1 * 2 / 7 * 100 = 200/7 + # Expected y = 2 * 2 / 7 * 100 = 400/7 + expected = (200/7, 400/7) + # Assert + assert result == pytest.approx(expected) + """Projektionsfunktion mit Skalierung""" point = (1.0, 2.0, 3.0) assert project_ortho(point, scale=100) == (100.0, 200.0)