Перейти к публикации
Форум - ComputerCraft
Seryoga

[OC] GUI Library. Vector graphics. beta 0.0.2

Рекомендованные сообщения

    Последнее время пишется очень много GUI библиотек для open computers. Я решил не отставать от моды и начал разрабатывать свою библиотеку. Так как все гонятся за красивостью и универсальностью, я решил сделать упор на скорость рисования 2D объектов и их математических представлениях.

    В этой библиотеке содержится описание примитивных математических объектов: 

https://gist.github.com/DeveloperHacker/18e08fdfc2269f1ad5c8

  • Вектор

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Vector:new(x, y): Vector -- создаёт вектор с координатами x, y
    Vector:clone(): Vector -- создаёт копию текущего вектора
    Vector:sabs(): Double -- возвращает квадрат модуля вектора
    Vector:abs(): Double -- возвращает модуль вектора
    Vector:__add(v): Vector -- возвращает результат сложения двух векторов
    Vector:__sub(v): Vector -- возвращает результат вычитания двух векторов
    Vector:__mul(v): Double -- возвращает число, где знак это направление вектора результата, а модуль -- модуль этого вектора
    Vector:__unm(v): Vector -- возвращает противоположный вектор
    Vector:dot(v): Double -- возвращает скалярное произведение двух векторов
    Vector:cos(v): Double -- возвращает косинус угла между векторами
    Vector:scale(a): Vector -- возвращает вектор в а раз больший текущего
    Vector:rotate(theta): Vector -- возвращает вектор повёрнутый на theta радиан относительно данного вектора
    Vector.ceil(v): Vector -- возвращает вектор у которого координаты округлены до целого
    Vector:equals(v): Boolean -- возвращает результат сравнения двух векторов
    Vector:toString(): String -- приводит вектор к строке
    Vector:print(): void -- выводит координаты вектора

  • Отрезок

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Section:new(p1, p2): Section -- создаёт новый отрезок с концами в точках p1, p2
    Section:clone(): Section -- создаёт копию текущего отрезка
    Section:IsInside(p): Boolean -- возвращает результат проверки включения точки p отрезку
    Section.intersection(s1, s2): Boolean -- возвращает результат проверки пересечения двух отрезков
    Section:equals(v): Boolean -- возвращает результат сравнения двух отрезков
    Section:toString(): String -- приводит отрезок к строке
    Section:print(): void -- выводит координаты отрезка

  • Линия

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Line:new(s): Line -- создаёт линию проходящую через отрезок s
    Line:solve(p): Double -- ...

    Line:y(x): Double -- ...

    Line:x(y): Double -- ...

    Line:equals(l): Boolean -- возвращает результат сравнения двух прямых
    Line:toString(): String -- приводит линию к строке

    Line:print(): void -- выводит уравнение прямой

  • Ломаная

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Polyline:new(pos, outline): Polyline -- создаёт новую ломаную в точке pos где координаты остальных вершин находятся по координатам относительно точки pos, которые содержатся в массиве outline 
    Polyline:add(v): void -- добавляет координаты новой вершины

    Polyline:equals(poly): Boolean -- возвращает результат сравнения двух ломаных

  • Многоугольник

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Polygon:new(polyline): Polygon -- создаёт новый полигон на основе ломаную
    Polygon:rectangle(pos, width, height): Polygon -- создаёт прямоугольник
    Polygon:rightFigure(pos, qVertexes, radius, theta): Polygon -- создаёт правильную фигуру, где theta -- это угол отклонения первого угла от нормали   
    Polygon:convex(): Boolean -- возвращает результат проверки, того что полигон является выпуклым
    Polygon:height(): Double -- рассчитывает высоту полигона, лучше использовать поле с таким же названием

    Polygon:width(): Double -- рассчитывает ширину полигона, лучше использовать поле с таким же названием

    Polygon:isInside(v): Boolean -- проверяет принадлежит ли точка полигону

    Polygon:center(): Vector -- рассчитывает координаты центра полигона, лучше использовать поле с таким же названием 

    Polygon:rotate(origin, theta): Polygon -- возвращает результат поворота полигона на theta радиан относительно точки origin

   А также есть классы, которые участвуют в рисовании:

