브레젠험 직선(Bresenham’s Line) 알고리즘 이란?
- 브레젠험 직선(Bresenham’s Line) 알고리즘은 컴퓨터 그래픽스에서 복잡하고 계산을 느리게 만드는 실수 계산을 배제하고 정수 계산만으로도 직선을 그리기 위해 만들어진 알고리즘입니다.
브레젠험 직선 알고리즘을 사용하는 이유
- 직선을 그릴때 'y = mx + b' 직선 방정식을 통해서 그릴 수 있습니다. 하지만, 이러한 직선 방정식을 그대로 사용하여 그리게 될 경우 실수를 반드시 사용해야 됩니다. 과거에는 실수 연산이 성능이 좋지 않아서 되도록 정수 연산만을 사용하도록 하였으며, 픽셀 단위로 직선을 그려야 할 때는 실수를 사용하는 직선 방정식보다 정수만을 가지고 직선을 그릴 수 있는 브레젠험 직선 알고리즘을 이용하는 것이 더 적합합니다.
브레젠험 직선(Bresenham’s Line) 알고리즘 원리
- 브레젠험 직선 알고리즘은 위와 같이 기울기가 0보다 크고 1보다 작을 경우 (x + 1, y + 0.5) 좌표에서 직선이 위에 있을 경우 픽셀의 위치를 y축으로 1증가시켜 그리며, 아래 있을 경우 증가시키지 않은 위치에 픽셀을 그립니다.
기울기가 0이상 1 미만일 때 브레젠험 직선 알고리즘 판별식 구하는 방법
// a는 기울기, b는 y절편입니다.
1. y = ax + b
// x에는 +1, y에는 +0.5를 합니다.
2. (y + 0.5) = a(x + 1) + b;
// y절편을 구하는 공식은 y - (h/w)x 입니다.
3. (h/w)(x + 1) + y - (h/w)x = (y + 0.5)
// y가 더 클 경우 직선이 위에 있고, 더 작을 경우 직선이 아래에 있습니다.
4. (h/w)(x + 1) + y - (h/w)x < (y + 0.5)
// y의 위치를 옮김니다.
5. (h/w)(x + 1) + y - (h/w)x - (y + 0.5) < 0
// 각 항에 w를 곱하여 분자를 없앱니다.
6. h(x + 1) + wy - hx - w(y + 0.5) < 0
// x와 y에 0을 대입하고, 소수점을 없애기 위해서 2를 곱합니다.
7. 2h - w < 0
- 위와 같이 기울기에 따라서 판별식을 구할 수 있으며, x가 1씩 증가할 때마다 판별식이 2h씩 증가하고 x와 y값이 1씩 증가할 때마다 2w + 2h씩 증가합니다. 즉, 2h - w < 0이 성립하지 않아서 x, y를 증가시켰다면, 2h - w 에 2h - 2w를 더하여 다음 판별식에 사용해야 합니다.
브레젠험 직선 알고리즘 코드
#include <iostream>
using namespace std;
constexpr int MAX_LEN = 30;
int m[MAX_LEN][MAX_LEN];
void makeBresenhamLine(int startX, int startY, int endX, int endY)
{
int width = abs(startX - endX);
int height = abs(startY - endY);
int xFactor = startX > endX ? -1 : 1;
int yFactor = startY > endY ? -1 : 1;
if (width > height)
{
int y = startY;
int dest = 2 * height - width;
for (int x = startX; x != endX; x += xFactor)
{
m[y][x] = 1;
if (dest < 0)
dest += 2 * height;
else
{
y += yFactor;
dest += 2 * height - 2 * width;
}
}
}
else
{
int x = startX;
int dest = 2 * width - height;
for (int y = startY; y != endY; y += yFactor)
{
m[y][x] = 1;
if (dest < 0)
dest += 2 * width;
else
{
x += xFactor;
dest += 2 * width - 2 * height;
}
}
}
return;
}
int main()
{
int startX, startY, endX, endY;
cout << "시작 좌표와 끝 좌표를 입력해주세요 (x와 y의 최대 크기는 29입니다.)\n";
cin >> startX >> startY >> endX >> endY;
// y좌표 뒤집기
startY = MAX_LEN - startY - 1;
endY = MAX_LEN - endY - 1;
makeBresenhamLine(startX, startY, endX, endY);
for (int y = 0; y < MAX_LEN; ++y) {
for (int x = 0; x < MAX_LEN; ++x) {
cout << m[y][x] << " ";
}
cout << "\n";
}
return 0;
}
'알고리즘 & 자료구조' 카테고리의 다른 글
동적 계획법( DP : Dynamic Programming )이란? (0) | 2023.02.05 |
---|---|
그리디 알고리즘( Greedy Algorithm )이란? (0) | 2023.02.05 |
트리 순회( tree traversal ) 순회 방법 (0) | 2023.02.03 |
DFS( Depth Firsth Search )와 BFS( Breadth First Search ) (0) | 2023.02.03 |
인접 행렬(adjacency matrix)과 인접 리스트(adjacency list)란? (0) | 2023.02.03 |