1P by GN⁺ | ★ favorite | 댓글 1개
  • 3D 회전은 표현 방식마다 강점이 달라서, 점 변환에는 회전 행렬이 편하지만 보간·합성·평균에는 별도 도구가 필요함
  • Euler angles는 사람이 다루기 쉽지만 gimbal lock, 비상수 각속도, 최단 경로를 놓치는 선형 보간 문제가 생길 수 있음
  • 단위 quaternion은 slerp로 일정 속도 최단 경로 보간을 제공하지만, 벡터 공간이 아니어서 직접 저작·스칼라 곱·평균이 직관적이지 않음
  • 지수/로그 맵은 axis/angle 벡터와 회전 행렬을 연결해 R(t) = exp(t log(R1 R0^-1)) R0 형태의 2D·3D 최단 경로 보간을 구성함
  • 여러 회전의 평균은 단순 axis/angle 평균만으로는 catastrophic cancellation이 생길 수 있으며, Karcher mean은 각거리 제곱합을 최소화하는 회전을 반복적으로 찾아 더 일관된 결과를 냄

회전 표현별 장단점

  • 3D 회전에는 여러 표현이 있고, 변환·저작·보간·평균 중 무엇을 하느냐에 따라 적합한 선택이 달라짐
  • 회전 행렬

    • 가장 직접적인 선형대수 표현은 양의 행렬식을 가진 orthonormal 3x3 matrix
    • 회전 행렬의 세 열은 회전 후 x, y, z 축이 어디로 이동하는지 나타냄
    • 점 변환은 행렬 곱으로 처리할 수 있고, 다른 선형 변환과도 행렬 곱으로 합성 가능함
    • 화면에 그릴 때 회전 행렬을 쓰는 이유는 world-space에서 screen으로 점을 옮기는 데 하나의 행렬 곱만 필요하기 때문임
    • 회전 행렬은 벡터 공간이 아니므로 두 회전 행렬을 더해도 다시 회전 행렬이 되지 않음
    • 두 회전 행렬을 선형 보간하면 회전뿐 아니라 scaling이 섞일 수 있음
  • Euler angles

    • Euler angles는 x, y, z 축에 대한 세 회전을 지정하며 pitch, yaw, roll로도 불림
    • 세 구성 회전의 적용 순서는 관례에 따라 달라지고, 예시는 x, y, z 순서를 사용함
    • 사람이 이해하기 쉽고 회전 저작에 자주 쓰이지만, 단순 보간은 원치 않는 결과를 만들 수 있음
    • 한 구성 회전 때문에 나머지 두 회전축이 평행해지는 gimbal lock은 singularity에 해당함
    • singularity에서는 잠긴 두 각도 중 어느 쪽을 바꿔도 같은 출력 회전을 만들 수 있음
    • 보간 경로가 singularity에 도달하면 현재 위치를 표현하는 자유도가 늘어나고, 임의 표현을 골라 이어갈 때 출력 보간이 불연속이 될 수 있음
    • 각 구성 각도가 cyclic이기 때문에 선형 보간이 항상 두 회전 사이의 최단 경로를 고르지는 못함
    • 경로가 singularity를 지나지 않으면 보간은 매끄럽고, “straight up”과 “straight down”을 표현할 필요가 없다면 한계를 우회할 수 있음
  • Quaternions

    • 단위 quaternion은 회전 합성과 보간의 표준 도구로 쓰임
    • spherical linear interpolation, 즉 slerp는 두 quaternion 사이의 일정 속도 최단 경로를 선택함
    • 단위 quaternion도 벡터 공간이 아니며, 사람이 직접 저작하기 어렵고 보간 계산 비용이 들 수 있음
    • 스칼라 곱이나 평균에 대한 직관적 개념도 부족함
    • quaternion은 회전 공간을 double-cover하므로 경우에 따라 Q(1)-Q1으로 갈 수 있음
  • Axis/angle

    • axis/angle 회전은 실수 3D 벡터로 표현됨
    • 벡터의 방향은 회전축을, 크기는 그 축에 대한 회전 각도를 지정함
    • θu로 쓰며, u는 단위 벡터이고 θ는 회전 각도임
    • 3D 벡터이므로 벡터 공간을 이루며 더하기, 스케일링, 보간이 가능함
    • 두 axis/angle 회전을 선형 보간하면 매끄럽고 일정한 각속도를 줄 수 있음
    • 다만 목표 회전을 어떤 axis/angle 표현으로 지정하느냐에 따라 선형 보간이 최단 경로를 고르지 못할 수 있음
    • quaternion처럼 axis/angle 벡터도 회전 공간을 double-cover함

