48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
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]}" |