Распространение двумерного массива с использованием алгоритма линии Брезенхэма

В данный момент я пытаюсь нарисовать несколько угловых линий, используя алгоритм линии Брезенхэма, который может циркулировать в виде двумерного массива размером 21x21, как линия, расположенная под углом от 0 до 2pi.

строки из Брезенхема

Итак, идея состоит в том, что программа должна выводить значения, через которые проходят линии в сетке.

Так пример с 5х5

Angle:0
     _ _ _ _ _ 
    |_|_|_|_|_|
    |_|_|_|_|_|
    |_|_|.|.|.|
    |_|_|_|_|_|
    |_|_|_|_|_|

Angle: 45
     _ _ _ _ _ 
    |_|_|_|_|.|
    |_|_|_|.|_|
    |_|_|.|_|_|
    |_|_|_|_|_|
    |_|_|_|_|_|

и так далее..

Проблема здесь в том, что не похоже, что моя программа делает это. Конечная точка находится в пределах заданной длины радиуса.

Я уверен, что я запутался с математикой.. Поэтому я надеюсь, что некоторые из вас могли бы мне помочь здесь..

#include <iostream>
#include <math.h>
using namespace std;
typedef std::pair<int,int> coordinate;

int sign(double x ){ return (x > 0) ? 1 : ((x < 0) ? -1 : 0); }

coordinate endpoint(double angle, int x1 , int y1, int lenght)
{
    double radians = (M_PI/180)*angle;

    double x2 = x1 + (lenght * cos(radians));
    double y2 = y1 + (lenght * sin(radians));

    return std::make_pair(round(x2),round(y2));
}

void bresenham(coordinate start, coordinate end)
{
    //restriction a.x < b.x  and 0 < H/W < 1
    int y =  start.second;
    int w = end.first - start.first;
    int h = end.second - start.second;
    int f = 2*h-w; // current error term

    for (int x = start.first; x<= end.first; x++)
    {
        cout << "mark: " << x << "," << y << endl;
        if (f < 0)
        {
            f = f + 2*h;
        }
        else
        {
            y++;
            f=f+2*(h-w);
        }
    }
}


int main(int argc, const char * argv[])
{

    coordinate start = make_pair(0,0);
    for (int i = 0; i <= 45; i++)
    {
        coordinate end = endpoint(i,0,0,10);
        cout << "    endPos: "<< "(" << end.first <<","  << end.second   <<")"    << " Angle: " << i << "       " << endl;
        cout << "--------------------------------------------" << endl;
        bresenham(start, end);
        cout << "--------------------------------------------" << endl;
    }

    return 0;
}

Вот результат.

    endPos: (10,0) Angle: 0       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,0
mark: 6,0
mark: 7,0
mark: 8,0
mark: 9,0
mark: 10,0
--------------------------------------------
    endPos: (10,0) Angle: 1       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,0
mark: 6,0
mark: 7,0
mark: 8,0
mark: 9,0
mark: 10,0
--------------------------------------------
    endPos: (10,0) Angle: 2       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,0
mark: 6,0
mark: 7,0
mark: 8,0
mark: 9,0
mark: 10,0
--------------------------------------------
    endPos: (10,1) Angle: 3       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,1
mark: 9,1
mark: 10,1
--------------------------------------------
    endPos: (10,1) Angle: 4       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,1
mark: 9,1
mark: 10,1
--------------------------------------------
    endPos: (10,1) Angle: 5       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,1
mark: 9,1
mark: 10,1
--------------------------------------------
    endPos: (10,1) Angle: 6       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,1
mark: 9,1
mark: 10,1
--------------------------------------------
    endPos: (10,1) Angle: 7       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,1
mark: 9,1
mark: 10,1
--------------------------------------------
    endPos: (10,1) Angle: 8       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,0
mark: 4,0
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,1
mark: 9,1
mark: 10,1
--------------------------------------------
    endPos: (10,2) Angle: 9       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,1
mark: 4,1
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,2
mark: 9,2
mark: 10,2
--------------------------------------------
    endPos: (10,2) Angle: 10       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,1
mark: 4,1
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,2
mark: 9,2
mark: 10,2
--------------------------------------------
    endPos: (10,2) Angle: 11       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,1
mark: 4,1
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,2
mark: 9,2
mark: 10,2
--------------------------------------------
    endPos: (10,2) Angle: 12       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,1
mark: 4,1
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,2
mark: 9,2
mark: 10,2
--------------------------------------------
    endPos: (10,2) Angle: 13       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,1
mark: 4,1
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,2
mark: 9,2
mark: 10,2
--------------------------------------------
    endPos: (10,2) Angle: 14       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,0