지수 맵과 로그 맵

  • 여러 회전 표현을 목적에 맞게 오갈 수 있으면 표현별 장점을 함께 사용할 수 있음
  • 최종 변환에는 회전 행렬이 필요하므로 행렬을 canonical form으로 둠
  • exponential map은 회전 객체를 받아 동등한 회전 행렬을 반환하는 함수임
  • logarithmic map은 회전 행렬을 받아 회전 객체로 되돌리는 대응 함수임
  • 여기서는 회전 행렬과 axis/angle 벡터 사이를 오가는 explog 맵을 다룸

2D axis/angle에서 출발하는 직관

  • 2D에서는 회전축이 평면 밖을 향하는 하나뿐이므로 axis/angle 회전은 각도 θ 하나로 표현 가능함
  • 2D 점 pθ만큼 회전한 는 다음처럼 쓸 수 있음
    • pθ = p cosθ + Jp sinθ
    • J는 2D 벡터를 90도 회전시키는 행렬임
  • J[[0, -1], [1, 0]]이고, J² = -I이므로 두 번 적용하면 180도 회전이 됨
  • 이 식을 전개하면 표준 2D 회전 행렬 [[cosθ, -sinθ], [sinθ, cosθ]]가 나옴

2D 지수 맵과 로그 맵

  • 복소수의 Euler 공식 e^(iθ) = cosθ + i sinθ에서 i가 quarter turn 역할을 하듯, 2D 행렬 식에서는 J가 같은 역할을 함
  • 지수 함수의 Taylor series에 행렬 A = θJ를 넣으면 행렬 덧셈, 곱셈, 스케일링으로 같은 계산을 수행할 수 있음
  • 전개 결과 sinθcosθ의 Taylor series가 나타나며 다음 식을 얻음
    • e^(θJ) = [[cosθ, -sinθ], [sinθ, cosθ]]
  • 따라서 2D 지수 맵은 각도 θ를 대응하는 회전 행렬로 변환함
  • 로그 맵은 지수 맵의 역으로 정의됨
    • R = exp(θJ)이면 log(R) = θJ
    • θ = atan2(R21, R11)로 복원 가능함
  • 지수 맵은 injective가 아님
    • exp(θJ) = exp((θ + 2π)J)이므로 한 바퀴를 더해도 같은 회전 행렬이 됨
    • 로그 맵은 해당 회전 행렬에 대응하는 가장 작은 각도를 반환하도록 정의함
    • atan2가 이 정의를 구현함

exp/log 기반 보간

  • 두 2D 회전 각도 θ0, θ1을 단순 선형 보간한 뒤 회전 행렬을 만들 수 있음
  • 그러나 θ0θ1π보다 멀리 떨어져 있으면 각도의 cyclic 성질을 반영하지 못해 긴 경로를 택함
  • exp/log 기반 보간은 두 회전 행렬 R0, R1에서 직접 이동 회전을 계산함
    • R1 R0^-1은 먼저 R0를 되돌리고 R1을 적용하는 회전임
    • log(R1 R0^-1)R0에서 R1로 가는 가장 작은 각도를 제공함
    • 이 axis/angle 회전을 t로 스케일한 뒤 exp로 다시 행렬로 바꿈
  • 최종 보간식은 다음과 같음
    • R(t) = exp(t log(R1 R0^-1)) R0
    • R(0) = R0, R(1) = R1
  • 2D에서는 각도 차이를 직접 확인해도 되지만, 이 방식은 수정 없이 3D와 임의 차원으로 일반화됨

