Страница 1 из 1

Дайте советов :)

СообщениеДобавлено: 03.02.2015 21:00:39
xterro
Доброго времени суток, в голове есть немного мешанины и вопросов, спешу поделиться и попросить совета.
Итак, вводная: есть несколько простых классов, реализующих мелкие примитивы, типа Line, Rect, Arc, Text... Так же есть класс Symbol, который содержит в себе список этих примитивов и при отрисовке всё это вылазит на канву, делая мне красиво. Каждый примитив имеется свои координаты, цвет, толщину линии etc. Вопросы будут по реализации и рисованию, кода не предоставляю, т.к вопрос концептуальный, мол, в правильном ли направлении двигаюсь 8)

0. Сейчас все эти примитивы, наследую от базового класса Primitive, он содержит основные свойства, типа цвет, толщина линии, тип примитива. Следует ли мне сделать его интерфейсом(IPrimitive), или тогда мне придётся одинаковые свойства переопределять в каждом классе-примитиве(типа Line) реализующем этот интерфейс одни и те же свойства?

1. Рисовать все эти примитивы думал с помощью OpenGL, отсюда появился вопрос: OpenGL умеет вращать, масштабировать объект(матрицу), можно ли после осуществления преобразования, т.е масштабирования, либо поворота, получить изменившиеся величины в матрице обратно в свой объект? При отрисовали скажем линию по координатам из полей объекта, повернули линию, и эти изменившиеся координаты записали назад в объект?

2. Проистекает из первого. Если так можно делать, то как лучше поступить, доверить трансформацию OpenGL и изменения записывать в объект или самому реализовать методы масштабирования, поворота? Также, насколько знаю, OpenGL может проверять попадание точки на примитив/рисуемый объект, стоит ли мне реализовывать свой HitTest в каждом примитиве, или доверить это OpenGL? У кого какие соображения на этот счёт?

3. Проверка попадания в примитив. Для простых примитивов делается просто, а для кривых, скажем арки, или кривой Безье, чуть по сложнее. Думаю, делать так, разделить рисование примитива на две части: расчёт массива точек и само рисование по ним. Соответственно проверка попадания будет сводиться к тому, что нужно пробежать по этому списку точек и проверит, не находится ли она рядом с проверяемой точкой. (Кривая рисуется как, т.е есть список точек, и рисование заключается в соединении последовательно всех точек линиями, 1-2, 2-3, 3-4 и т.д, получается кривая - или в данном случае проверять попадание нужной мне точки на каждую из этих прямых? )

Пока вроде это всё что накопилось :roll:

Re: Дайте советов :)

СообщениеДобавлено: 03.02.2015 23:21:00
скалогрыз
Советы:
-1. Если ты не работаешь в условиях сроков, то не бойся практиковаться. Т.к. опыт приходит только с практикой. Т.е. всё изложенное ниже ты мог бы написать, и попробовать использовать. Практикуясь всегда движешься в правильно направлении.
0. Если они наследуются от общего класса Primitive, то эти самые свойства у них всё-равно переопределены. Но мне кажется, если ты будешь всё рисовать через Symbol (или даже ISymbol?), то тебе IPrimitive вообще ни к чему.
1. Потенциально можно (разбирая матрицу на составляющие), но в реальности тебе это не нужно. А не нужно это как раз потому, что в OpenGL матрицу вращать ты будешь исходя из коордиантов объекта. Координаты первичны.
2. OpenGL не сделает hittest за тебя, так что "доверить" ты ему ничего не сможешь. HitTest через OpenGL делается через отрисовку (не на экран, а текстуру/память), а значит все вращения которые ты производишь при отрисовке, тебе необходимо повторять и при hitTest-е. Делать Hit-test не через OpenGL можно, но только если сам уверенно можешь просчитать кооридантные преобразования (в двух или трёх-мерном пространстве). Ну и конечно, если сцена не будет слишком сложной, а код не будет слишком тормозным :)
3. Всё именно так!
Математические функции и библиотеки обычно без труда находятся в интернете. за 20 лет люди много чего уже написали и выложили в свободное использование.

Re: Дайте советов :)

СообщениеДобавлено: 03.02.2015 23:26:56
xterro
У меня простое 2D. Т.е я понял, что операции, масштабирования, поворота и HitTest-а нужно реализовывать самому. Спасибо :roll:

Re: Дайте советов :)

СообщениеДобавлено: 03.02.2015 23:42:08
zub
0 как душе угодно
1 можно, но декомпозиция матрицы не всегда однозначна, емнип например нельзя отличить что было с объектом - отзеркаливание по двум осям или поворот на 180 градусов. подход правильный, т.к. всякие углы поворота нужны для наглядности пользователю, компу удобней работать с матрицами и координатами
2 в опенгл есть несколько режимов для хиттеста я когдато давно пробовал для этого glfeedback и gluPickMatrix, потом сделал руками - быстрее и предсказуемей. И да, опенгл не проверяет попадание точки куда либо, он проверяет попадание примитива в "область выбора"
3 да, както так

Re: Дайте советов :)

СообщениеДобавлено: 04.02.2015 00:31:16
yeger
Сам под 2д использую http://zengl.org/features_ru.html библиотеку. Коллизии, работа с примитивами и изображениями, даже физика - все есть и все кросс (включая андроид).

Re: Дайте советов :)

СообщениеДобавлено: 04.02.2015 06:33:17
sign
xterro писал(а):1. Рисовать все эти примитивы думал с помощью OpenGL, отсюда появился вопрос: OpenGL умеет вращать, масштабировать объект(матрицу), можно ли после осуществления преобразования, т.е масштабирования, либо поворота, получить изменившиеся величины в матрице обратно в свой объект? При отрисовали скажем линию по координатам из полей объекта, повернули линию, и эти изменившиеся координаты записали назад в объект?

Можете посмотреть в сторону BGRAControls.
Там есть всё, что вы хотите.
И 2D, и 3D, и градиенты, и всякие прочие всячины.
Для этого реализованы классы TBGRACanvas и TBGRACanvas2D.
Как всё работает хорошо видно из TBGRAShape.Paint.

Re: Дайте советов :)

СообщениеДобавлено: 04.02.2015 10:07:34
Дож
xterro писал(а):0. Сейчас все эти примитивы, наследую от базового класса Primitive, он содержит основные свойства, типа цвет, толщина линии, тип примитива. Следует ли мне сделать его интерфейсом(IPrimitive), или тогда мне придётся одинаковые свойства переопределять в каждом классе-примитиве(типа Line) реализующем этот интерфейс одни и те же свойства?


Если реализовывать интерфейс IPrimitive, то от него можно унаследовать класс TPrimitive, в котором реализовать все общие поля и свойства, поэтому проблемы с одинаковыми свойствами нет. Недостатком интерфейса является то, что при его использовании скрытые функции AddRef и Release будут отрабатывать при каждом вызове виртуального метода интерфейса, — это накладные расходы, особенно в многопоточных приложениях. И, кроме того, IPrimitive — ещё один уровень иерархии в программе.

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

Так что, отвечая на Ваш вопрос: скорее всего не следует.

Re: Дайте советов :)

СообщениеДобавлено: 04.02.2015 11:27:40
xterro
Дож, sign, yeger, zub Спасибо :)