Files
2026-09-02 15:13:13 +08:00

64 lines
2.3 KiB
Python

"""line_of_sight_test.py —— PixelToAngle 单元测试。
移植自 reference-c++/visual_track_control/tests/line_of_sight_test.cpp。
覆盖(物理追踪思路 §4.1/§5.1,C2):零偏移、画面边缘偏移 = 半视场角、
奇对称、单调性、与线性近似的偏离(全程针孔模型)、构造期非法参数抛异常。
"""
import math
import pytest
from visual_track_control.line_of_sight import PixelToAngle
def test_zero_offset_gives_zero_angle():
conv = PixelToAngle(1000.0, math.radians(90.0))
assert conv.convert(0.0) == 0.0
def test_half_size_offset_gives_half_fov():
# 针孔模型:偏移 = size/2 时 angle = atan(tan(θ/2)) = θ/2
conv = PixelToAngle(1000.0, math.radians(90.0))
assert conv.convert(500.0) == pytest.approx(math.radians(45.0), abs=1e-12)
assert conv.convert(-500.0) == pytest.approx(-math.radians(45.0), abs=1e-12)
def test_odd_symmetry():
conv = PixelToAngle(1920.0, math.radians(60.0))
for offset in (1.0, 100.0, 730.5):
assert conv.convert(-offset) == pytest.approx(-conv.convert(offset),
abs=1e-15)
def test_monotonic_increasing():
conv = PixelToAngle(1080.0, math.radians(35.0))
prev = conv.convert(-600.0)
for x in range(-500, 601, 100):
cur = conv.convert(float(x))
assert cur > prev
prev = cur
def test_deviates_from_linear_approximation():
# C2:全程针孔模型。θ=90°、偏移比例 0.25 处线性近似误差约 4°,
# 针孔结果必须与之明显偏离(证明未走线性支路)。
conv = PixelToAngle(1000.0, math.radians(90.0))
pinhole_deg = math.degrees(conv.convert(250.0)) # atan(250·2·tan45°/1000)
linear_deg = 250.0 * (90.0 / 1000.0) # θ·offset/size = 22.5°
assert pinhole_deg == pytest.approx(math.degrees(math.atan(0.5)), abs=1e-9)
assert abs(pinhole_deg - linear_deg) > 2.0
def test_constructor_rejects_invalid_args():
with pytest.raises(ValueError):
PixelToAngle(0.0, 1.0)
with pytest.raises(ValueError):
PixelToAngle(-10.0, 1.0)
with pytest.raises(ValueError):
PixelToAngle(1000.0, 0.0)
with pytest.raises(ValueError):
PixelToAngle(1000.0, math.pi)
with pytest.raises(ValueError):
PixelToAngle(1000.0, math.pi + 0.1)