https://gist.github.com/DeveloperHacker/c54e3442202274b0ca9a

  • Цвет RGBA

    Color.decode©: int, int, int, int -- раскодирует укороченную запись цвета rgba
    Color.code(r, g, b, a): hex -- создаёт укороченную запись цвета rgba

    Color.decodeRGB©: int, int, int -- раскодирует укороченную запись цвета rgb

    Color.codeRGB(r, g, b): hex -- создаёт укороченную запись цвета rgb

    Color.toRGBA(rgb, a): hex -- создаёт укороченную запись цвета rgba на основе rgb и его alpha-канале 0 <= a <= 255 

    Color.toRGB(rgba): hex -- создаёт укороченную запись цвета rgb на основе rgba

    Color.mix(c1, c2): hex -- возвращает значение выражения (c1.alpha) * c1.rgb + c2.rgb, реализует полупрозрачное наслоение цвета c1 на цвет c2 

  • Matrix для рисования низкоуровневых объектов

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Matrix:new(x, y, w, h, gpu): Matrix -- создаёт новую матрицу, x, y координаты (в пикселях) позиции матрицы на экране

    Matrix:paint(): void -- рисует новые объекты на экран

    Matrix:repaint(): void -- полностью перерисовывает матрицу 

    Matrix:setBackground(rgba): void -- изменяет цвет фона
    Matrix:setBrush(rgba): void -- изменяет цвет кисти

    Matrix:drawPixel(x, y): void -- рисует пиксель на матрицу

    Matrix:drawLine(x1, y1, x2, y2, drawEndPixel): void -- рисует линию на матрицу, если drawEndPixel = false, то не отображается последний пиксель. 

    Matrix:drawPolyline(vectors): void -- рисует ломаную на матрицу, где в массиве vectors расположены вершины ломаной

    Matrix:drawPolygon(vectors): void -- рисует полигон на матрицу, где в массиве vectors расположены вершины полигона

    Matrix:clear(): void -- очищает матрицу
    Matrix:clone(): Matrix -- копирует матрицу
    Matrix:revert(prev): void -- откатывает матрицу self до матрицы prev

  • Painter для рисования высокоуровневых объектов

    Важно!! не изменяйте вручную поля классов. Это может привести к неопределённым ошибкам
    Painter:new(matrix, pos): Painter -- создаёт нового художника, где pos -- позиция матрицы в пространстве, где заданы фигуры 
    Painter:drawPoint(vector): void -- рисует точку на матрице

    Painter:drawLine(section): void -- рисует линию на матрице

    Painter:drawPolyline(polyline): void -- рисует ломаную на матрице

    Painter:drawPolygon(polygon): void -- рисует полигон на матрице 

    Вспомогательные программки без которых сложно, что либо проектировать:

https://gist.github.com/DeveloperHacker/5f4925b04a9524790036

  • Расширение gpu

    Future description

  • Программа для быстрой смены цвета текста и фона консоли, можно добавить изменение разрешения

    Future description

  • Программы для запуска файлов с расширением

    Future description

    Пример работы с моей библиотекой:

https://gist.github.com/DeveloperHacker/cc84c09a0980fcd21472

  • Рисование при помощи матрицы

    Future description

  • Рисование при помощи painter'а

    Future description

   В планах:

  • Написать документацию
  • Добавить проверку соседних пикселей 
  • Добавить закрашивание фигур
  • Добавить рисование растровых изображений
  • Добавить класс Intersector, он будет специализироваться на обнаружении наложений объектов и их пересечении
  • Добавить сохранение матрицы в растровом и векторном виде
  • Добавить закрашивание фона фигур и матрицы растровым изображением
  • Попробовать уменьшить пиксели до половины, как это сделал Zer0Gelaxy http://computercraft.ru/topic/1451-graficheskaia-biblioteka-graffiti/?do=findComment&comment=20699
  • Добиться максимальной производительности
  • Написать небольшой проект использующий эту библиотеку
  • Реализовать 3D

   Писал это библиотеку максимально гибко, поэтому возможна интеграция с другими Gui lib'ами. Если вам она понравиться, то я продолжу разработку в ускоренном темпе. Не откажусь от чьей либо помощи. Надеюсь вам понравится.

 

P.s моя реализация похожей библиотеки на языке java https://github.com/DeveloperHacker/2DEngine

post-10754-0-40287000-1455450225_thumb.png

