Рисование закрашенных кругов и треугольников на Raspberry Pi Pico с помощью MicroPython

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

Библиотека framebuf — это то, что, при разработке на MicroPython, даёт нам возможности по работе с основными графическими элементами. Например — с текстовыми символами, с прямоугольниками, да и с отдельными пикселями. Это позволяет создать множество интересных изображений. Но весьма полезно оснастить MicroPython ещё и возможность рисования закрашенных треугольников, кругов и колец.

Закрашенные круги

В этом руководстве речь пойдёт о реализации этих полезных мелочей. Здесь же будут продемонстрированы возможности недорогого цветного дислея, состыкованного с Raspberry Pi Pico.

Материалы


Дисплей и Raspberry Pi Pico

Для того чтобы воспроизвести то, о чём я расскажу, вам понадобятся следующие комплектующие и программы:

  • Программируемый микроконтроллер Raspberry Pi Pico.
  • Цветной LCD-дисплей Waveshare разрешением 160×80 пикселей с диагональю 0,96 дюйма, выполненный в форм-факторе модуля для Raspberry Pi Pico.
  • USB-кабель.
  • Редактор Thonny.

Шаг 1. Дисплей


Изображение, выведенное на дисплее

У выбранного мной дисплея имеются разъёмы, соответствующие пинам Pi Pico. Для соединения двух устройств достаточно лёгкого нажатия. Правда, не стоит нажимать на экран, давление надо прикладывать только к плате дисплея. Нужно, кроме того, правильно его ориентировать — так, чтобы джойстик находился бы с той стороны, где у Pi Pico расположен USB-разъём. Джойстик и кнопки, которыми оснащён дисплей, будут использованы в наших проектах в роли простых устройств ввода информации.

Обычно, когда рекламируют подобные дисплеи, на них выводят цветные фотографии. Наш дисплей вполне на такое способен. Снимок экрана, приведённый в начале раздела, это подтверждает. Ниже я расскажу о том, как это делается. Правда, большая часть этого материала посвящена не тому, как выводить на дисплей готовые изображения, а тому, как создавать и выводить что-то своё.

Шаг 2. Изучение документации


Справка по плате дисплея

Дисплей

Документацию по дисплею можно найти здесь. На неё стоит взглянуть.

Компания Waveshare предлагает пользователям пример программы с включённым в её состав драйвером дисплея, а не отдельную библиотеку для работы с дисплеем. (Мне нравится такой подход, так как он избавляет от необходимости постоянной возни с библиотеками при смене периферийных устройств).

Вот — моя, немного дополненная, версия этого примера. Она выводит линии и текст, поддерживает работу джойстика и кнопок. Драйвер — это самая важная часть программы. Его код нужно включать в состав всех программ, которые работают с дисплеем.

Шаг 3. Рисование кругов


Теорема Пифагора

Если нарисовать в круге радиус, а так же — вертикальные и горизонтальные линии, формирующие прямоугольные треугольники, можно воспользоваться теоремой Пифагора для того чтобы найди длину стороны a для любого значения i. Если нарисовать горизонтальные линии длины a в обоих направления от вертикального диаметра — они коснутся обеих сторон круга по его границе. Рисование последовательности таких линий, для каждой пиксельной строки, позволит закрасить круг.

def circle(x,y,r,c):
  lcd.hline(x-r,y,r*2,c)
  for i in range(1,r):
    a = int(math.sqrt(r*r-i*i)) # Теорема Пифагора!
    lcd.hline(x-a,y+i,a*2,c) # Нижняя половина
    lcd.hline(x-a,y-i,a*2,c) # Верхняя половина
    lcd.display()
    utime.sleep(0.1)

Если же нарисовать лишь конечные точки линий на границе круга — получится кольцо.

def ring(x,y,r,c):
  lcd.pixel(x-r,y,c)
  lcd.pixel(x+r,y,c)
  lcd.pixel(x,y-r,c)
  lcd.pixel(x,y+r,c)
  lcd.display()
  utime.sleep(0.1)
  for i in range(1,r):
    a = int(math.sqrt(r*r-i*i)) # Теорема Пифагора
    lcd.pixel(x-a,y-i,c)
    lcd.pixel(x+a,y-i,c)
    lcd.pixel(x-a,y+i,c)
    lcd.pixel(x+a,y+i,c)
    lcd.pixel(x-i,y-a,c)
    lcd.pixel(x+i,y-a,c)
    lcd.pixel(x-i,y+a,c)
    lcd.pixel(x+i,y+a,c)
    lcd.display()
    utime.sleep(0.1)

Шаг 4. Треугольники



Разобьём треугольник на две части горизонтальной линией. Закрасим его, двигаясь от верхнего угла вниз и от нижнего угла вверх

Рисование границ треугольника — задача очень простая. Это — всего лишь три прямых линии.

def triangle(x1,y1,x2,y2,x3,y3,c): # Рисуем границы треугольника
  lcd.line(x1,y1,x2,y2,c)
  lcd.line(x2,y2,x3,y3,c)
  lcd.line(x3,y3,x1,y1,c)

А вот рисование закрашенного треугольника — это уже гораздо более сложная задача. Подробности об этом можно почитать здесь.

Предлагаемый метод похож на тот, который мы использовали для закрашивания кругов — для закрашивания треугольника рисуют прямые линии, касающиеся его границ.

