Проблема в реализации алгоритма Брезенехема на C#

Рейтинг: 0Ответов: 1Опубликовано: 20.08.2023

Нашел на хабре код для реализации алгоритма Брезенхема на C#, одолжил и немного переписал под рисование в консоли. Проблема заключается в том, что реализованный метод не может рисовать прямую вертикальную линию. Подскажите что не так

Изначальный код:

 void BresenhamLine(int x0, int y0, int x1, int y1)
{
    var steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); // Проверяем рост отрезка по оси икс и по оси игрек
    // Отражаем линию по диагонали, если угол наклона слишком большой
    if (steep)
    {
        Swap(ref x0, ref y0); // Перетасовка координат вынесена в отдельную функцию для красоты
        Swap(ref x1, ref y1);
    }
    // Если линия растёт не слева направо, то меняем начало и конец отрезка местами
    if (x0 > x1)
    {
        Swap(ref x0, ref x1);
        Swap(ref y0, ref y1);
    }
    int dx = x1 - x0;
    int dy = Math.Abs(y1 - y0);
    int error = dx / 2; // Здесь используется оптимизация с умножением на dx, чтобы избавиться от лишних дробей
    int ystep = (y0 < y1) ? 1 : -1; // Выбираем направление роста координаты y
    int y = y0;
    for (int x = x0; x <= x1; x++)
    {
        DrawPoint(steep ? y : x, steep ? x : y); // Не забываем вернуть координаты на место
        error -= dy;
        if (error < 0)
        {
            y += ystep;
            error += dx;
        }
    }
}   

адаптированный:

void LinePainter(int[] X, int[] Y)
{
    var steep = Math.Abs(Y[1] - Y[0]) > Math.Abs(X[1] - X[0]);

    if (steep)
    {
        X[0] = Y[0];
        X[1] = Y[1];
    }
    if (X[0] > X[1])
    {
        X[0] = X[1];
        Y[0] = Y[1];
    }
    int dx = X[1] - X[0];
    int dy = Math.Abs(Y[1] - Y[0]);
    int error = dx / 2;
    int ystep = (Y[0] < Y[1]) ? 1 : -1;
    int y = Y[0];
    for (int x = X[0]; x <= X[1]; x++)
    {   
        error -= dy;
        if (error < 0)
        {
            y += ystep;
            error += dx;
        }
        DotPainter(x, y);
    }
}

метод отрисовки точек в консоли:

void DotPainter(int x, int y)
{
    Console.SetCursorPosition(x, y);
    Console.Write("*");
}

а вот что получилось после отрисовки линии с координатами xy0 = 0, 0; xy1 = 0, 10; это типо прямая вертикальная линия)

Ответы

▲ 0Принят

Метод Swap (исходя из названия) меняет переменные местами, однако вы их просто присваиваете. На самом деле это должно выглядеть примерно так:

    if (steep)
    {
        (X[0], Y[0]) = (Y[0], X[0]);
        (X[1], Y[1]) = (Y[1], X[1]);
    }
    if (X[0] > X[1])
    {
        (X[0], X[1]) = (X[1], X[0]);
        (Y[0], Y[1]) = (Y[1], Y[0]);    
    }