3D axis/angle과 skew-symmetric matrix

  • 3D에서도 axis/angle θu를 지수화해 회전 행렬을 만들 수 있음
  • 핵심은 단위 벡터 u를 축으로 하는 quarter turn 변환을 찾는 데 있음
  • cross product u × pup가 만드는 평면에 수직인 벡터로 정의되지만, pu에 수직인 평면에 투영한 p⊥의 quarter turn으로도 해석할 수 있음
  • u × p와 같은 결과를 내는 행렬 û를 만들 수 있음
    • û = [[0, -uz, uy], [uz, 0, -ux], [-uy, ux, 0]]
    • ûp = u × p
  • ûᵀ = -û이므로 ûskew-symmetric matrix
  • 2D의 J도 skew-symmetric이고 2D cross product를 나타내므로 같은 구조가 이어짐
  • skew-symmetric matrix의 합과 스칼라 곱도 skew-symmetric이어서 axis/angle 벡터 공간 성질이 이 행렬 표현에서도 유지됨
  • û^(k+2) = -û^k라는 항등식은 cross product를 세 번 적용하면 p⊥를 세 번 quarter turn시켜 음의 quarter turn과 같다는 기하학적 해석에서 나옴

3D 지수 맵: Rodrigues’ formula

  • axis/angle 회전 θu에서 θû를 만들고 지수화하면 3D 회전 행렬을 얻음
  • Taylor series와 û^(k+2) = -û^k를 사용하면 다음 식이 도출됨
    • e^(θû) = I + sin(θ)û + (1 - cos(θ))û²
  • 이 식은 Rodrigues’ formula로 알려져 있음
  • θ = 0이면 e^(0û)p = p가 되어 점이 그대로 유지됨
  • θ = π/2이면 u × p + p∥가 되어 quarter rotation이 됨
  • θ = π이면 -p⊥ + p∥가 되어 half rotation이 됨
  • 이 행렬은 orthonormal임
    • AᵀA = I 조건을 ûᵀ = -ûû^(k+2) = -û^k로 확인함
  • 행렬식은 θ = 0에서 1이고, 행렬식이 0이 되는 경우가 없으며, expθû에 대해 연속이므로 음수가 될 수 없음
  • 따라서 exp(θû)는 3D 회전 행렬임

3D 로그 맵

  • 3D 지수 맵도 injective가 아니므로 3D 로그 맵은 주어진 행렬에 대응하는 가장 작은 크기의 axis/angle 회전을 반환하도록 정의함
  • R = exp(θû) = I + sin(θ)û + (1 - cos(θ))û²에서 trace를 취하면 회전 각도를 구할 수 있음
    • trace는 대각합임
    • tr(I) = 3
    • û는 skew-symmetric이므로 대각합이 0임
    • tr(û²) = -2
    • 따라서 tr(R) = 1 + 2cosθ
    • θ = arccos((tr(R) - 1) / 2)
  • 회전축은 R을 antisymmetrize해서 복원함
    • R - Rᵀ = 2 sin(θ)û
    • û = (R - Rᵀ) / (2 sinθ)
    • u = 1/(2 sinθ) [R32 - R23, R13 - R31, R21 - R12]ᵀ
  • 이렇게 3D 회전 행렬에서 axis/angle로 돌아가는 전체 로그 맵이 완성됨

3D 보간의 결과

  • 3D에서도 2D와 같은 보간식이 그대로 적용됨
    • R(t) = exp(t log(R1 R0^-1)) R0
  • 이 보간은 axis/angle 회전의 장점을 유지하면서 항상 최단 경로를 선택함
  • Euler angles로는 같은 예제가 매끄럽게 보이지 않을 수 있음

여러 회전의 평균

  • quaternion을 쓰면 좋은 보간을 얻을 수 있어 exp/log 행렬 수학 없이도 보간 문제는 해결 가능함
  • axis/angle 회전으로 더 쉽게 할 수 있는 작업 중 하나가 여러 회전 행렬의 평균
  • 가장 단순한 방법은 각 행렬을 axis/angle로 바꾸고, 벡터를 평균낸 뒤 다시 변환하는 것임
  • 이 방식은 유효하지만 직관적이지 않은 동작을 만들 수 있음
  • 특히 axis/angle 벡터를 합치면 catastrophic cancellation이 생길 수 있음
    • 예시는 [π, 0, 0][-π, 0, 0]을 평균내면 0이 되는 경우임
    • 두 값은 동등한 회전인데 평균 결과 0은 두 회전을 대표하지 못함