mark: 3,1
mark: 4,1
mark: 5,1
mark: 6,1
mark: 7,1
mark: 8,2
mark: 9,2
mark: 10,2
--------------------------------------------
    endPos: (10,3) Angle: 15       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,1
mark: 5,2
mark: 6,2
mark: 7,2
mark: 8,2
mark: 9,3
mark: 10,3
--------------------------------------------
    endPos: (10,3) Angle: 16       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,1
mark: 5,2
mark: 6,2
mark: 7,2
mark: 8,2
mark: 9,3
mark: 10,3
--------------------------------------------
    endPos: (10,3) Angle: 17       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,1
mark: 5,2
mark: 6,2
mark: 7,2
mark: 8,2
mark: 9,3
mark: 10,3
--------------------------------------------
    endPos: (10,3) Angle: 18       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,1
mark: 5,2
mark: 6,2
mark: 7,2
mark: 8,2
mark: 9,3
mark: 10,3
--------------------------------------------
    endPos: (9,3) Angle: 19       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,1
mark: 5,2
mark: 6,2
mark: 7,2
mark: 8,3
mark: 9,3
--------------------------------------------
    endPos: (9,3) Angle: 20       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,1
mark: 5,2
mark: 6,2
mark: 7,2
mark: 8,3
mark: 9,3
--------------------------------------------
    endPos: (9,4) Angle: 21       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,2
mark: 5,2
mark: 6,3
mark: 7,3
mark: 8,4
mark: 9,4
--------------------------------------------
    endPos: (9,4) Angle: 22       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,2
mark: 5,2
mark: 6,3
mark: 7,3
mark: 8,4
mark: 9,4
--------------------------------------------
    endPos: (9,4) Angle: 23       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,2
mark: 5,2
mark: 6,3
mark: 7,3
mark: 8,4
mark: 9,4
--------------------------------------------
    endPos: (9,4) Angle: 24       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,2
mark: 5,2
mark: 6,3
mark: 7,3
mark: 8,4
mark: 9,4
--------------------------------------------
    endPos: (9,4) Angle: 25       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,2
mark: 5,2
mark: 6,3
mark: 7,3
mark: 8,4
mark: 9,4
--------------------------------------------
    endPos: (9,4) Angle: 26       
--------------------------------------------
mark: 0,0
mark: 1,0
mark: 2,1
mark: 3,1
mark: 4,2
mark: 5,2
mark: 6,3
mark: 7,3
mark: 8,4
mark: 9,4
--------------------------------------------
    endPos: (9,5) Angle: 27       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,2
mark: 5,3
mark: 6,3
mark: 7,4
mark: 8,4
mark: 9,5
--------------------------------------------
    endPos: (9,5) Angle: 28       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,2
mark: 5,3
mark: 6,3
mark: 7,4
mark: 8,4
mark: 9,5
--------------------------------------------
    endPos: (9,5) Angle: 29       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,2
mark: 5,3
mark: 6,3
mark: 7,4
mark: 8,4
mark: 9,5
--------------------------------------------
    endPos: (9,5) Angle: 30       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,2
mark: 5,3
mark: 6,3
mark: 7,4
mark: 8,4
mark: 9,5
--------------------------------------------
    endPos: (9,5) Angle: 31       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,2
mark: 5,3
mark: 6,3
mark: 7,4
mark: 8,4
mark: 9,5
--------------------------------------------
    endPos: (8,5) Angle: 32       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,3
mark: 5,3
mark: 6,4
mark: 7,4
mark: 8,5
--------------------------------------------
    endPos: (8,5) Angle: 33       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,1
mark: 3,2
mark: 4,3
mark: 5,3
mark: 6,4
mark: 7,4
mark: 8,5
--------------------------------------------
    endPos: (8,6) Angle: 34       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,6) Angle: 35       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,6) Angle: 36       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,6) Angle: 37       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,6) Angle: 38       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,6) Angle: 39       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,6) Angle: 40       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,2
mark: 4,3
mark: 5,4
mark: 6,5
mark: 7,5
mark: 8,6
--------------------------------------------
    endPos: (8,7) Angle: 41       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,3
mark: 4,4
mark: 5,4
mark: 6,5
mark: 7,6
mark: 8,7
--------------------------------------------
    endPos: (7,7) Angle: 42       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,3
mark: 4,4
mark: 5,5
mark: 6,6
mark: 7,7
--------------------------------------------
    endPos: (7,7) Angle: 43       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,3
mark: 4,4
mark: 5,5
mark: 6,6
mark: 7,7
--------------------------------------------
    endPos: (7,7) Angle: 44       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,3
mark: 4,4
mark: 5,5
mark: 6,6
mark: 7,7
--------------------------------------------
    endPos: (7,7) Angle: 45       
--------------------------------------------
mark: 0,0
mark: 1,1
mark: 2,2
mark: 3,3
mark: 4,4
mark: 5,5
mark: 6,6
mark: 7,7
--------------------------------------------

