이를 정수연산으로만 끝낼 수 없을까에서 나온 알고리즘이다.
실수연산이 정수연산에 비해서 매우 느린 것도 이유가 되고 어차피 화면에 그려질 때도 정수단위의 픽셀에 그려지기 때문에
정수연산만으로 처리하는 것이 더 좋다.
x의 변화량이 y의 변화량 보다 크다면
위와 같은 그림으로 그려지게 될 텐데 xi와 xi + 1까지는 y값이 yi에 더 가깝기 때문에 yi에 점이 그려지고
xi + 2때는 y값이 yi + 1에 더 가깝기 때문에 yi + 1에 그려져야 나름 부드럽게 보이는 선이 만들어지게 된다.
방정식에 의해 나온 y값이 정수값인 yi와 yi+1중 어디에 가까운지 판단하는 것 부터 아이디어를 뻗어나가면 된다.
위에 그림처럼 d1과 d2값을 구해 더 차이가 적은 쪽을 선택하면 된다.
직선의 방정식 : mx + b ( m은 기울기, b는 y절편 ) m = dy/dx
d1 = m(xi+1) + b - yi
d2 = (yi+1) - m(xi+1) - b
계산 한번으로 어디에 가까운지 판단하기 위해서 위 두 식을 합친다.
d1 - d2를 구해 이 값이 0보다 작다면 d1이 작다는 의미로 판단할 수 있고 0보다 크다면 d2가 더 작다는 것을 알 수 있다.
d1 - d2 = m(xi+1) + b - yi - ((yi+1) - m(xi+1) - b)
= m(xi+1) + b - yi - (yi+1) + m(xi+1) + b
= 2m(xi+1) + 2b - 2yi - 1
식을 x와 y값을 이용해서만 계산할 수 있게 하기위해 m = dy/dx를 넣어 정리해 준다.
d1 - d2 = 2(dy/dx)(xi+1) + 2b - 2yi - 1
해당 값의 부호만 판단하면 되기 때문에 굳이 코스트가 많이 드는 나누기 연산을 할 필요가 없다.
따라서 dx를 양변에 곱해준다.
dx(d1 - d2) = 2(dy)xi + 2dy + 2b(dx) - 2(dx)yi - dx
b, dx, dy값은 변화하지 않는 상수이므로 한번만 계산하면 된다.
위 식을 다시 이쁘게 정리해보자.
dx(d1 - d2) = 2(dy)xi - 2(dx)yi + 2dy - dx + 2b(dx)
= 2(dy)xi - 2(dx)yi + 2dy + dx(2b - 1)
위에 빨간색으로 밑줄친 부분은 선을 긋겠다고 마음 먹은 시점에 dx, dy, b값을 알 수 있기 때문에
계산을 하고 한 변수에 넣어 두면 된다. 식에서도 보기 쉽게 C로 정리하겠다.
dx(d1 - d2) = 2(dy)xi - 2(dx)yi + C
일단 1차적인 공식은 끝이 났다.
브레젠함 알고리즘은 이전 값을 이용하여 다음 값을 찾는 형식으로 루프를 돌게 되어있다.
이전 값을 Pi라 하고 그 이후의 값을 Pi+1이라 하자.
Pi = 2(dy)xi - 2(dx)yi + C
Pi+1 = 2(dy)xi+1 - 2(dx)yi+1 + C
이전 Pi값에 계속 값을 더해주어서 다음 값을 찾는 방법을 이용하기 때문에
더해주어야 되는 값을 구하기 위해 Pi+1 에서 Pi 를 빼보자.
Pi+1 - Pi = 2(dy)xi+1 - 2(dx)yi+1 + C - 2(dy)xi + 2(dx)yi - C
= 2(dy)(xi+1 - xi) - 2(dx)(yi+1 - yi)
지금은 dx가 dy보다 크다고 가정을 한 상태에서 식을 세우고 있기 때문에
xi+1 - xi = 1 이 된다. (무조건 한 칸씩 옆으로 가니까)
대신 y값은 이전과 같은 점일 수도 있고 한 칸 움직인 점일 수도 있다.
그렇기 때문에 위의 식에서 부터 두 가지 경우에 대한 식으로 정리할 수 있다.
1. yi+1 - yi = 0 일때 : 2(dy) -> Pi+1 = Pi + 2(dy)
2. yi+1 - yi = 1 일때 : 2(dy) - 2(dx) -> Pi+1 = Pi + 2(dy) - 2(dx)
이를 통해 다음 P값을 구할 수 있는 식을 구하게 되었다.
조건에 의해서 두 식중 알맞는 식을 골라서 사용해 나아가면 된다.
이런 점화식을 적용하기 위해서는 처음 값을 알아야 그 뒤부터 적용이 가능하다.
지금의 상황의 경우에는 처음 점을 (X1, Y1)으로 두고 그 다음 점을 (X1 + 1, Y1 + 1/2) 로 두고
구해내면 된다. (x는 1씩 증가하지만 y는 어떻게 될 지 모르기 때문에 절반 값을 넣어 줌)
위 점화식에 넣고 구해보면 최종적으로 처음 점은
P0 = 2(dy) - (dx)가 나온다.
지금까지 나온 값들을 적용해서 코드로 변경하면 된다.
참고 : http://forum.falinux.com/zbxe/?mid=graphic&page=3&document_srl=406146&listStyle=&cpage
위 사이트에 정리가 잘 되어 있어서 올립니다.
이 사이트에서 사용한 그림들도 위 사이트에서 사용한 그림을 이용하였습니다.
문제가 된다면 삭제하겠습니다.
'프로그래밍 > 소프트웨어 렌더링' 카테고리의 다른 글
Cohen–Sutherland algorithm_Wiki (0) | 2012.08.16 |
---|---|
소프트웨어 렌더링 공개 소스 코드 (0) | 2011.08.17 |
Clear함수 구현 (0) | 2011.05.17 |
시작하기 (0) | 2011.05.16 |
소프트웨어 렌더링 참고 링크 (0) | 2011.05.13 |