평균과 혼합(Averaging and Blending)

평균

초등학교로 돌아가서 평균을 구하는 방법을 떠올려 봅시다. 정말 기본적인 문제를 하나 내보겠습니다.

두 수의 평균을 구하는 방법은?

평균=(A+B)/2평균 = (A + B) / 2

평균을 구하는 공식을 조금 바꿔 보면 이렇게도 표현할 수 있습니다.

=(.5A)+(.5B)= (.5 * A) + (.5 * B)

역주) (A + B) / 2 = (A + B) * 0.5 = (0.5 * A) + (0.5 * B) 이기 때문입니다.

즉 평균이란 A의 절반과 B의 절반을 더한다 라고 말할 수 있습니다. 또는 A와 B를 50대 50으로 혼합한다 라고도 할 수 있습니다.

혼합

A와 B를 50대 50이 아닌 불규칙하게 혼합할 수도 있습니다. 가중치를 다르게 주는 방식인데 예를들어 30대 70, 10대 90등으로 말이죠.

(.35A)+(.65B)(.35 * A) + (.65 * B)

이 경우는 A의 35퍼센트, B의 65퍼센트가 혼합된 것입니다. 총 합이 100퍼센트(=1)인 범위내에서 양쪽의 가중치를 다르게 줄 수 있는 것이죠.

이 식에서 0.35 = s, 0.65 = t 라는 알파벳으로 대신 쓴다면 아래와 같은 식으로 바꿀 수 있습니다.

(sA)+(tB)(s * A) + (t * B)

특정 숫자대신 문자를 사용해 일반화 시킨다고 보면 됩니다. s 는 혼합할 A의양, t는 혼합할 B의 양이 됩니다. 그리고 아까 총합이 100퍼센트라고 정해놨기 때문에 s + t = 1이어야 할겁니다. 다시 말하면 s = 1 - t라고 볼수도 있죠. s 대신 1 - t를 넣어서 다시 써보면 이렇게 됩니다.

((1t)A)+(tB)((1 - t) * A) + (t * B)

이 공식을 사용하면 t의 값에 따라 혼합할 양을 조절할 수 있다는 의미가 되죠.

역주) 일반화 시킨다는건 프로그래밍으로 본다면 상수값을 하드코딩 하는 대신 변수를 사용하는 것이라고 생각하면 됩니다. 좀 더 이해하기 쉽게 코드로 나타내 보겠습니다.

float A = 10;
float B = 20;
float t = 0.65f;
float s = 0.35f;
float average = (s * A) + (t * B);
// average = 16.5

s = 1 - t 이므로 s대신 1 - t를 쓴다면 아래와 같은 코드가 됩니다.

float A = 10;
float B = 20;
float t = 0.65f;
float average = ((1 - t) * A) + (t * B);
// average = 16.5

정리해보면 이렇게 됩니다.

#1. A의 일부분과 B의 일부분을 혼합한다.
(s * A) + (t * B)  // s = 1 - t

또는 이렇게 표현하는 방법도 있습니다.

#2. A를 시작으로 A에서 B까지의 거리중 일부분을 더한다.
이 말을 공식으로 표현하면 이렇게 됩니다.
A + t * (B - A)

두 공식 모두 같은 결과를 나타냅니다. 예를들어 t = 0이라면 어떤 공식으로 계산하던 결과값은 A가 되죠.

(1.00A)+(0.00B)=A (1.00 * A) + (0.00 * B) = A

또는

A+0.00(BA)=AA + 0.00 * (B – A) = A

마찬가지로 t = 1이라면 혼합한 결과는 B가 됩니다.

(0.00A)+(1.00B)=B(0.00 * A) + (1.00 * B) = B

또는

A+1.00(BA)=A+BA=BA + 1.00 * (B – A) = A + B - A = B

아래 그림처럼 t라고 불리우는 손잡이가 있고, 그 손잡이를 조절하여 A와 B사이의 값을 얻을 수 있다고 생각하면 됩니다.

복잡적인 값의 혼합

단순히 숫자뿐만 아니라 복합적인 값도 혼합할 수 있습니다. 예를들면 두개의 3차원 벡터를 혼합하는 것이죠. 복합적인 값이라고 해서 특별한 공식을 사용하는것은 아닙니다. 단순하게 각 요소별로 모두 혼합을 적용시키면 됩니다.

P=(sA)+(tB)P = (s * A) + (t * B)

앞에서 봤던 혼합 공식입니다. 여기에서 A와 B에 숫자가 아닌 3차원 벡터를 넣는다면 이렇게 됩니다.

Px=(sAx)+(tBx)Px = (s * Ax) + (t * Bx)
Py=(sAy)+(tBy)Py = (s * Ay) + (t * By)
Pz=(sAz)+(tBz)Pz = (s * Az) + (t * Bz)

벡터의 예)

이처럼 단순한 값이 아닌 복합적인 값도 얼마든지 같은 방법으로 혼합할 수 있습니다. 하지만 모든 값들이 정확하게 혼합되는것은 아닙니다. 예를들면 RGB컬러값이나 오일러 각도, 행렬, 쿼터니온등은 이런 방식으로는 정확한 값을 얻을 수 없습니다.

만약 A = RGB(255, 0, 0) - 빨간색 B = RGB(0, 255, 0) - 초록색

일 때

t = 0.5 로 혼합한다면 그 결과는 RGB(127, 127, 0) 이 됩니다. 이 색상값은 0 ~ 255의 중간값이 맞지만 우리가 정말 원하는 색은 아닙니다.

우리가 원하는 색상은 바로 이것인데,

이런 색상이 나와버리는 것이죠.

RGB값과 같이 특별한 데이터의 경우, "정확하게 계산되는" 특정한 혼합 함수를 만드는것이 필요할 수 있습니다(예를들어, RGB값을 HSV방식으로 변경한 뒤 혼합을 하고 다시 RGB값으로 돌리는 방법을 생각해 볼 수 있죠).

Last updated