Что я делаю неправильно?... Я знаю, что алгоритм Брезенхэма, возможно, придется изменить, чтобы преодолеть наклоны больше 1 и ниже 0.

--Обновить Уточнить проблему--

Я пытаюсь выполнить итерацию массива 2d по кругу, используя алгоритм линии Брезенхема.

Алгоритм должен начинаться с центра массива 2d и «выстреливать» лучом под углами от 0 до 2pi. Луч должен начинаться из центра и заканчиваться на краю матрицы, надеюсь, это имеет больше смысла.

 _ _ _ _ _ _ _ _ _ _ _ 
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|.|.|.|.|.|.|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|

 _ _ _ _ _ _ _ _ _ _ _ 
|_|_|_|_|_|_|_|_|_|.|.|
|_|_|_|_|_|_|_|_|.|_|_|
|_|_|_|_|_|_|_|.|_|_|_|
|_|_|_|_|_|_|.|_|_|_|_|
|_|_|_|_|_|.|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|

person Community    schedule 08.12.2015    source источник
comment
Почему вы думаете, что делаете что-то не так? Выход выглядит разумным, насколько я вижу. Конечно, я не мог проверить каждый номер...   -  person Nico Schertler    schedule 08.12.2015
comment
Каждый выход должен содержать 10 точек данных. Следовательно, длина = 10. Но выходные данные от угла 0 до угла 17 имеют 11 точек данных.. и от угла 32 до 45 содержат менее 10 точек данных. Вот почему это так. делай как надо..   -  person    schedule 08.12.2015
comment
Нет, это абсолютно нормально. От (0, 0) до (10, 0) 11 точек. Если у вас очень малый угол, вы действуете по длине стороны пикселя. Если ваш угол равен 45°, вы действуете по диагонали пикселя, которая длиннее. Следовательно, вам нужно меньше пикселей по диагонали, чтобы достичь того же радиуса.   -  person Nico Schertler    schedule 08.12.2015
comment
хммм... но это не решает моей проблемы с взятием элементов только из центра и размещением всех элементов под определенным углом...   -  person    schedule 08.12.2015
comment
Может быть, вы хотите сэмплировать целевые точки на окружающем квадрате, а не на круге?   -  person Nico Schertler    schedule 08.12.2015
comment
я хочу попробовать точки, которые линия пересекает в матрице.. надеюсь, что добавление сделает его более понятным..   -  person    schedule 08.12.2015
comment
Тогда не используйте круг для создания целевых точек. Пройдите вдоль границы матрицы.   -  person Nico Schertler    schedule 08.12.2015
comment
как насчет угла?... и будет ли ваше решение похоже на ..   -  person    schedule 08.12.2015
comment
@ J.Down J.Down Правильно ли я предполагаю, что (0,0) находится в середине вашей матрицы, а не в углу? если нет, то вы также должны установить x1,y1 в середину матрицы...   -  person Spektre    schedule 09.12.2015
comment
(0,0) - это середина моей матрицы   -  person    schedule 09.12.2015


Ответы (1)


  1. У вас есть Брезенхэм только для первого октанта (dx>=0,dy>=0,dx>=dy)

    поэтому, когда вы используете углы за пределами <0,45> градусов, это не будет работать должным образом. У вас есть больше возможностей решить эту проблему:

    • use 8 branches each with own interpolation ( dx>=0, dx<0 combined with dy>=0, dy<0)
    • используйте 2 ветви ( |dx|>=|dy|, |dx|<|dy| ) здесь вместо x++,y++,x--,y-- используйте x+=sx,y+=sy вместо этого, где sx,sy - это направление шага, предварительно вычисленное перед интерполяцией. (в asm обычно используются автоматически изменяемые константы, но в C/C++ для этого нужны переменные)

    Не забудьте использовать в качестве основной оси интерполяции ось с большим абсолютным изменением. Таким образом, если (|dx|>=|dy|), то главная ось равна x, что означает, что x увеличивается (убывает) при каждом for проходе и y только в выражении if...

  2. конечная точка неверна

    Как отметил Нико Шертлер, конечные точки неверны. Используйте в качестве радиуса большую половину размера вашей матрицы и измените интерполяцию Брезенхема, чтобы она останавливалась, когда x или y выходит за пределы диапазона матрицы...

    Другой вариант - установить большую ось на край матрицы (зависит от октантов) и вычислить вторую ось через sin или cos (это треугольник 90 градусов)

person Spektre    schedule 09.12.2015
comment
Я не уверен, что вы имели в виду под большей половиной.. (0,0) я центр матрицы.. и, следовательно, каждая половина имеет одинаковую длину.. - person ; 09.12.2015