# 브레젠험

Bresenham의 라인 알고리즘이란 무엇입니까?

  • Bresenham Line Algorithm은 복잡하고 계산 속도가 느린 실수를 포함하는 계산을 제외하고 정수 계산만을 사용하여 직선을 그리기 위해 컴퓨터 그래픽에서 개발된 알고리즘입니다.

Bresenham 직선 알고리즘을 사용하는 이유는 무엇입니까?

  • 직선을 그릴 때 직선 방정식 ‘y = mx + b’를 사용하여 그릴 수 있습니다.
    그러나 이러한 직선 방정식을 그대로 플로팅하려면 실수를 사용해야 합니다.
    예전에는 실수연산의 성능이 좋지 않아서 최대한 정수연산만 사용했는데, 픽셀단위로 직선을 그릴때는 브레젠햄 직선알고리즘을 사용하는 것이 더 적절하다.
    실수가 있는 직선 방정식 대신 정수만 있는 직선. .

Bresenham 라인 알고리즘의 원리


  • Bresenham의 직선 알고리즘에서 위와 같이 기울기가 0보다 크고 1보다 작고(x0 + 1, y0 + 0.5) 선이 좌표 위에 있으면 y축의 픽셀 위치가 1만큼 증가하고 그 이하이면 증가하지 않습니다.
    한 점에 한 픽셀씩 그립니다.

기울기가 0보다 크고 1보다 작은 경우 Bresenham 라인 알고리즘의 판별식을 찾는 방법

// a는 기울기, b는 y절편입니다.
y = ax + b // x에는 +1, y에는 +0.5를 합니다.
(y + 0.5) = a(x + 1) + b; // y절편을 구하는 공식은 y - (h/w)x 입니다.
(h/w)(x + 1) + y - (h/w)x = (y + 0.5) // y가 더 클 경우 직선이 위에 있고, 더 작을 경우 직선이 아래에 있습니다.
(h/w)(x + 1) + y - (h/w)x < (y + 0.5) // y의 위치를 옮김니다.
(h/w)(x + 1) + y - (h/w)x - (y + 0.5) < 0 // 각 항에 w를 곱하여 분자를 없앱니다.
h(x + 1) + wy - hx - w(y + 0.5) < 0 // x와 y에 0을 대입하고, 소수점을 없애기 위해서 2를 곱합니다.
2h - w < 0
  • 위와 같이 기울기에 따라 판별식을 구할 수 있습니다.
    x가 1씩 증가할 때마다 판별식은 2h씩 증가하고, x와 y 값이 1씩 증가할 때마다 판별식은 2w+2h씩 증가합니다.
    즉, 2h – w < 0이 성립하지 않기 때문에 x와 y를 증가시키면 다음 판별식에 사용하기 위해 2h - w를 2h - 2w에 더해야 합니다.

Bresenham의 직선 알고리즘 코드

#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; }