Karcher mean

  • 평면의 점 평균은 모든 점까지의 총 제곱거리를 최소화하는 점으로 볼 수 있음
  • 이를 반복 최적화로 찾는 절차는 다음과 같음
    • 초기 추정값 x̄ ∈ R²를 고름
    • 각 점에서 추정값까지의 translation ui = xi - x̄를 계산함
    • 벡터 평균 u = (1/n) Σ ui를 구함
    • x̄ = x̄ + τu로 평균 방향으로 이동함
    • |u| > ε인 동안 반복함
  • 같은 아이디어를 회전 R0, ..., Rn에 적용할 수 있음
    • 초기 추정 회전 R̄ ∈ R^(3×3)를 고름
    • 각 행렬에 대해 추정값에서 해당 회전까지의 axis/angle ui = log(Ri R̄^-1)를 계산함
    • 벡터 평균 u = (1/n) Σ ui를 구함
    • R̄ = exp(τu) R̄로 평균 회전 방향으로 이동함
    • |u| > ε인 동안 반복함
  • 이 알고리듬의 결과가 Karcher mean
  • Karcher mean은 다른 모든 회전까지의 제곱 각거리를 최소화하는 회전임
  • catastrophic cancellation을 받지 않아 항상 0이 아닌 중간 회전으로 수렴함
  • 단순 axis/angle 평균과 Karcher mean의 결과는 종종 비슷하지만, Karcher mean이 더 일관된 동작을 보임

Quaternion과 exp/log의 관계

  • 이 부분은 quaternion 지식을 전제로 함
  • 복소수 지수화가 skew-symmetric 2D 행렬 지수화와 동등했던 것처럼, quaternion 지수화는 skew-symmetric 3D 행렬 지수화와 동등함
  • 2D에서는 axis/angle 회전 θ로 pure-imaginary complex number 를 만들고 지수화함
    • e^(iθ) = cosθ + i sinθ
    • 결과는 점에 곱했을 때 θ만큼 회전시키는 복소수임
    • 항상 norm이 1이므로 2D 회전은 unit-norm complex number로 표현 가능함
  • 3D에서는 axis/angle 회전 벡터 u에서 pure-imaginary quaternion q = ux i + uy j + uz k를 만들 수 있음
  • quaternion 곱셈 규칙을 이용하면 q² = -||q||² = -θ²가 되고, 이는 skew-symmetric matrix에서 사용한 항등식과 닮아 있음
  • 지수화 결과는 다음과 같음
    • e^q = cosθ + (q/θ) sinθ
    • 2D 식과 거의 같지만 imaginary axis가 하나가 아니라 세 개임
  • 3D axis/angle 회전은 unit-norm quaternion으로 변환됨
  • rotation matrix가 필요 없다면 quaternion 지수 맵은 계산하기 쉬운 선택지임
  • quaternion 로그 맵도 단순함
    • θ = arccos(Re(q))
    • u = Im(q) / sinθ
  • quaternion q로 점 p를 회전하려면 conjugation q p q^-1을 계산함
    • p = px i + py j + pz k인 pure-imaginary quaternion으로 점을 표현함
    • conjugation은 기술적으로 u축에 대해 만큼 회전시키므로, 처음에 |u| = θ/2로 두면 됨

더 읽을거리

댓글과 토론

