Разработка конструктора цветочных букетов
Анализ программных средств для разработки трехмерных моделей. Выбор языка программирования, инструментов, технологий. Разработка приложения для конструирования цветочных букетов. Проверка возможностей конструктора и корректности отображения компонентов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 28.05.2018 |
Размер файла | 1,0 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru
ВВЕДЕНИЕ
Цветочный бизнес в России широко представлен и занимает уже устоявшуюся нишу. Конкуренция среди фирм данного бизнеса подталкивает их к поиску новых информационных источников, в которых они могут показать себя. Хороший способ сделать это - создание сайта по продаже и доставке цветов, который может использоваться для привлечения клиентов даже из других регионов. К примеру, в настоящее время на рынке Москвы, занимающего 70% от объёма рынка России, не осталось предприятия, которое бы не осуществляло доставку цветов по всем городам России. Доставка цветов в междугороднем и международном сообщении пользуется большим спросом у конечного потребителя [1].
Очень интересный подход к созданию данного бизнеса представила компания «fl3ur»[2], которая разработала сервис по доставке цветов. В нем пользователю предлагают заказать уже составленный букет или использовать конструктор для создания собственного букета на основе существующего, либо с нуля. Сервис представляет собой мобильное приложение, написанное для платформы IOS, где для отображения букета применяется двухмерная графика. Конструктор «fl3ur» позволяет добавлять в букет цветы и зелень, изменять положение цветов, при этом положение зелени не изменяется, она отображается позади букета, и при вращении букета остается на месте неподвижным фоном.
Данный подход интересен и позволяет добавить сервису интерактивности, но использование двумерной графики не позволяет должным образом настроить букет и показать его максимально детально и реалистично. Отсюда возникает задача, создать приложение - конструктор цветочных букетов с использованием трехмерной графики и возможностью расширенной настройки букета, просмотра его со всех сторон и масштабирования.
Конструктор должен создавать круглые букеты спиральной скрутки, используя уже готовые трехмерные объекты цветов, зелени и декора, с возможностью расширенной настройки: должна быть предусмотрена возможность позиционирования элементов букета, изменения элементов букета по вылету, изменения радиуса букета. Цветы должны располагаться как отдельная единица, для которой можно задать позицию в букете, либо как база букета - множество единиц располагаются равномерно внутри букета, их позиция не изменяется, либо как каркас букета - множество единиц равномерно расположены по периметру букета, их позиция не изменяется. Декор располагается на месте соединения букета и никак не изменяет своей позиции. Для цветов и зелени должна быть предусмотрена возможность изменения положения по вылету.
Конструктор должен состоять из каталога, редактора и обозревателя. Каталог используется для добавления цветов, зелени и декора и представляет собой список из трех разделов, соответственно. Цветы и декор группируются по цвету, зелень по способу расположения. Редактор используется для изменения положения цветов и зелени, которые располагаются как отдельная единица, изменения по вылету цветов и зелени, изменения радиуса букета. Обозреватель используется для отображения трехмерных объектов цветов, зелени и декора, просмотра букета со всех сторон и масштабирования. Обозреватель букета должен быть реализован с помощью библиотеки Three JS. Для демонстрации возможностей конструктора должны быть разработаны трехмерные модели цветов зелени и декора.
Конструктор должен представлять собой модуль, который можно импортировать в HTML страницу, реализованный как класс на языке JavaScript, для вставки конструктора в страницу необходимо присоединить к странице файл который хранит класс. Трехмерные объекты, изображения и список всех цветов, зелени и декора, сохраненный в файле, должны храниться на сервере и загружаться по ходу работы.
Пояснительная записка состоит из введения, двух глав, тестирования и заключения. В первой главе рассматриваются применяемые программные средства и языки разработки. Во второй главе рассматривается принцип устройства приложения, основных его компонентов и взаимодействия их между собой. Тестирование предполагает проверку выполнения всех функциональных возможностей конструктора и правильности отображения всех его компонентов.
трехмерный программирование конструктор букет цветочный
1. СРЕДСТВА РАЗРАБОТКИ
1.1 Программные средства
1.1.1 JetBrains WebStorm
WebStorm - интегрированная среда разработки на JavaScript, CSS & HTML[3].
Главное достоинство WebStorm - это удобный и умный редактор, который обеспечивает автодополнение, анализ кода на лету, навигацию по коду, рефакторинг, отладку, и интеграцию с системами управления версиями. Важным преимуществом, повлиявшим на выбор этого средства разработки, является поддержка Node.js, а так же возможность модификация файлов .css, .html, .js с одновременным просмотром результатов - LiveEditor.
1.1.2 GIMP
Для работы с графическими файлами (необходимыми для должного оформления интерфейса приложения) был выбран GIMP. Выбор обусловлен тем, что это очень мощный инструмент, с которым у меня имелся опыт работы, к тому же - свободно распространяемый. GIMP(GNU Image Manipulation Program) -- многоплатформенное программное обеспечение для работы c изображениями[4]. Редактор GIMP возможен для составления множества задач и целей по редактированию рисунков. Программа GIMP имеет множество функций. Её также использовать как простой графический редактор, как профессиональное приложение для ретуши фотографий, как сетевую систему пакетной обработки изображений, как программу для воспроизводства изображений, как преобразователь форматов изображений и т.д.
1.1.3 Blender
Для разработки трехмерных моделей используемых в конструкторе мною был выбран редактор трехмерной компьютерной графики Blender. Blender -- свободный, профессиональный пакет для создания трёхмерной компьютерной графики, включающий в себя средства моделирования, анимации, рендеринга, постобработки и монтажа видео со звуком, компоновки с помощью «узлов» (Node Compositing), а также для создания интерактивных игр[5]. В настоящее время Blender пользуется наибольшей популярностью среди бесплатных 3D редакторов в связи с его быстрым и стабильным развитием, которому способствует профессиональная команда разработчиков. Кроме того для программы Blender в свободном доступе имеется множество плагинов для экспортирования графических сцен и трехмерных объектов в самых разных форматах.
1.2 Языки программирования и используемые технологии
В реализации дипломного проекта будут использоваться следующие инструменты и технологии:
· Язык разметки - HTML5
· Каскадные таблицы стилей - CSS
· Прототипно-ориентированный сценарный язык программирования - JavaScript
· Текстовый формат - JSON
· Библиотека для работы с трехмерной графикой THREE JS
· Формат импортирования трехмерных сцен Collada
1.2.1 HTML5
HTML -- язык для структурирования и представления содержимого всемирной паутины (HyperText Markup Language - “язык гипертекстовой разметки”) [6]. Изначально HTML представлял собой простой язык разметки, интерпретируемый браузером, а полученный в результате интерпретации текст отображался на экране, однако с выходом все новых версий он постепенно наращивал «мускулатуру». В настоящее время мы располагаем HTML пятой версии, заточенной под создание полноценных веб-приложений с поддержкой localStorage, 2D- и 3D- рисования, и автономного режима работы, сокетов, потоков.
В HTML5 реализовано множество новых синтаксических особенностей. Например, элементы <video>, <audio> и<canvas>, а также возможность использования SVG и математических формул. Эти новшества разработаны для упрощения создания и управления графическими и мультимедийными объектами в сети без необходимости использования сторонних API и плагинов. Другие новые элементы, такие как <section>, <article>, <header> и <nav>, разработаны для того, чтобы обогащать семантическое содержимое документа (страницы). Новые атрибуты были введены с той же целью, хотя последовательности элементов и атрибутов были удалены. Отдельные элементы, например, <a>, <menu> и <cite>, были модифицированы, переопределены или стандартизированы. API и DOM стали важнейшими частями спецификации HTML5. HTML5 также назначает некоторые особенности обработки промахов вёрстки, поэтому синтаксические ошибки должны подвергаться анализу в равной мере всеми совместимыми браузерами.
1.2.2 CSS
Дизайн конструктора реализован на языке каскадных таблиц стилей CSS (“Cascading Style Sheets”) - формальный язык описания и оформления внешнего вида документа, явившийся вследствие развития HTML[7]. Главной целью разработки CSS являлось разделение описания логической структуры веб-страницы (которое производится с помощью HTML или других языков разметки) от описания внешнего вида этой веб-страницы (которое теперь производится с помощью формального языка CSS).
Таблицу стилей необходимо написать только единожды при планировании сайта для всякого из устройств, на котором намечается вывод информации. К тому же - таблица стилей может быть единой для целого сайта. И, выходит, не нужно будет повторять одни и те же описания стилей на каждой из страниц. Размещение всей стилевой информации в одном внешнем файле раскрывает и другие полезные потенциалы - видоизменив содержимое только одного стилевого файла, можно сменить всю стилистику сайта. Причем никаких других изменений не потребуется. Использование CSS поможет увеличить доступность стилистики, предоставив возможности для управления его представлением, а также понизить сложность и повторяемость в структурном содержимом. Кроме того, CSS разрешает представлять один и тот же документ в различных стилях или методах вывода.
1.2.3 JavaScript
Класс конструктора реализован на языке JavaScript - это интерпретируемый язык программирования с объектно-ориентированными возможностями[8]. Прототипирование используемое в языке обуславливает отличия в работе с объектами по сравнению с традиционными класс-ориентированными языками. Кроме того, JavaScript имеет ряд свойств, присущих функциональным языкам -- функции как объекты первого класса, объекты как списки, анонимные функции, замыкания -- что придаёт языку дополнительную гибкость.
Несмотря на схожий с Си синтаксис, JavaScript по сравнению с языком Си имеет коренные отличия:
· объекты, с возможностью интроспекции;
· функции как объекты первого класса;
· автоматическое приведение типов;
· автоматическая сборка мусора;
· анонимные функции.
Целью разработки JavaScript было создание языка, встраиваемого в HTML. Изначально язык был назван LiveScript и предопределялся как для программирования на стороне клиента, так и для программирования на стороне сервера. Затем язык переименовали, и он заслужил громадную известность.
Современный JavaScript - это «безопасный» язык программирования общего назначения[9]. Он не предоставляет низкоуровневых средств работы с памятью, процессором, так как изначально был ориентирован на браузеры, в которых это не требуется. Уникальность данного языка программирования заключается в том, что он поддерживается практически всеми браузерами и полностью интегрируется с ними. Ни одна другая технология не вмещает в себе все эти преимущества вместе. К примеру, есть такие, которые не кросс-браузерны (то есть поддерживаются не всеми браузерами). Это -- VBScript, ActiveX, XUL. А есть такие, которые с браузером не интегрированы в нужной степени, это - Java, Flash, Silverlight.
JavaScript может выполняться не только в браузере, а где угодно, нужна лишь специальная программа - интерпретатор. Процесс выполнения скрипта называют «интерпретацией». Современные интерпретаторы перед выполнением преобразуют JavaScript в машинный код или близко к нему, оптимизируют, а уже затем выполняют. И даже во время выполнения стараются оптимизировать. Поэтому JavaScript работает очень быстро.
Для добавления JavaScript-кода на страницу, можно использовать теги <script></script>, которые рекомендуется, но не обязательно, помещать внутри контейнера <head>. Контейнеров <script> в одном документе может быть сколько угодно. Так же скрипт может быть перенесен в отдельный документ или расположен внутри тега.
С помощью Javascript можно изменять страницу, изменять стили элементов, удалять или добавлять теги. С его помощью можно узнать о любых манипуляциях пользователя на странице (прокрутка страницы, нажатие любой клавиши, клики мышкой, увеличение или уменьшение рабочей области экрана…). Через него можно к любому элементу HTML-кода получить доступ и делать с этим элементом множество манипуляций. Можно загружать данные, не перезагружая страницу, выводить сообщения, считывать или устанавливать cookie и выполнять множество других действий.
1.2.4 JSON
Так как приложение предполагает работу с уже готовым списком моделей букета, а так же задачей при разработке конструктора являлось разработать приложение, которое можно удобно и просто импортировать как модуль в веб страницу, решено было отказаться от использования базы данных в пользу формата JSON. JSON -«родной» формат JavaScript, а проект как раз на JavaScript. JSON - текстовый формат обмена данными, основанный на JavaScript[9] и обычно используемый именно с этим языком. Как и многие другие текстовые форматы, JSON легко читается людьми. Для многих языков существует готовый код для создания и обработки данных в формате JSON.
1.2.5 THREE JS
Трехмерное представление букета реализовано с применением технологии WebGL - это технология рисования, отображения и интерактивного взаимодействия с трехмерной компьютерной графикой в веб-браузерах[10]. Технология WebGL поддерживается всеми современными браузерами. Программирование WebGL напрямую, однако, является очень сложным. Необходимо знать внутренние детали WebGL и изучать сложный язык затенения, чтобы получить максимальную отдачу от WebGL. В своей работе я использую фреймворк для упрощенной работы с WebGL, под названием THREE.JS, который обеспечивает очень простой в использовании JavaScript API, не углубляясь в особенности WebGL.
Three.js -- легковесная кроссбраузерная библиотека JavaScript, используемая для создания и отображения анимированной компьютерной 3D графики при разработке веб-приложений[11]. Three.js скрипты могут использоваться совместно с элементом HTML5 CANVAS, SVG или WebGL. Библиотека Three.js поставляется в одном JavaScript файле, который может быть подключён к странице в любом месте. Three.js позволяет создавать ускоренную на GPU 3D графику, используя язык JavaScript как часть сайта без подключения проприетарных плагинов для браузера.
1.2.6 COLLADA
COLLADA -- это открытый стандарт файлов для интерактивных 3D приложений базирующийся на формате XML[12].
Расширяя формат XML, COLLADA позволяет разработчикам свободно обмениваться данными различным приложениям, работающим с 3D графикой, и при этом иметь минимальную потерю данных. COLLADA допускает передачу таких данных, как объекты и их трансформация, материалы и текстуры, источники освещения и камеры, анимация.
Начиная с версии 1.5.0, формат COLLADA для обмена данными между приложениями для работы с 3D признан сериями международных стандартов, такими как ISO, PAS. На данный момент COLLADA поддерживается большим количеством программ, включая Blender, что делает его очень гибким форматом.
2. РЕАЛИЗАЦИЯ ПРИЛОЖЕНИЯ
2.1 Архитектура приложения
Конструктор цветочных букетов представляет собой клиент-серверное приложение, в котором клиентом выступает браузер, а сервером - веб-сервер. Логика приложения реализована на стороне клиента, хранение данных осуществляется, преимущественно, на сервере. Клиент запрашивает файлы изображений, трехмерных объектов и конфигураций букета и выполняет дальнейшие манипуляции с ними. Сервер обрабатывает запросы клиента и выполняет передачу данных.
Рис. 1. Диаграмма архитектуры «клиент-сервер».
Если пользователь хочет выполнить добавление новой модели в букет или произвести загрузку конфигурации букета, он через браузер взаимодействует с конструктором (клиентом), клиент посылает HTTP GET запрос серверу и тот возвращает ему необходимую информацию.
Конструктор представляет собой модуль, импортируемый в код веб-страницы. Добавление происходит в 2 этапа: первый - присоединение к коду страницы JS-файла с классом конструктора, второй - создание объекты класса конструктор. Класс конструктора реализован на основе DomElement, который будет использован как контейнер для отображения. Для создания объекта класса конструктор, ему необходимо передать DomElement. После чего конструктор выполняет загрузку CSS-файла, JS-файлов, JSON-файла и необходимые png, jpeg, gif изображения. Наглядная схема загрузки представлена на рисунке 2.
Рис.2. Схема добавления конструктора на страницу.
Визуально конструктор можно разделить на три блока: каталог, редактор и обозреватель, помимо которых, существует блок конфигурации, скрытый от нашего взгляда. Каталог реализован в функциональном стиле, а редактор, обозреватель и конфигурация в стиле ООП.
Рис. 3. Интерфейс конструктора.
Каждый из блоков, представляет собой DomElement, дополненный методами и функциями, обработчиками событий, или объект класса, имеющий аналогичные функции и методы. Обработчики событий одних блоков конструктора, вызывают методы других полей конструктора - таким образом, достигается их взаимодействие. Взаимодействие блоков наглядно представлено на рисунке 4.
Рис. 4. Диаграмма взаимодействия блоков конструктора.
Каталог представляет собой список моделей, с возможностью группировки моделей по типу и группе. В каталоге определено событие выбора модели. В случае выбора происходит добавление новых элементов в редактор, обозреватель и конфигурацию. Редактор используется для позиционирования, а так же удаления элементов. В блоке редактор определено событие перемещения изменение по вылету, изменения радиуса и удаления, каждое из которых сопровождается изменением конфигурации и обозревателя. Блок редактора не имеет отдельной программной реализации, он состоит из макета, слайдера изменения радиуса и слайдера изменения вылета, эти компоненты выделены в отдельный блок логически. Обозреватель используется как средство для просмотра букета, в нем определено событие поворота, в случае возникновении которого происходит поворот макета редактора. Блок конфигурации используется для хранения данных о текущих добавленных моделях, их положении в букете и радиуса букета.
Все взаимодействующие элементы обмениваются координатами положения моделей, и значениями радиуса букета, которые вычисляется с условием, что максимальный радиус букета равен 1, и значениями смещения модели по вылету в диапазоне от -1, соответствующей минимальному смещению, до 1, соответствующей максимальному смещению. Такой подход позволяет избежать дублирования полей конфигурации, и упростить обмен данными между элементами. Данные значения называются значениями конфигурации.
Информация об имеющихся моделях хранится в JSON-файле в виде массива коллекций, имеющих поля:
· idModel - уникальный идентификатор модели,
· name - имя модели,
· group - группа модели,
· type - тип модели (цветы, зелень или декор),
· img - ссылка на изображение,
· src - ссылка на трехмерный объект,
· positionType - тип расположения модели,
· numberOfUnits - число элементов.
Таблица 1. Типы расположения моделей |
||
unit |
Трехмерный обьект отображается как отдельная единица, есть возможность изменения позиции внутри букета, изменения вылета. |
|
staticUnit |
Трехмерный обьект располагается в месте соединения букета, изменения расположения и изменения по вылету не предусмотрено, данный тип расположения применяется только к декору. |
|
base |
Заданное количество копий трехмерный объектов равномерно располагаются внутри букета, есть возможность изменения по вылету, расположение изменяется вместе с изменением радиуса букета. |
|
frame |
Заданное количество копий трехмерный объектов равномерно распределяется по периметру букета, есть возможность изменения вылета, расположение изменяется вместе с изменением радиуса букета. |
2.2 Глобальные функции
ajaxGetRequest(url : строка, handler : функция) - функция используемая для создания HTTP GET запроса, в качестве параметров передаются ссылка на загружаемый файл и функция обработчик события успешной загрузки в которую передается текст файла.
fixWhich(e : MouseEvent) - для события нажатия кнопки мыши функция создает свойство which из свойства button, если его нет.
isIE() : булевое значение - функция возвращает истину, если текущий браузер InternetExplorer.
fixInputAndChangeEvents() - функция объявляет события ввода и изменения для всех DOM элементов input типа range, использует функцию isIE().
sphereToDecart(phi : число, theta : число, r : число) : коллекция{x,y,z} - функция перевода сферических координат в трехмерные декартовые.
decartToSphere(x : число, y : число, z : число) : коллекция{phi ,theta,r} - функция перевода трехмерных декартовых координат в сферические.
2.3 Класс Constructor
Конструктор представляет собой класс, использующий DomElement, как контейнер для отображения конструктора, который передается как параметр при создании объекта класса Constructor.
Конструктор класса выполняет загрузку файлов со стилями, классами и информацией о моделях, после чего выполняется инициализация. Конструктор создает и компонует все визуальные элементы внутри контейнера для отображения конструктора, и присваивает им стили. Создает объекты каталога, макета, слайдеров, обозревателя и конфигурации и переопределяет обработчики событий, связывая их с методами других объектов. На последнем шаге инициализации происходит загрузка конфигурации по умолчанию и её установка.
Таблица 2. Поля и методы класса Constructor |
||
Поля |
_MODELS[] : массив коллекций - массив хранящий информацию о моделях; _config : Configuration- конфигурация; _layout : Layout - макет; _shiftSlider : DomElement - слайдер изменения вылета; _radiusSlider : DomElement - слайдер изменения радиуса; _viewer : Viewer -обозреватель; _curIdConf : число -идентификатор конфигурации выбранного элемента; |
|
Методы |
_init(div) - инициализация конструктора; _initCatalog(), initCatalogMenu(), _createCatalogMenuItem(name, image), _initCatalogList(), _createCatalogListItem(name, image, options) - методы инициализации и создания каталога и его элементов; _getModelByIdModel(idModel) - получение элемента массива моделей по заданному идентификатору; _addByIdModel(idModel, args) - добавление модели; _removeByIdConf(idConf) - удаление модели по идентификатору конфигурации; _removeByPositionType(positionType) - удаление модели по типу расположения; loadConfig(src) - загрузка конфигурации; getConfig() : коллекция { R, items[] } - получение конфигурации; setConfig(config) - установка конфигурации; |
Каталог при выборе элемента соответствующего модели вызывает обработчик события onselect, конструктор в свою очередь выполняет добавление нового элемента в конфигурацию и полученный идентификатор конфигурации использует для добавления элемента в макет и обозреватель, устанавливает значение слайдера изменения вылета.
Макет, при выборе элемента, выполняет функцию onselect, которая переопределена в конструкторе. Конструктор устанавливает значение вылета, получая его из конфигурации по идентификатору, и запоминает идентификатор конфигурации текущего выбранного элемента. При перемещении элемента макет выполняет функцию onmove. Конструктор сохраняет новое положение элемента в конфигурации и устанавливает новую позицию элемента в обозревателе. При удалении элемента макет выполняет функцию onremove, конструктор выполняет удаление данного элемента из конфигурации и обозревателя, обнуляет идентификатор выбранного элемента и скрывает слайдер изменения вылета.
При изменении значения слайдера вылета, выполняется функция обработчик, изменения вносятся в конфигурацию и вылет выбранного элемента изменяется в обозревателе. При изменении значения слайдера радиуса выполняется функция обработчик, конструктор вносит изменение в конфигурацию, для макета и обозревателя устанавливается новый радиус.
При вращении букета обозреватель выполняет функцию onrotate и конструктор, соответственно, выполняет разворот макета.
При окончании инициализации конструктора он выполняет загрузку конфигурации по умолчанию.
Добавление модели осуществляется при помощи метода _addByIdModel, в случае если модель имеет тип base, frame или staticUnit конструктор выполняет удаление модели такого же типа из конфигурации, макета и обозревателя, а затем выполняет добавление выбранной модели.
Функция setConfig выполняет удаление всех моделей из конфигурации, макета и обозревателя, а затем добавляет новые элементы из полученной конфигурации в конструктор с помощью метода _addByIdModel.
2.4 Реализация каталога
Для создания каталога используется метод класса Constructor _initCatalog. Каталог представляет собой DomElement DIV, дополненный методами и обработчиками событий. Каталог является контейнером, в котором отображаются два его компонента - это меню и список. Для меню и списка определены обработчики событий, вызываемые при нажатии на элемент. Меню служит для выбора типа отображаемых моделей, а список отображает модели и группирует их. В случае нажатия на элемент списка соответствующий модели конструктор вызывает обработчик события onselect.
Таблица 3. Поля, методы и обработчики событий объекта catalog. |
||
Поля |
curType : строка, curGroup : строка - текущие выбранные тип и группа; catalogMenu : DomElement - меню; catalogList : DomElement - список; |
|
Методы |
fillByDefault() - заполнение по умолчанию; |
|
Обработчики событий |
onselect(idModel : число) - событие выбора модели; |
Меню представляет собой DomElement DIV. Для меню определен обработчик события нажатия кнопки мыши, который при нажатии на элемент меню вызывает собственный обработчик события onselect и передает в него выбранный элемент, отменяет состояние выбора для предыдущего выбранного элемента и устанавливает для текущего. По умолчанию меню заполняется тремя элементами соответствующие типам цветы, зелень и декор. Для создания меню используется метод _initCatalogMenu. Для создания элемента используется метод _createCatalogMenuItem, создающая и возвращающая DomElement DIV, дополненный полями и методами, и для которого устанавливается соответствующая фоновая картинка. Элемент списка имеет состояние выбора, который определяет его стиль.
Таблица 4. Поля и обработчики событий объекта catalogMenu. |
||
Поля |
flowersMenuItem, greenMenuItem, decoreMenuItem - элементы меню; |
|
Обработчики события |
onselect(item : DomElement) - событие выбора элемента; |
Таблица 5. Поля и методы объекта сatalogMenuItem. |
||
Поля |
name - имя элемента меню; _selection - состояние выбора; |
|
Методы |
setSelectionState(value) - устанавливает состояние выбора; isSelected() : булевое значение - возвращает состояние выбора; |
Для создания списка используется метод _initCatalogList, который создает DomElement DIV. Для списка определен обработчик события нажатия кнопки мыши, в случае нажатия на элемент списка вызывается его собственный обработчик onselect и передает в него выбранный элемент. Список имеет метод fill который заполняет список элементами на основе данных из массива MODELS конструктора, с учетом выбранных типа и группы. Для создания элемента меню используется функция _createCatalogListItem, которая возвращает DomElement DIV, дополненный полями name и options{id, type, group}, и для которого устанавливается фоновая картинка.
Таблица 6. Поля, методы и обработчики событий объекта сatalogList. |
||
Поля |
children[] : DomElement - элементы списка; |
|
Методы |
fill(type, group) - заполняет список элементами; |
|
Обработчики события |
onselect(item : DomElement) - событие выбора элемента; |
Таблица 7. Объект сatalogListItem. |
||
Поля |
flowersMenuItem, greenMenuItem, decoreMenuItem - элементы меню; |
|
Обработчики события |
onselect(item : DomElement) - событие выбора элемента; |
Список представляет собой контейнер для элементов списка. Для инициализации используется функция _initCatalogList, возвращающая DomElement на основе DIV блока. В списке определен обработчик события клика кнопки мыши, вызывающий функцию onselect, которая переопределена в каталоге и там же обрабатывается, а так же метод fill, который заполняет список элементами на основе данных из массива MODELS конструктора, с учетом выбранных типа и группы.
Для создания элемента списка используется функция _createCatalogListItem(name, image, options), которая создает и возвращает DomElement на основе DIV блока, и добавляет ему поля name и options{id, type, group}, устанавливает фоновую картинку image для элемента.
2.5 Классы Configuration и ConfigurationItem
Для хранения информации о текущем расположении моделей букета и его радиуса используется класс Configuration, который, по сути, является контейнером для хранения конфигураций отдельных моделей, реализованных в классе ConfigurationItem.
Таблица 8. Поля и методы класса Configuration. |
||
Поля |
R : число - радиус букета; items : массив Configuration - массив конфигураций элементов букета; _idConf : число - текущий индекс конфигурации; |
|
Методы |
add( args : коллекция{ idModel, customShift, customX, customY, numberUnits}) : число - метод добавления элементов, возвращает идентификатор нового элемента; removeByIdConf(idConf) : ConfigurationItem - удаление элемента по идентификатору конфигурации; getByIdConf(idConf) : ConfigurationItem - получение элемента по идентификаторы конфигурации; get() : коллекция{ R, items } - получение элемента по идентификаторы конфигурации; |
Таблица 9. Поля и методы класса ConfigurationItem. |
||
Поля |
idModel : число - идентификатор модели; idConf : число - идентификатор конфигурации; customShift : число - значение изменения по вылету; customX, customY : число - координаты элемента букета numberUnits : число - количество копий модели; |
Добавление в конфигурацию происходит с помощью метода add, в который передается коллекция параметров элемента. Метод генерирует уникальный идентификатор конфигурации для каждого элемента и возвращает его, эти идентификаторы используются в макете и обозревателе.
2.6 Классы Layout и LayoutItem
Layout представляет собой класс на основе DomElement Canvas. Служит для отображения вида сверху букета позиционирования моделей букета, удаления моделей букета, а так же полной очистки букета. Макет состоит из окружности соответствующей радиусу букета, внутри которой размещены динамические элементы - модели типа unit, их положение на макете определяет их положение в букете. В левом верхнем углу расположены статические элементы, подписанные как База, Каркас и Декор - им соответствуют модели типа base, frame, staticUnit - их положение в макете никак не влияет на положение в букете. В правом верхнем углу расположены кнопки удаления модели и очистки букета. Все кнопки, динамические и статические элементы представляют собой объекты класса LayoutItem. На макете можно разместить только один статический элемент каждого типа модели, количество динамических элементов не ограничено.
Рис. 5. Вид макета.
Класс LayoutItem загружает и отображает картинку соответствующей ему модели, и размещает её в заданных координатах, в соответствии с указанным размером. Позиция LayoutItem задается для его центра относительно левого верхнего угла макета. Так же для LayoutItem можно получить и установить координаты относительно центра макета и координаты конфигурации. LayoutItem имеет состояние выбора, в случае которого вокруг элемента отрисовывается окружность.
Таблица 10. Поля, методы и обработчики событий класса Layout. |
||
Поля |
_context : 2DContext - используется для рисования на Canvas ; _base : LayoutItem - база букета; _frame : LayoutItem - каркас букета; _staticUnit : LayoutItem - декор; _units : массив LayoutItem - массив элементов располагающихся как отдельная единица; _removeItem : LayoutItem - кнопка удаления элемента; _clearItem : LayoutItem - кнопка очистки элемента; _selectedItem : LayoutItem - выбранный элемент; _draggedItem : LayoutItem - перемещаемый элемент; _mouseShift : {число x,число y} - смещение мыши; _maxR : число - максимальный радиус окружности макета; _R : число - текущий радиус окружности макета; _center : коллекция {число x,число y} - координаты центра окружности макета; _angle : число - угол разворота динамических элементов |
|
Методы |
Layout(div) - конструктор класса; _initComponents() - инициализация компонентов; _render() - метод отрисовки макета; addBase(число id, строка img), addFrame(число id, строка img),addStaticUnit(число id, строка img), addUnit(число id, строка img, число customX, число customY) - добавление элементов макета; removeById(число id) - удаление элемента по id; setRadius(число value) - метод устанавливает радиус окружности; rotate(число radians) - метод выполняет разворот макета на заданный угол; _remove(LayoutItem item) - удаление элемента; _positionStaticItems() - метод выполняет позиционирование статических элементов на макете; _moveOnEdgeOfCircle(LayoutItem item) - смещает элемент на границу окружности; _isBelongTo(LayoutItem item) : LayoutItem - возвращает элемент к которому относятся принятые координаты; _onMouseDown(число x, число y) - обработчик события нажатия мыши; _onMouseMove(число x, число y) - обработчик события перемещения мыши; _onMouseUp() - обработчик события отжатия кнопки мыши; _onMouseLeave() - обработчик события выхода мыши за границы макета; |
|
Обработчики событий |
onselect(число id) - обработчик события выбора элемента; onmove(число id, число customX, число customY) - обработчик события перемещения элемента; onremove(число id) - обработчик события удаления элемента; |
Таблица 11. Поля и методы класса LayoutItem. |
||
Поля |
id : число - идентификатор элемента; x : число - координата относительно левого верхнего угла; y : число - координата относительно левого верхнего угла; size : число - размер элемента; isSelect : булевое значение - состояние выбора; _img : Image - изображение элемента; _layout : Layout - макет к которому относится элемент; |
|
Методы |
setImage(строка src) -устанавливает изображение; render() - выполняет отрисовку элемента на макете; center(x,y) : коллекция {число x,число y} - метод используется для получения и для установки координат относительно центра окружности макета; custom(x,y) : коллекция {число x,число y} - метод используется для получения и для установки custom координат; getDistanceToCenter() : число - получает расстояние до центра окружности макета; isBelong(число x,число y) : булевое значение - определяет принадлежат ли принятые координаты элементу; |
Внутри класса макет заданы обработчики событий нажатия и отжатия кнопки мыши, перемещения мыши, выхода мыши за границы Canvas, которые обрабатываются методами класса Layout _onMouseDown, _onMouseUp, _onMouseMove, _onMouseLeave, соответственно.
При нажатии кнопки мыши вызывается метод _isBelongTo, который возвращает элемент, к которому относятся принимаемые методом координаты, в случае нажатия на статический или динамический элемент запоминает его как выбранный и перетаскиваемый, и вычисляет смещение положения мыши относительно координат элемента и вызывает обработчик события onselect. Если нажата кнопка удаления - удаляем выбранный элемент и вызываем обработчик события удаления элемента onremove, подсвечиваем кнопку. Если нажата кнопка очистки - удаляем все динамические и статические элементы и вызываем для каждого элемента обработчик события onremove, подсвечиваем кнопку очистки.
При перемещении мыши, перетаскиваемый элемент перемещается на место координат мыши с учетом смещения, если перемещаемый элемент пересекается с кнопкой удаления, подсвечиваем её, если перемещаемый элемент динамический - вызываем обработчик события перемещения элемента onmove.
В случае отжатия кнопки мыши, отменяем подсветку для кнопок удаления и очистки. Если перемещаемый элемент находится над кнопкой очистки, удаляем его и вызываем обработчик события удаления элемента onremove. Если перемещаемый элемент вышел за границу окружности и при этом не находится над кнопкой очистки, если он статический возвращаем его на место с помощью метода _positionStaticUnits, если динамический - смещаем на край окружности с помощью метода _moveOnEdgeOfCircle и вызываем обработчик события перемещения элемента onmove.
Для добавления элементов используются функции addBase, addFrame, addStaticUnit, addUnit, первые три метода заменяют соответствующие элементы, а последний метод добавляет новый динамический элемент в заданные координаты или в центр окружности, выполняется выбор элемента и вызов обработчика события выбора элемента onselect.
Удаление осуществляется при помощи публичного метода removeById удаляющего элемент по идентификатору, а так же при помощи приватного метода _remove в который передается элемент для удаления, и для которого вызывается обработчик события нажатия удаления onremove.
Для изменения радиуса окружности используется метод setRadius, который устанавливает радиус окружности и изменяет координаты динамических элементов пропорционально изменению радиуса окружности, в случае если динамические элементы выходят за границы окружности они смещаются на границу, для каждого из перемещаемых элементов вызывается обработчик события onmove.
При повороте букета в обозревателе выполняется поворот макета с помощью публичного метода rotate, который выполняет поворот всех динамических элементов макета относительно центра окружности, при этом обработчик события onmove не вызывается. При получении координат конфигурации элемента на макете учитывается, поворот макета, в остальных случаях не учитываются.
2.7 Класс Viewer
Обозреватель является средством отображения трехмерного вида букета, с возможностью просмотра букета со всех сторон и масштабирования. Обозреватель представляет собой объект класса Viewer, использующий DomElement Canvas, передаваемый как параметр при создании элемента класса, и инструменты фреймворка THREE.JS для создания трехмерной графики.
Во фреймворке THREE JS для создания простейшей трехмерной сцены необходимо определить объекты сцены, камеры и визуализатора. Сцена представляет собой контейнер, используемый для хранения и отслеживания всех объектов, которые мы хотим отобразить, и всех источников света, которые хотим использовать. Камера определяет, что мы увидим, когда визуализируем сцену. Визуализатор отвечает за расчеты, и то, как будет выглядеть сцена в браузере в том или ином ракурсе.
Класс Viewer содержит сцену, камеру, визуализатор, источники света и элементы обозревателя - объекты классов Unit, Base, Frame, StaticUnit, использующиеся для представления моделей различных типов расположения. Эти классы используются для создания и позиционирования объектов моделей, которые сохраняются на сцене. Классы Unit и StaticUnit работают с одним экземпляром объекта модели, а классы Base и Frame с множеством копий объектов моделей, внутри себя они содержат объекты класса Unit.
Таблица 12. Поля, методы и обработчики событий класса Viewer. |
||
Поля |
_scene : THREE.Scene - сцена; _camera : THREE.PerspectiveCamera - камера; _cameraPhi : число, _cameraTheta : число, _cameraR : число - сферические координаты определяющие положение камеры; _renderer : THREE.WebGLRenderer - отрисовщик; _units[] : массив Unit, _frame : Frame , _base : Base, _staticUnit : StaticUnit - элементы, соответствующие моделям по типу расположения; _cursor : THREE.Object3D - курсор, используется для навигации; |
|
Методы |
Viewer(Canvas : DomElement) - конструктор класса; _initThreeJSObjects () - инициализация объектов создания трехмерной графики; _onWheel() - обработчик события прокрутки колеса мыши; _onMouseDown() - обработчик события нажатия кнопки мыши; _onMouseMove() - обработчик события перемещения мыши; _onMouseUp() - обработчик события отжатия кнопки мыши; _onMouseLeave() - обработчик события выхода мыши за границы обозревателя; _loadModel(src) - выполняет загрузку модели; addUnit(id, src, customShift, customX, customZ), addStaticUnit(id, src), addFrame(id, src, customShift, numberUnits, customR), addBase(id, src, customShift, numberUnits, customR) - добавляет модель; removeById(id) - удаляет модель; setPositionById(id, custom, customZ) - устанавливает позицию элемента по id; setShiftById(id, customShift) - устанавливает изменение вылета по id; setRadius(id, customR) - устанавливает радиус букета; _setCursorR(customR) - устанавливает радиус курсора; setNumberUnitsById(id, numberUnits) - устанавливает количество копий модели; setDefaultView() - устанавливает камеру в начальное положение; |
|
Обработчики событий |
onrotate(radians) - обработчик события вызываемый при горизонтальном перемещении камеры; |
Таблица 13. Глобальные переменные. |
|
VIEWER_CAMERA_MIN_RADIUS, VIEWER_CAMERA_MAX_RADIUS, VIEWER_CAMERA_HEIGHT, VIEWER_CAMERA_LOOK_AT_HEIGHT - параметры задающие положение и взгляд камеры; VIEWER_LAYOUT_HEIGHT, VIEWER_LAYOUT_R - высота и радиус букета; VIEWER_JOINT_HEIGHT, VIEWER_JOINT_R - высота и радиус букета в месте соединения; VIEWER_TWIST_ANGLE - угол скрутки; VIEWER_SHIFT - максимальное смещение моделей; |
Конструктор класса Viewer производит объявление полей и инициализацию объектов для создания трехмерной графики, таких как сцена, камера, визуализатор, источники света и курсор, используемый для обозначения передней части букета. Конструктор назначает обработчики событий прокрутки колеса мыши - _onWheel, который приближает и отдаляет камеру, изменяя значение радиуса ее сферических координат. Событие нажатия, отжатия кнопки мыши вызывают обработчики _onMouseDown, _onMouseUp, перемещения и выхода мыши за границы обозревателя - _onMouseMove, _onMouseLeave, которые меняют положение камеры, изменяя углы phi и theta сферических координат. А так же назначается обработчик события, вызываемый при горизонтальном перемещении камеры onrotate, который используется в классе конструктор.
Добавление моделей происходит при помощи методов addUnit, addBase, addFrame, addStaticUnit, которые производят загрузку объекта модели, по завершении которой объект устанавливается в начальное положение - смещается на высоту соединения и разворачивается вдоль оси Y. Это сделано в связи с тем, что в редакторе трехмерных моделей Blender оси направленны как в декартовой системе координат, а в THREE JS иначе. После чего происходит создание элемента обозревателя - объекта класса Unit, StaticUnit, Base или Frame, загрузка трехмерных объектов элемента обозревателя на сцену.
Метод _removeById принимает на вход идентификатор удаляемого элемента, выполняет его поиск и производит удаление элемента и его трехмерного объекта со сцены.
Для изменения радиуса букета используется метод setCustomRadius, который устанавливает радиус для обьектов _base и _frame, и с помощью метода _setCursorR изменяют радиус курсора. Курсор представляет собой трехмерный объект, который расположен на месте соединения букета, состоящий из окружности и треугольника, и указывает на фронтальную часть букета.
2.8 Класс Unit
Класс Unit используется для представления модели типа расположения unit. Класс принимает и устанавливает идентификатор, объект модели и параметры положения, в которое его необходимо установить, - смещение по вылету и координаты. Параметры положения из конфигурации конвертируются в реальные значения, используемые в THREE JS. Выполняется позиционирование трехмерного объекта, с помощью метода _ performPosition.
Для позиционирования объекта модели необходимо определить 2 точки: первая соответствует положению объекта на макете и принадлежит верхней плоскости букета, а вторая соответствует положению модели в месте соединения букета и принадлежит нижней плоскости букета. Верхняя плоскость находится на уровне высоты букета, нижняя на уровне места соединения букета.
Рис. 6. Точки задающие позицию объекта модели.
Зная высоту, на которой лежит верхняя плоскость, мы можем определить декартовые координаты точки в трехмерном пространстве, а так же можем найти циклические координаты точки P1 в верхней плоскости.
Циклические координаты точки P2 в нижней плоскости можно найти по следующей формуле:
phi2 = phi1 - TWIST_ANGLE
r2 = JOINT_R
Зная высоту на которой лежит нижняя плоскость можем получить декартовые координаты точки P2 в трехмерном пространстве.
Далее находит углы phi и theta, полученные, как сферические координаты точки P1 вычисляемые относительно точки P2.
Рис. 7. Сферические координаты точки P2 относительно точки P1.
Выполняется поворот трехмерной модели на угол phi относительно OY, если необходимо развернуть модель фронтом к передней части букета или на угол П/2 если требуется развернуть модель тылом к центру букета. Далее происходит поворот на угол phi относительно OZ, поворот на theta относительно OY и перемещение модели в координаты точки P2 - на место соединения.
Таблица 14. Класс Unit. |
||
Поля |
id : число - идентификатор; object3D : THREE.Object3D - обьект сцены; _shift : число - смещение; _x : число - координата X; _z : число - координата Y; _rotateToFront : булевое значение - определяет способ разворота обьекта модели. |
|
Методы |
Unit(id : число, object3D : THREE.Object3D, customShift : число, customX : число, customZ : число) - конструктор класса; _performPositing() - вычисляет и устанавливает позицию; setShift(customShift : число) - устанавливает смещение по вылет; setPosition(customX : число, customZ : число) - устаанвливает позицию; rotateFaceToFront(bool : булевое значение) - выполняет разворот модели в строну передней части букета, либо разворачивает передней частью к центру букета; |
Метод setShift и setPosition принимают на вход параметры положения, переводит его в значения, используемые в THREE JS, и выполняет позиционирование при помощи метода _performPosition. Метод rotateFaceToFront выполняет разворот модели в строну передней части букета, либо разворачивает передней частью к центру букета;
2.9 Класс StaticUnit
Класс StaticUnit используется для представления модели типа расположения `staticUnit'. Класс принимает идентификатор и устанавливает его в поле id, объект модели - в поле object3D. Данный класс никак не изменяет объект, а просто его хранит.
Таблица 15. Класс StaticUnit. |
||
Поля |
id - идентификатор; object3D : THREE.Object3D - трехмерный объект; |
2.10 Класс Base
Класс Base используется для представления модели типа расположения `base'. Класс создает множество копий трехмерного объекта модели и на их основе создает объекты класса Unit, объединяет их в один трехмерный объект.
Таблица 16. Класс Base. |
||
Поля |
Base(id, object3D, numberUnits, customShift, customR) - конструктор класса; _computeUnitsPosition() : коллекция {customX, customZ} - вычисляет расположение элементов базы; setRadius(customR : число) - устанавливает радиус; setShift(customShift : число) - устанавливает смещение; setNumberUnits(numberUnits) - устанавливает число элеметов базы; |
|
Методы |
id : число - идентификатор; object3D : THREE.Object3D - группа трехмерных обьектов; _unitObject3D : THREE.Object3D - копия обьекта модели; _customShift : число - смещение элементов базы; _customR : число - радиус базы; _units[] : Unit - массив элементов базы; |
Конструктор класса принимает и устанавливает идентификатор, создает объект модели, который представляет собой группу других трехмерных объектов, создает копию принимаемого объекта модели, записывает принимаемые параметры положения, создает пустой массив объектов класса Unit, и заполняет его, используя метод setNumberUnits.
Метод setNumberUnits создает заданное количество объектов класса Unit, вычисляет их позицию с помощью метода _computeUnitsPosition и устанавливает её, добавляет их в массив _units и объединяет их в один трехмерный объект - поле object3D.
Метод _computeUnitsPosition вычисляет позиции для элементов базы. Окружность базы разделяется на несколько окружностей меньшего радиуса в зависимости от числа располагаемых элементов. Для каждой окружности вычисляется интервалы, на которых будут располагаться объекты. Получаются циклические координаты каждого элемента, которые необходимо перевести в декартовые, а затем в координаты конфигурации.
2.11 Класс Frame
Класс Frame используется для представления модели типа расположения `frame'. Класс Frame аналогичен Base за исключением метода _computeUnitsPosition, который располагает элементы каркаса не внутри окружности, а по периметру.
Таблица 17. Класс Frame. |
||
Поля |
Frame(id, object3D, numberUnits, customShift, customR) - конструктор класса; _computeUnitsPosition() : коллекция {customX, customZ} - вычисляет расположение элементов базы; setRadius(число customR) - устанавливает радиус; setShift(число customShift) - устанавливает смещение; setNumberUnits(число numberUnits) - устанавливает число элеметов базы; |
|
Методы |
Id : число - идентификатор; object3D : THREE.Object3D - группа трехмерных обьектов; _unitObject3D : THREE.Object3D - копия обьекта модели; _customShift : число - смещение элементов базы; _customR : число - радиус базы; _units[] : Unit - массив элементов базы; |
3. ТЕСТИРОВАНИЕ
Тестирование представляет собой проверку выполнения всех возможностей конструктора и одновременно проверки корректности отображения всех визуальных компонентов.
Тестирование проводится на браузерах Google Chrome, Mozilla Firefox, Opera и Internet Explorer последних версий. Данные тестирования сведены в таблицу. Верхняя строка таблицы соответствует браузеру, на котором проводилось тестирование, в крайнем левом столбце перечислены тестируемые функции.
Таблица 18. Тестирование приложения. |
|||||
Google Chrome |
Internet Explorer |
Mozila FireFox |
Opera |
||
Добавление модели из каталога |
+ |
+ |
+ |
+ |
|
Изменение радиуса букета |
+ |
+/- |
+ |
+ |
|
Изменение положения модели |
+ |
+ |
+ |
+ |
|
Очистка элементов букета |
+ |
+ |
+ |
+ |
|
Изменение положений камеры в обозревателе |
+ |
+ |
+ |
+ |
|
Масштабирование букета |
+ |
+/- |
+ |
+ |
|
Загрузка и установка конфигурации |
+ |
+ |
+ |
+ |
|
Сохранение конфигурации |
+ |
+ |
+ |
+ |
В ходе тестирование было выявлено два недостатка вязанных с реализацией DOM элементов Canvas и Input Range в браузере Internet Explorer. Проблем верстки и корректности отображения элементов конструктора выявлено не было.
Подобные документы
Анализ методов разработки сайта с помощью веб-инструментов, конструктора, системы управления сайтом. Выбор языка веб-программирования, графического редактора. Разработка корпоративного сайта, его внедрение в интернет и тестирование на различных браузерах.
курсовая работа [2,5 M], добавлен 22.03.2017Общая характеристика интерфейса языка программирования Delphi. Рассмотрение окна редактора кода, конструктора формы, инспектора объектов и расширения файлов. Ознакомление с основными этапами создания и сохранения простого приложения; проверка его работы.
презентация [184,3 K], добавлен 18.03.2014Математическое описание операций преобразования плоских фигур. Выбор и обоснование языка программирования и среды разработки. Задание базовой фигуры. Разработка алгоритма работы программы. Проверка корректности работы программы в различных режимах.
курсовая работа [567,6 K], добавлен 13.10.2014Принципы разработки в системе программного обеспечения САПР. Выбор среды для формирования моделей и функций. Процесс создания моделей деталей. Разработка API-приложения для среды разработки. Тестирование разработанного функционала портала-хранилища.
курсовая работа [704,0 K], добавлен 18.01.2017Архитектура сети: одноранговая, клиент - сервер, терминал - главный компьютер. Разработка конструктора электронных моделей компьютерных сетей с функциями проектирования сети и её диагностики. Требования к проектированию структурированных кабельных систем.
курсовая работа [1,6 M], добавлен 19.11.2010Создание, изучение и разработка приложение на Android. Среда разработки приложения DelphiXE5. Установка и настройка среды программирования. Этапы разработки приложения. Инструменты для упрощения конструирования графического интерфейса пользователя.
курсовая работа [1,6 M], добавлен 19.04.2017Изучение основных методов разработки программ для операционных систем семейства Windows с применением технологий .NET. Анализ возможностей интегрированной среды разработки Microsoft Visual Studio, языка C# и создание приложения "пункт видеопроката".
курсовая работа [1014,7 K], добавлен 28.06.2011Разработка приложения на базе скриптового языка программирования JavaScript, с использованием каскадных таблиц стилей CSS в среде программирования Bluefish Editor. Обоснование выбора инструментов. Применение клавиш управления памятью калькулятора.
курсовая работа [3,8 M], добавлен 22.06.2015Проектирование удобного приложения для комфортной навигации по файлам облачного хранилища в одном файловом менеджере. Выбор интегрированной среды разработки. Выбор инструментов для визуализации приложения. Выбор средств отслеживания HTTPзапросов.
курсовая работа [3,6 M], добавлен 16.07.2016Интегрированная среда разработки Lazarus. Среда программных продуктов Lazarus, объекты программных компонентов. Палитра компонентов Standard, Additional. Разработка справочной системы: структура проекта, интерфейс программы, компоненты приложения.
курсовая работа [695,2 K], добавлен 08.01.2023