동차 좌표 예제 사다리 문서의 문제 4 풀이 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""동차 좌표 예제 사다리 문제 1~4 검증. 3×3 동차 좌표, 분수로 정확히."""
from fractions import Fraction as F
def mm(A, B):
return [[sum(A[i][k] * B[k][j] for k in range(3)) for j in range(3)] for i in range(3)]
def mv(A, p):
v = [p[0], p[1], 1]
return tuple(sum(A[i][k] * v[k] for k in range(3)) for i in range(2))
T = lambda a, b: [[1, 0, a], [0, 1, b], [0, 0, 1]]
S = lambda s: [[s, 0, 0], [0, s, 0], [0, 0, 1]]
R90 = [[0, -1, 0], [1, 0, 0], [0, 0, 1]]
Fx = [[1, 0, 0], [0, -1, 0], [0, 0, 1]]
def main():
# 문제 1: 점 (1, 1) 중심 2배 확대, 점 (3, 2)
H1 = mm(T(1, 1), mm(S(2), T(-1, -1)))
assert H1 == [[2, 0, -1], [0, 2, -1], [0, 0, 1]] and mv(H1, (3, 2)) == (5, 3)
# 문제 2: 점 (2, 0) 중심 90° 회전, 점 (3, 0)
H2 = mm(T(2, 0), mm(R90, T(-2, 0)))
assert H2 == [[0, -1, 2], [1, 0, -2], [0, 0, 1]] and mv(H2, (3, 0)) == (2, 1)
# 문제 3: 직선 y = 1에 대한 반사 다음 (3, 0) 평행이동, 점 (1, 4)
M = mm(T(0, 1), mm(Fx, T(0, -1)))
assert M == [[1, 0, 0], [0, -1, 2], [0, 0, 1]]
H3 = mm(T(3, 0), M)
assert H3 == [[1, 0, 3], [0, -1, 2], [0, 0, 1]] and mv(H3, (1, 4)) == (4, -2)
# 문제 4: 90° 회전 뒤 (1, 2) 이동, 역행렬과 되돌리기
H4 = mm(T(1, 2), R90)
assert H4 == [[0, -1, 1], [1, 0, 2], [0, 0, 1]] and mv(H4, (3, 4)) == (-3, 5)
H4i = mm([[0, 1, 0], [-1, 0, 0], [0, 0, 1]], T(-1, -2))
assert H4i == [[0, 1, -2], [-1, 0, 1], [0, 0, 1]]
assert mm(H4, H4i) == [[1, 0, 0], [0, 1, 0], [0, 0, 1]] and mv(H4i, (-3, 5)) == (3, 4)
print("ALL CHECKS PASSED")
if __name__ == "__main__":
main()