Расчет положения элемента в фиксированной точке для рисования TFT - PullRequest
0 голосов
/ 27 января 2019

В настоящее время я пишу пользовательский интерфейс для небольшого проекта ОК.Возникли проблемы с вычислением положения вертикальной линии.Идея состоит в том, чтобы переместить красную линию вдоль оси x к концу прямоугольника.

Значение, которое увеличивается с помощью бесконечного поворотного энкодера и имеет диапазон от 0 до 800 с шагом 1. Левая сторона прямоугольника - это начало оси x, а также x = 0.диапазон 0–800 представляет 0–100,00 в нотации с фиксированной точкой Q13.3 с типом данных uint16_t.

Прямоугольник в настоящее время имеет ширину 300 пикселей, я гибок с этим, но он должен быть не менее 240 пикселей,Ширина строки составляет 1 пиксель.

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

enter image description here

То, что я сейчас делаю, - это счетчик, который увеличивается с каждым щелчком кодера.СТГ.например:

        if(direction) counter++;        //Running forwards
        if(!direction) counter--;       //Running backwards
        if((counter % 8 ) == 0){
            if(direction) line.x += 3;
            if(!direction) line.x -= 3;
        }

, что меньше оптимального, поскольку интервал составляет 3 пикселя.

В идеале, если бы вычисление с плавающей запятой было опцией, я бы просто увеличил счетчик на 0,375

Приветствую любые советы по этому вопросу.

ура

Ответы [ 2 ]

0 голосов
/ 28 января 2019

на очень маленьких мисро, вам нужно сделать несколько трюков:

uint8_t result;
static uint8_t counter1 = 0, counter2 = 0;

void handleEncoderTickUp(void)
{   
    if(++counter1 == 2) {result++; counter1 = 0;}
    if(++counter2 == 3) {result +=2; counter2 = 0;}
}

Очень похоже на обратный отсчет

0 голосов
/ 27 января 2019

Просто возьмите положение счетчика в единицах 0 ... 800 и уменьшите его до 0 ... width?

Т.е. умножьте значение счетчика на width и , затем сделайтецелочисленное деление на max, где max - это максимум вашего логического диапазона.

uint16_t scale(uint16_t value, uint16_t logical_max, uint16_t physical_max)
{
   uint32_t val = value * physical_max; // use a wider type to cope with overflow
   return (uint16_t) ((val / logical_max) & 0xFFFFU);
}
...