sixth commit: test added
This commit is contained in:
1 parent
b649addb49
commit
e6d4274525
4 files changed
+90
-1
No files matched your search
@@ -1 +1 @@
|
||||
from .compute import matmul, transpose, rot_2D, rot_3D
|
||||
from .compute import matmul, transpose, rot_2D, rot_3D, project_ortho, project_perspective
|
||||
@@ -142,6 +142,26 @@ def rot_3D(angle: float, axis: str) -> list[list[float]]:
|
||||
[0, 0, 1],
|
||||
]
|
||||
|
||||
def project_ortho(point: tuple[float, float, float], scale: float = 1) -> tuple[float, float]:
|
||||
"""Project a 3D point onto a 2D plane using orthogonal projection."""
|
||||
x, y, _z = point
|
||||
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]:
|
||||
"""Project a 3D point onto a 2D plane using perspective projection."""
|
||||
x, y ,z = point
|
||||
factor = focal_length / (z+camera_distance)
|
||||
x_2d = x * factor * scale
|
||||
y_2d = y * factor * scale
|
||||
return (x_2d, y_2d)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import math
|
||||
import pytest
|
||||
|
||||
from matrixmania import project_perspective
|
||||
|
||||
|
||||
def approx_equal(a: float, b: float, rel_tol: float = 1e-9) -> bool:
|
||||
"""Utility to compare two floats with a relative tolerance."""
|
||||
return math.isclose(a, b, rel_tol=rel_tol)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"point,focal_length,scale,expected",
|
||||
[
|
||||
# Case 1 – no scaling, unit focal length
|
||||
(
|
||||
(1.0, 2.0, 3.0),
|
||||
1.0, # focal_length
|
||||
1.0, # scale
|
||||
(
|
||||
1.0 / (4.0 + 3.0), # x projected
|
||||
2.0 / (4.0 + 3.0), # y projected
|
||||
),
|
||||
),
|
||||
# Case 2 – scale 100, focal length 2
|
||||
(
|
||||
(1.0, 2.0, 3.0),
|
||||
2.0, # focal_length
|
||||
100.0, # scale
|
||||
(
|
||||
2.0 * 100.0 / (4.0 + 3.0), # x projected
|
||||
2.0 * 100.0 * 2.0 / (4.0 + 3.0), # y projected
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_project_perspective(point, focal_length, scale, expected):
|
||||
"""Test that project_perspective returns the correct 2‑D projection."""
|
||||
# Call the function under test
|
||||
result = project_perspective(point, focal_length=focal_length, scale=scale)
|
||||
|
||||
# Basic sanity checks
|
||||
assert isinstance(result, tuple), "Result should be a tuple"
|
||||
assert len(result) == 2, "Result should contain two coordinates"
|
||||
|
||||
# Confirm values are close to expected (within tiny tolerance)
|
||||
assert approx_equal(result[0], expected[0]), f"X coordinate mismatch: {result[0]} != {expected[0]}"
|
||||
assert approx_equal(result[1], expected[1]), f"Y coordinate mismatch: {result[1]} != {expected[1]}"
|
||||
@@ -0,0 +1,21 @@
|
||||
from matrixmania import project_ortho
|
||||
|
||||
|
||||
def test_projection_point():
|
||||
#Arrange
|
||||
point = (1.0, 2.0, 3.0)
|
||||
expected_value = (1.0, 2.0)
|
||||
|
||||
#Act
|
||||
result = project_ortho(point)
|
||||
|
||||
#Assert
|
||||
assert result == expected_value
|
||||
|
||||
def test_projection_scale():
|
||||
point = (1.0, 2.0, 3.0)
|
||||
scale = 100
|
||||
expected_value = (100.0, 200.0)
|
||||
|
||||
result = project_ortho(point, scale)
|
||||
assert result == expected_value
|
||||
Reference in new issue
Block a user