Изменено пользователем Seryoga
  • Like 5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Векторная отрисовка - отличная идея. Но пока ничего не ясно. Не видно примеров, ни скриншотов, ни сравнения производительности с готовыми решениями.

Пожалуйста, добавь эти три пункта в первый пост. И не ссылками, а прямо на форуме.

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Используйте Gist, который в одном гисте может хранить тучу файлов, для скачивания же вот прога. А то мало того, что пост не до конца оформлен, так ещё и хост, с которого выгружал, заблочил.
 
Ну и скриншоты, доки, сравнения и человекочитаемый текст обязательно. Набор ссылок — meh.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Либа прикольная, только какой в ней смысл не понятно. Очень хочется вставить эту картинку:

 

 

d0e7323f980a.jpg

 

 

 

А так норм, сменя лайк и плюсик в репку.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Либа прикольная, только какой в ней смысл не понятно.

Попробуй запустить файл painter.test. Там ты увидишь два двигающихся объекта и много статических. + один из этих объектов полупрозрачный.

  1. Когда перемещаются эти объекты экран не мигает. 
  2. Простота анализа пересечений объектов. Например чтобы проверить пересекаются ли два прямоугольника, нужно написать кучу проверок. Здесь тебе нужно задать два прямоугольника и в цикле проверить входят ли углы одного прямоугольника в другой. При помощи метода isInside(Vector): Boolean. В будущем я добавлю функции по типу intersectionFF(Polygon2d, Polygon2d): Boolean и intersectFF(Polygon2d, Polygon2d): Polygon2d
  3. Объекты заданные векторно легко масштабируются, перемещаются, искривляются, поворачиваются и мн. др.
  4. Это всё упростит разработку редакторов и игр на луа
  5. и др...

 

Все тесты с циферками приведу позже, пока что все оценки скорости на глазок. Очевидно, что полное перерисовывание экрана каждый такт менее производительно, чем частичное перерисовывание. 

Изменено пользователем Seryoga
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Added an description of vector2d
Added an description of section2d
Added an description of line2d
Added an description of polyline2d
Added an description of polygon2d

Изменено пользователем Seryoga

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
........................ы.ыыыыыыыы......................

 

Я понимаю что оно делает, я не понимаю зачем оно это делает. Кому нужны квадратики и кружочки?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Серега, не слушай Лёшу, пиши документацию. Мне, к примеру, пока не понятно, как векторная графика связана с GUI?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Added an description of color
Added an description of pixel
Added an description of matrix
Added an description of painter

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Начнем с того, что тут мы имеем крайне медленную и неоптимизированную отрисовку: цвет фона меняется каждую итерацию в цикле. Например, если мы имеем в памяти линию красного цвета длиной в 150 пикселей, то куда грамотнее будет разово изменить цвет фона на красный, а затем выполнить gpu.fill(), нежели выполнять 150 итераций со сменой цвета и установкой пикселя (скриншот кода с гиста автора ниже). Это нехитрое действо сократит количество GPU-операций в десятки и сотни раз, учитывая размеры мониторов.

 

Далее рассмотрим таблицу matrix: во-первых, это трехмерный массив, что уже сильно повышает расход оперативной памяти: куда выгоднее сделать одномерную таблицу с последующим получением из нее нужных индексов. Во-вторых, в каждой подтаблице имеется отдельная boolean-переменная, отвечающей за смену пикселя. Это шутка такая? Боюсь себе представить, сколько памяти сжирают эти махинации.

 

7df06e65166fb8b9ba0c7c2ed3726351.png

 

Сильно не люблю критиковать других людей, но заявленным "упором на скорость рисования 2D-объектов" тут даже близко не пахнет. Плюс, реализация библиотеки с пародией на ООП лично у меня вызывают лютое отвращение: неудобно, некрасиво, куча лишнего кода при создании программ, бр-р-р. Кроме того, на форуме уже есть прекрасная графическая GML-либа: названия ее методов просты как божий день, да и графика рисуется в разы быстрее. Также рекомендую либу двойного буфера для максимальной скорости рисования.

 

В общем, шли бы лучше игрушки кодить для опенкомпов - и детишкам понравилось бы, и критики никакой не услышали бы, игры любят все, в любом виде!  :lol:

