1.0 Lession 1 Brensenham画线算法

[TOC]

参考资料

算法分析

算法代码

伪代码

function line(x0, x1, y0, y1)
     int deltax := x1 - x0
     int deltay := y1 - y0
     real error := 0
     real deltaerr := deltay / deltax    // 假設deltax != 0(非垂直線),
           // 注意:需保留除法運算結果的小數部份
     int y := y0
     for x from x0 to x1
         plot(x,y)
         error := error + deltaerr
         if abs (error) ≥ 0.5 then
             y := y + 1
             error := error - 1.0

一般化

void line(Vec2i p0, Vec2i p1, TGAColor color, TGAImage &image) {
    bool steep = std::abs(p1.y - p0.y) > std::abs(p1.x - p0.x);
    if (steep) {
        std::swap(p0.x, p0.y);
        std::swap(p1.x, p1.y);
    }

    if(p0.x > p1.x) {
        std::swap(p0, p1);
    }

    int dy = p1.y - p0.y;
    int dx = p1.x - p0.x;

    float derror = (float )std::abs(dy) / dx;
    float error = 0;
    int yStep = dy > 0 ? 1 : -1;
    float y = p0.y;
    for (int x = p0.x; x <= p1.x; x++) {
        if (steep) {
            image.set(y, x, color);
        } else {
            image.set(x, y, color);
        }

        error += derror;
        if (error > 0.5f) {
            error -=1;
            y += yStep;
        }
    }
}

最佳化

浮点数计算比较慢,换算成整数计算


void line(Vec2i p0, Vec2i p1, TGAColor color, TGAImage &image) {
    bool steep = std::abs(p1.y - p0.y) > std::abs(p1.x - p0.x);
    if (steep) {
        std::swap(p0.x, p0.y);
        std::swap(p1.x, p1.y);
    }

    if(p0.x > p1.x) {
        std::swap(p0, p1);
    }

    int dy = p1.y - p0.y;
    int dx = p1.x - p0.x;

    float derror = (float )std::abs(dy) * 2;
    float delta = dx * 2;
    float error = 0;
    int yStep = dy > 0 ? 1 : -1;;
    float y = p0.y;
    for (int x = p0.x; x <= p1.x; x++) {
        if (steep) {
            image.set(y, x, color);
        } else {
            image.set(x, y, color);
        }

        error += derror;
        if (error > dx) {
            error -= delta;
            y += yStep;
        }
    }
}