Рисование линий по данным о расстоянии и угле в полном круге - PullRequest
0 голосов
/ 02 мая 2020

краткий контекст

Я работаю над проектом гидролокатора. Компьютер получает два расстояния - от двух датчиков, обращенных в разные стороны - и данные угла. Расстояние будет расстоянием до ближайшего препятствия для данного угла. Нарисованная линия будет состоять из двух цветов, обозначающих известное свободное пространство и оставшийся заблокированный прицел. Все будет нарисовано в виде мозаичного круга.


задача

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

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


, где я дошел до сих пор

Скелет алгоритма выглядит так:

  • получить наклон (м) значение
  • сканирование по оси x
  • наложение y = m * x и выделение соответствующей плитки
  • , если текущий радиус больше расстояния, измените цвета
  • , если текущий радиус больше максимального радиуса. Завершить.

Кроме того, я не могу выполнить сканирование в диапазоне от -x до + x, так как для работы последнего оператора мне нужно работать с восходящими функциями. В противном случае он остановится еще до начала.

Как вы можете догадаться, этот алгоритм создает целую кучу проблем, когда он приближается к 90 градусам. Наклон становится огромным и мусор на 90 градусов, как и ожидалось, поэтому мне нужно иметь особые случаи и привязывать значение y к кругу.

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


ненужный контекст

Я использую C ++ и SDL2. Связанная часть кода выглядит следующим образом:

for ( x = 0; x < MAX_RADIUS, !improper; x += 0.01 )
{
    y = m*x;

    //Determine if the distance from first sensor or second sensor will be relevant.
    distance = y>=0 ? distance1 : distance2;


    //If the distance of obstacle is reached, change colors
    if ( y*y + x*x > distance*distance ) 
    {
        SDL_SetRenderDrawColor( renderer, SDL_WHITE );  
    }

    //If the current radius went out of range:
    if ( y*y + x*x > MAX_RADIUS_SQUARED )
    {
        //Clamp current point to the boundary of the circle, so it won't be invisible
        y = ( y/abs(y) ) * sqrt( MAX_RADIUS_SQUARED - x*x );

        //Break at next iteration. ( need to print clamped y )
        improper = true;
    }


    //Discard the remainder, otherwise it won't be tile based
    int temp_x = x - (int)x % TILE_LENGTH;


    //Render the current tile
    SDL_Rect temp = { temp_x+origin.x, -y+origin.y, TILE_LENGTH, TILE_LENGTH };
    SDL_RenderFillRect( renderer, &temp );  

    //Note: calculations are made in classical mathematical coordinate system (origin in middle),
    //whereas screen uses computer-like coordinate system (origin at top left)
    //this is why I am converting as: (x,y) --> (x + o(x), -y + o(y))

}

И есть еще один l oop, который идентичен, за исключением того, что он идет от -1 до -MAX_RADIUS.

Вот некоторые выводы:

Right: 60°   Left: 89°

Редактировать: Разрыв красной линии на правом изображении был вызван секундами для l oop, чтобы начать с -1, я изменил его на быть 0 и теперь оба начинаются с начала координат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...