휘도와 조도 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""휘도와 조도 검증.
문서: 13.휘도와 조도 (예시로 보기, 정의, 카드 C2·C3)
주장:
1. 점광원(광도 I cd)에서 거리 d m 떨어진, 빛에 수직인 면의 조도는 E = I / d^2 lx다.
I = 100 cd이면 1 m에서 100 lx, 2 m에서 25 lx다. 거리가 2배면 조도는 1/4이다.
2. 빛을 모든 방향으로 고르게 되쏘는 면(완전 확산면)의 휘도는 L = rho * E / pi다.
E = 500 lx에서 흰 종이(rho = 0.8)는 약 127.3 cd/m^2, 검은 종이(rho = 0.05)는 약 8.0 cd/m^2다.
같은 조도에서도 휘도는 다르다.
3. 두 종이의 마이컬슨 대비 (Lmax - Lmin)/(Lmax + Lmin)는 조도와 상관없이
(0.8 - 0.05)/(0.8 + 0.05) = 0.882로 같다.
"""
import math
def illuminance(I_cd: float, d_m: float) -> float:
return I_cd / d_m ** 2
def luminance(rho: float, E_lx: float) -> float:
return rho * E_lx / math.pi
def michelson(l_max: float, l_min: float) -> float:
return (l_max - l_min) / (l_max + l_min)
def weber(l_target: float, l_background: float) -> float:
return (l_target - l_background) / l_background
def main() -> None:
assert illuminance(100, 1) == 100 and illuminance(100, 2) == 25
print("[OK] 100 cd: 1 m -> 100 lx, 2 m -> 25 lx")
white = luminance(0.8, 500)
black = luminance(0.05, 500)
assert abs(white - 127.32) < 0.01 and abs(black - 7.96) < 0.01
print(f"[OK] E=500 lx: 흰 종이 {white:.1f} cd/m^2, 검은 종이 {black:.2f} cd/m^2")
expected = (0.8 - 0.05) / (0.8 + 0.05)
for E in (50, 500, 5000, 50000):
c = michelson(luminance(0.8, E), luminance(0.05, E))
assert abs(c - expected) < 1e-12
print(f"[OK] 조도 50~50,000 lx에서 마이컬슨 대비 = {expected:.3f}로 일정")
w = weber(luminance(0.8, 500), luminance(0.05, 500))
assert abs(w - 15.0) < 1e-9
print(f"[OK] 검은 배경 위 흰 종이의 웨버 대비 = {w:.1f}")
# 카드 C2: 100 cd, 2 m -> 25 lx, 반사율 0.8 -> 약 6.4 cd/m^2
assert abs(luminance(0.8, illuminance(100, 2)) - 6.366) < 0.001
print(f"[OK] 카드 C2: 25 lx에서 흰 종이 {luminance(0.8, 25):.2f} cd/m^2")
print("ALL CHECKS PASSED")
if __name__ == "__main__":
main()