Hacker News 의견들
  • 리 군/리 대수 대응은 학교에서 배웠으면 좋았을 가장 멋진 개념 중 하나임. 글에서 말하는 지수 사상과 로그 사상이지만, 훨씬 재사용하기 좋은 형태로 나타남
    3D 회전처럼 다루고 싶은 추상 대상을 좌표의 세부사항에 휘말리지 않고 잡으면 그게 리 군이고, 거기서 잘 동작하는 좌표 표현을 유도하면 대응하는 리 대수가 됨
    그러면 좌표와 추상 대상 사이를 오가는 방법, 합성하는 방법 등이 거의 공짜로 생기며, 엔지니어링에서 자주 만나는 경우에는 보간과 평균도 꽤 합리적으로 처리 가능함
    문제를 리 군들의 조합으로 표현할 수 있으면, 각 대수가 무엇인지 찾아서 직접 하기엔 오래 걸릴 작업을 많이 절약할 수 있음
    여기서 대상은 매끄러운 변화 개념과 약간의 추가 구조가 있어야 하고, 오가는 과정에는 연결 성분 문제가 생기기도 하지만 이미 알려진 결과를 빌려 쓰기 좋은 이유이기도 함

  • 긴 한 주가 거의 끝나가는데, 슬라이더로 소를 회전시키는 게 딱 필요했던 휴식이었음

    • 숫자가 잔뜩 보이자마자 눈이 흐려졌지만, 소는 정말 귀여웠음
    • 저노력 iOS 캐시카우 게임으로 만들면 딱일 것 같은 느낌
  • 많은 3D 소프트웨어가 회전에 Arcball 인터페이스를 쓰지 않는 게 오래된 불만임
    Autodesk 제품인 3DSmax와 Maya는 쓰지만 Blender와 OpenSCAD는 안 쓰고, Roblox에서 일할 때도 기존 방식으로도 사용자들이 버틴다는 이유로 PM을 설득하지 못했음
    Arcball은 사원수 기반이고 보간에 지수 함수를 쓰며, 한 번의 드래그로 어떤 회전이든 가능하고, 짐벌락이 없고, 닫힌 루프를 그리며 드래그하면 시작 위치로 돌아온다는 성질을 가짐
    단위 사원수가 SO(3)의 2중 덮개가 된다는 사실에서 수학적으로 증명할 수 있고, 원 위 회전을 단위 복소수가 정확히 표현하는 것과 비슷함
    직접 만져볼 수 있는 사원수/Arcball 참고 구현: https://romankogan.net/math/arcball_js/index.html
    코드는 주석이 많은 Java이고 Processing 라이브러리를 ProcessingJS로 JavaScript에서 돌리는 형태임
    손과 몸은 뇌보다 먼저 사원수를 이해할 수 있으니, 3D 소프트웨어를 만든다면 이 방식을 써주면 좋겠음
    Arcball: http://courses.cms.caltech.edu/cs171/assignments/hw3/hw3-not...
    회전용 사원수: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotati...
    Processing의 Arcball: https://romankogan.net/math/arcball_js/index.html

    • 가운데가 아니라 오른쪽 같은 지점에서 드래그하면 왜 훨씬 나쁘게 느껴지는지 궁금함. 뭔가 걸린 느낌이 들고 가끔 튀는데, 회전을 계산하는 기준점이 바뀐다면 그 의미가 화면에 시각적으로 드러나야 할 것 같음
    • 모바일에서도 동작하게 만들 수 있을지 궁금함
      지금 모바일에서 보고 있는데, https://asliceofrendering.com/camera/2019/11/30/ArcballCamer...가 Arcball을 이해하는 데 도움이 됐음
  • 이 맥락에서 왜 사원수를 그렇게 좋아하는지 잘 모르겠음. 행렬이 사원수보다 덜 직관적이라고 보기 어려움
    행렬은 벡터에 작용하고, 회전도 벡터에 작용하니 회전을 행렬로 보는 것보다 자연스러운 게 뭔가 싶음
    행렬 지수도 상미분방정식과 연결하면 직관적임. dx/dt = Ax의 해는 exp(t A)이고, A가 반대칭이면 x의 변화는 항상 x에 직교하므로 길이를 바꾸지 않는 회전이 됨
    리 군/리 대수는 이를 크게 일반화하지만, 핵심은 직교하는 변화를 연속적으로 만들어 회전을 생성하고 지수 사상이 그 과정을 설명한다는 점임. 이 그림이 훨씬 기하학적이고 직관적으로 느껴짐

    • 사원수 자체도 Pauli 행렬처럼 행렬로 표현되는 경우가 많고, 이는 양자 스핀 모델링에 널리 쓰임
      사원수의 장점은 같은 행렬 곱셈을 손으로 계산하는 것보다 종이와 펜만으로 다루기가 더 쉽다는 점이라고 봄
      개인적으로는 복소수와 비슷한 의미에서 직관적임. 처음엔 이상했지만 지금은 아는 대안들보다 쓰고 추론하기가 더 단순하게 느껴짐
    • 글에서도 사원수가 행렬보다 갖는 큰 장점을 설명했음. 사원수는 보간이 잘되고 행렬은 그렇지 않음
      이 성질은 애니메이션이나 3D 스플라인 곡선을 따라 프레임을 계산하는 그래픽스 작업에서 매우 중요함
    • 계산 관점에서 사원수의 장점은 3x3 행렬의 9개 숫자 대신 4개 숫자만 쓰고, 회전 적용도 비슷하게 연산량이 줄어든다는 점임
    • 사원수의 핵심 장점은 회전 합성
      2D 회전을 복소수로 다루는 것과 비슷하게, 복소수 두 개를 곱하면 회전이 합성되고 2D에서는 편각이 더해지는 형태가 됨. 마찬가지로 사원수 두 개를 곱하면 3D 회전을 합성할 수 있고, 3x3 행렬 곱보다 훨씬 효율적임
      직관을 위해 말하면 사원수는 축-각 표현과 밀접하고, 이는 리 대수 so(3)와 같음
      벡터에 작용한다는 관점에서는 여러 회전 매개변수화를 같은 추상 Rotation 특성의 구현으로 보면 됨. 내부 구현이 행렬, 사원수, 오일러 벡터, 오일러 각, Gibbs 벡터든 간에 회전은 벡터에 작용하고 합성되는 방식이 같음
  • 단위 사원수는 리 군이고, 아무렇게나 더할 수 있는 것을 원한다면 회전 속도를 나타내는 전체 사원수의 리 대수를 봐야 함. 축-각도 회전 속도를 나타내는 것과 같음
    단위 사원수와 축-각을 비교하는 건 범주가 살짝 어긋나며, 단위 사원수는 회전 행렬과, 전체 사원수는 축-각과 비교하는 편이 더 적절함
    사원수를 쓰면 지수 사상을 쉽게 계산할 수 있다는 장점이 있지만, 사원수를 쓸 때는 회전 행렬이 거의 필요하지 않음. 글에서처럼 pqp^-1로 회전을 계산할 수 있음
    사원수를 이해하는 가장 쉬운 길은 기하 대수를 읽는 것이라고 봄. 사원수를 발명하는 데 수백 년이 걸렸지만, 놀라울 만큼 단순한 기하 대수를 이해하면 몇 분 안에 사원수를 재발명할 수 있음
    몇 년 전 좋은 입문으로 봤던 글: https://crypto.stanford.edu/~blynn/haskell/ga.html

    • 회전을 생각할 때는 여전히 지수 사상이 가장 견고한 방식이라고 봄. SO(3)의 리 군을 좌표 전환, 미분, 접공간 처리까지 가장 직접적으로 다룰 수 있게 해주기 때문임
      기하 대수의 여러 정식화를 거쳐도 결국 SO(3)/SE(3) 공간을 표현하기 위해 회전자와 모터를 쓰게 되고, 이는 각각 사원수와 쌍대 사원수에 동형임
      하지만 그 목적이라면 지수 사상을 곁들인 3x3 회전 행렬과 4x4 변환 행렬이 여전히 훨씬 유용하다고 봄. 사원수는 저장 공간이 적고 서로 곱하기도 빠르지만, 점을 변환할 때는 행렬이 더 빠르며 전체 효율은 상황에 따라 달라짐
    • 여기서 “전체 사원수”라고 한 게 순허수 사원수를 뜻한 건지 궁금함
  • 대학에서 배운 멋진 것 중 하나는 + 연산자를 행렬과 벡터 공간 변화량에 맞게, - 연산자를 두 행렬에 맞게 재정의하면 Kalman 필터 상태 안에 회전 행렬을 그냥 넣을 수 있다는 점이었음
    이렇게 하면 짐벌락 걱정 없이 회전을 추정할 수 있음
    https://openslam-org.github.io/MTK

    • SO(2)의 접공간을 상태로 둔다는 뜻인지 궁금함
    • 접공간에서 + 연산자를 구현하는 건 Kalman 필터뿐 아니라 비선형 최적화 전반에서도 꽤 흔함. Ceres 라이브러리도 이를 위한 LocalParameterization을 지원함
  • 정말 좋았고, 소 부분만 좋았던 게 아님
    특히 이 방법들이 결국 표준 회전 행렬을 계산한다는 점이 좋았음. 백만 개 벡터를 회전해야 한다면 흥미로운 계산은 한 번만 하고, 이후에는 고도로 최적화된 행렬 곱셈 파이프라인을 돌리면 됨

  • 멋진 블로그였는데, 작성자 프로필을 눌러 다른 글을 보다가 “2010년쯤 9살 때 프로그래밍을 처음 접했다”는 문장을 봤음
    나는 2010년에 13살이었고 중등학교 수학과 과학을 머리에 넣으려 애쓰고 있었음
    멋진 컴퓨터 그래픽스 관련 글을 볼 때마다 나보다 어리고 훨씬 재능 있는 사람이 쓴 것 같아 심한 열등감이 듦

    • 아직 늦지 않았음. 최근 몇 년 사이 독학으로 틈새 기술을 익혔고, 어떤 대기업이 그걸 돈 주고 쓰고 싶어 하는 듯함. 나이는 35세쯤임
      다만 어떻게 하라는 조언은 잘 못 하겠음. 그냥 그걸 정말 좋아해서 계속 했기 때문임. 그래도 구조화된 연습 같은 것도 통할 가능성은 있어 보임
  • 여러 회전의 평균을 구하는 방법을 찾다가 https://mathweb.ucsd.edu/~sbuss/ResearchWeb/spheremean/paper...를 찾았음
    이 글의 방법은 적어도 내 수학 수준에서는 그 논문보다 훨씬 쉬워 보임

    • 여러 회전의 평균을 구하려는 맥락이 궁금함
      평균은 합으로 할 수 있는 작업이고, 합에서는 합성 순서가 중요하지 않음. 하지만 회전은 교환법칙을 따르지 않아서 우리가 보통 이해하는 평균 개념이 그대로 적용되지 않음
      휴대폰을 들고 화면을 180° 돌려 멀어지게 한 뒤, 지면 기준 시계방향으로 90° 돌리면 카메라는 왼쪽을 향함. 반대로 같은 두 회전을 역순으로 하면 카메라는 오른쪽을 향함
      이 두 회전의 “평균”에서 카메라가 어디를 향해야 하는지에는 단일한 답이 없고, 평균에서 원하는 성질에 따라 달라짐
    • 며칠 전 평면 회전과 관련해 약간 곁가지인 댓글을 쓴 적이 있음. 평면에서는 훨씬 단순해지고, 프로그래밍 환경이 복소수 연산을 일급 기능으로 지원하면 특히 편해짐
      https://news.ycombinator.com/item?id=40333541
      핵심 직관은 덧셈은 평행이동이고 곱셈은 회전이라는 것임. 그래서 평균 평행이동에는 산술평균을 쓰고, 평균 회전에는 기하평균을 쓸 수 있음
  • 수학에서도 소프트웨어 공학에서 추상화를 떠올리는 것과 비슷하게 추상화를 만들어낸다는 걸 깨닫기까지 오래 걸렸음
    어릴 때는 왜 허수를 만들고, 행렬은 대체 무슨 의미가 있는지 헷갈렸음
    나중에야 이런 표현들이 설계된 것이라는 걸 알게 됨. 허수라는 것을 만들면 어떤 계산이 쉬워지고, 선형방정식을 행렬로 쓰면 전체를 풀어 쓰는 것보다 훨씬 추론하기 쉬워짐
    당연해 보이지만 아무도 이렇게 말해주지 않았음

    • 더 추상적인 수학을 공부해도 이 관점은 계속 맞음. 예를 들어 은 인터페이스이고, “어떤 군”은 필요한 세 가지 성질/메서드를 구현하는 연산을 가진 타입이라고 볼 수 있음
      벡터 공간, 환, 거리 공간, 범주도 마찬가지고, 수학은 설계 패턴으로서의 인터페이스로 가득함
      다만 수학의 인터페이스는 프로그래밍의 상속보다 타입 클래스에 더 가까움. 같은 집합/타입도 여러 방식으로 군이 될 수 있기 때문임