Эту задачу легче решить в том случае, если речь идёт о треугольнике, имеющем вертикальную верхнюю или нижнюю сторону. Если такой стороны у треугольника нет, то исходный треугольник можно разделить на две части горизонтальной линией и закрасить получившиеся треугольники по отдельности. Всё это звучит довольно-таки просто, но для практической реализации этого механизма нужна серьёзная математика. Правда, что хорошо, для того, чтобы пользоваться математикой, понимать её не обязательно. А именно, я создал команду, обращение к которой вызывает выполнение довольно-таки сложных действий.

c = colour(0,255,0)
tri_filled(x1,y1,x2,y2,x3,y3,c)
lcd.display()

Полный код можно найти здесь, а результаты работы кода показаны в видеофрагменте, приведённом в следующем разделе. В коде программы содержится несколько команд utime.sleep(0.1), предназначенных для того, чтобы замедлить работу кода до такого уровня, чтобы можно было бы наблюдать за происходящим.

Шаг 5. Замедленная видеосъёмка процесса вывода треугольника, круга и кольца


Замедленная видеосъёмка

Шаг 6. Эксперименты с дисплеем


Эксперименты с дисплеем

Обычно я, когда покупаю и исследую новый дисплей, а потом пишу об этом, включаю в статью раздел, в котором экспериментирую с этим дисплеем (эти эксперименты я называю «Workout-примерами»). Делаю я это для того, чтобы помочь разработчикам понять, подойдёт ли он для их проектов. Вот — такой раздел для дисплея, описываемого в этом материале. Он выполняет всё то, что выполняют другие исследованные мной дисплеи. Это позволяет сравнивать скорость вывода информации и качество формируемой картинки. Здесь я использую джойстик и кнопки, вывожу тригонометрические графики и нечто вроде столбчатых диаграмм, показываю текст разных размеров, градиенты, а теперь — и круги с треугольниками.

Надеюсь, вам понравилось то, что вы видели.

Программа, в которой всё это реализовано, получилась довольно длинной — 828 строк кода. Но её удалось уложить хотя бы в такой размер только благодаря тому, что этому миниатюрному экрану не нужен огромный фрейм-буфер. Это — реальный плюс экранов, состоящих из небольшого количества пикселей, если речь идёт о необходимости работы с большими объёмами графического кода.

Из кода этой программы, там, где выводятся круги и треугольники, убраны все задержки. Её скорость меня впечатлила, но в её распоряжении имеется очень небольшой буфер для копирования данных через SPI при каждой перерисовке экрана.

Шаг 7. Вывод фотографий



Фотография, выведенная на дисплее

На предыдущем рисунке показана фотография, которую я сделал в Катманду, в храмовом центре Сваямбунатх.

В исходном виде это был .RAW-файл, сформированный фотоаппаратом Canon. Для вывода фотографии на дисплее мне понадобилось выполнить следующие действия:

  1. Я преобразовал файл в формат JPG, обрезал картинку, выдержав соотношение сторон, соответствующее разрешению в 160x80 пикселей, а после этого изменил размер изображения до 160x80 пикселей. Я это делал в Photoshop, но то же самое можно сделать и в бесплатном редакторе Gimp.
  2. Я преобразовал файл в новый RAW-формат, где, вместо 3-байтового цвета используется 2-байтовый цвет.
  3. Файл был скопирован на Pi Pico с Raspberry Pi 4 с использованием rshell.
  4. Изображение было выведено на экран с использованием соответствующей программы и подходящего драйвера экрана.

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

Шаг 8. Компьютерная графика основана на математике


В этом проекте использовалось следующее:

  1. Базовая арифметика: счёт, вычисления, работа с процентными значениями, сравнение величин.
  2. Теория множеств: мэппинг и маскировка битов.
  3. Представление чисел в разных системах счисления при работе с битами и байтами: в двоичной, шестнадцатеричной и десятичной.
  4. Геометрия: круги, треугольники, прямоугольники, линии, точки.
  5. Координатная геометрия: рисование точек и отрезков.
  6. Теорема Пифагора.
  7. Тигонометрия: радианы, синус, косинус.
  8. Списки и суффиксы/указатели: байтовые массивы.
  9. Теория вероятностей: случайные числа.

Применяете ли вы Raspberry Pi Pico в своих проектах?

Источник: https://habr.com/ru/company/ruvds/blog/592199/


Интересные статьи

Интересные статьи

Мы представляем GANcraft — работающий без участия человека фреймворк нейронного рендеринга для генерации фотореалистичных изображений больших миров из 3D-блоков, например, таких, кото...
Привет, Хабр!Под катом вас ждёт описание разработки консольной утилиты, которая умеет показывать показывать погоду в нужных вам городах. Её можно будет запустить на Linux...
Хочу рассказать о своем небольшом опыте работы с Home Assistant (далее – HA) на Raspberry pi и о подключении функционала видео регистрации, датчика движения и, соответственно, функции охраны дома...
Юникод исключительно сложен. Мало кто знает все хитрости: от невидимых символов и контрольных знаков до суррогатных пар и комбинированных эмодзи (когда при сложении двух знаков получается третий)...
Изображение: Pexels Не все предприниматели знают об этом, но на современном фондовом рынке есть возможности для корпоративных инвестиций. Как же заработать дополнительных денег для компани...