Изменено пользователем ECS
  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Крайне медленная и неоптимизированная отрисовка, цвет фона меняется каждый раз без проверки на соседние пиксели. Например, если мы имеем в памяти линию красного цвета длиной в 150 пикселей, то куда грамотнее будет разово изменить цвет фона на красный, а затем выполнить gpu.fill( ), нежели выполнять 150 итераций со сменой цвета (скриншот кода с гиста автора ниже). Это сократит количество GPU-операций в десятки и сотни раз, учитывая размеры мониторов. Так что "упором на скорость рисования 2D объектов" тут даже близко не пахнет, да и реализация библиотеки с упором на ООП у меня лично вызывают лютое отвращение: неудобно, некрасиво, бр-р-р. Кроме того, на форуме уже есть прекрасная графическая GML-либа: она написана куда приятнее, названия методов просты как божий день, да и прорисовка работает быстрее. Также рекомендую либу двойного буфера для максимальной скорости рисования. Шли бы лучше игрушки кодить для опенкомпов - и детишкам понравилось бы, и критики никакой не услышал бы, игры любят все!  :lol:

 

7df06e65166fb8b9ba0c7c2ed3726351.png

  1. Если тебе захочется нарисовать огромный прямоугольник, то можно сделать это за 1 операцию XD
  2. Упор идёт на динамические структуры. Я не спорю можно сделать анализ соседних пикселей, это в среднем сократит количество операций вдвое, хотя не факт. Так для рисования больших прямоугольников лучше использовать скомпилированные функции. Над чем я и работаю, просто сюда не добавил. Так как очень сырые.
  3. Ты нарисуешь один раз кучу объектов, подождёшь 0.1 сек, а дальше будет изменение 1 - 10 пикселей.

​Преимущества векторизации: 

  1. Возможность создания view-портов, что позволит только перемещать матрицу в мире, а не объекты. 
  2. Сейчас работаю над созданием матрицы у которой контур не прямоугольник, а полигон, что позволит создавать необычные сцены.
  3. Код легко расширяем, например чтобы сделать анализ соседних пикселей, я могу сопенсорсить твою функцию draw.
Изменено пользователем Seryoga

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Ты нарисуешь один раз кучу объектов, подождёшь 0.1 сек, а дальше будет изменение 1 - 10 пикселей.

 

А пиксели эти будут рисоваться с постоянной сменой цвета и фона, ага. Допустим, на экране изменился прямоугольник 5х2 синего цвета. Как будет работать твой код? Правильно, он выполнит 10 раз операцию gpu.setBackground() и 10 раз операцию gpu.set(), в то время как можно было бы всего лишь gpu.setBackground(); gpu.fill(). Напомню, каждая операция видеокарты - это реальные игровые тики, и при таком подходе к отрисовке любая более-менее сносная игра у тебя попросту будет фризится.

 

Кроме того, как я и сказал выше, у тебя крайне неразумен расход памяти. Надо скачать ради интереса твою либу и проверить, сколько памяти она сжирает при полноэкранных 160х50 отрисовках. Интересно, вылетит out of memory или нет? Как знать, как знать!

 


 

P.S. Боже упаси, 823 кбайта памяти сожрало! Изыди, изыди!  :D

 

491259dce35901551a1218ebfeb0bfff.png

Изменено пользователем ECS
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А пиксели эти будут рисоваться с постоянной сменой цвета и фона, ага. Допустим, на экране изменился прямоугольник 5х2 синего цвета. Как будет работать твой код? Правильно, он выполнит 10 раз операцию gpu.setBackground() и 10 раз операцию gpu.set(), в то время как можно было бы всего лишь gpu.setBackground(); gpu.fill(). Напомню, каждая операция видеокарты - это реальные игровые тики, и при таком подходе к отрисовке любая более-менее сносная игра у тебя попросту будет фризится.

 

Кроме того, как я и сказал выше, у тебя крайне неразумен расход памяти. Надо скачать ради интереса твою либу и проверить, сколько памяти она сжирает при полноэкранных 160х50 отрисовках. Интересно, вылетит out of memory или нет? Как знать, как знать!

Хорошо, в ближайшие дни добавлю анализ соседних пикселей.

Изменено пользователем Seryoga

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

pixel.lua удалён.
Изменена структура матрицы. Теперь она одномерная.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×