Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Основы САПР. CAD CAM CAE

.pdf
Скачиваний:
12
Добавлен:
19.11.2023
Размер:
29.79 Mб
Скачать

62

Глава 3. Основные концепции графического программирования

3.4.1. Отрезок

Для отображения отрезка пря.люй (лuuuu- line) необходимо задание координат двух его концов. В большинстве графических библиотек координаты концов мо­

гут задаваться в трехмерном пространстве; проецирование на плоскость экрана

осуществляется автоматически. Можно указывать атрибуты отрезка: тип, тол­ щину, цвет и другие. Типы отрезков, поддерживаемых большинством графиче­ ских библиотек, изображены на рис. 3.13. Для систем автоматизированной раз­ работки чертежей поддержка этих типов линий совершенно необходима,

поскольку они часто используются в машиностроительных и архитектурных

чертежах и электрических схемах.

Рис. 3.1 3. Различные виды отрезков

В qиблиотеках GKS, PHIGS и OpenGL одной из базовых функций является ло­

.маиая (polyline), представляющая собой набор соединенных друг с другом отрез­ ков. Координаты концов отрезков, составляющих ломаную, задаются в виде мат­

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

координаты двух его концов.

у/1

Примеры использования функций построения ломаной из библиотек PHIGS и OpenGL приведены ниже.

PHIGS

 

 

 

 

Pint

num of points = 10:

1* Количество-точек в лонаной. */

Ppoint3

point3[] =

{

 

 

 

{0.0.

0.0.

0.0}.

 

{10.0.

20.0.

15.0}.

 

{1.0.

3.0.

6.5}}:

/*Координаты концов отрезков лонаной. */

Ppolyline3(num of points. point3J:

1* Рисует заданную лонаную. */

OpenGL

GLdouЬle point[)[3] а {

{0.0. 0.0. 0.0}. {10.0. 20.0. 15.0} ...

{1.0. 3.0. 6.5}}:

3.4. Примитивы

63

/*Координаты концов отрезков ломаной. */

glBegin(GL LINE LOQP);

glVertexЗdv(&point[OJ[OJJ: glVertexЗdv(&point[l][O]J:

g1Vertex3dv(&point[9][0]): gl End():

/*Построение ломаной по заданным точкам (10 шт.) */

3.4.2. Многоугольник

Миогоугольиик - это то же самое, что и ломаная, за небольшим исключением:

первая и последняя строки матрицы вершин [Р] должны быть одинаковыми (со­ ответствующие им точки совпадают). Того же результата можно было бы дос­

тичь и с использованием функции построения ломаной, однако многоугольник,

построенный nри помощи специальной функции, распознается системой как

объект, имеющий внутреннюю и внешнюю части. Внутренняя площадь много­ угольника может быть заполнена штриховкой различных видов (рис. 3.14).

Рис. 3.14. Примеры различных заливок

Атрибутами многоугольника могут быть цвет внутренней области (цвет запол­

нения), а т~кже тип, ширина и цвет ломаной, ограничивающей эту область. Хотя

функция построения многоугольников может использоваться и для построения

кругов и прямоугольников, в большинстве графических библиотек существуют

специальные функции, требующие гораздо меньше входных параметров (напри­

мер, центр и радиус круга или два конца диагонали прямоугольника). Тем не ме­

нее внутри библиотек эти функции реализованы через функцию построения

многоугольников.

3.4.3. Маркер

Маркеры обычно используются для выделения точек на графиках. Маркеры,

достуnные в большинстве графических .библиотек, показаны на рис. 3.15.

Тип маркера указывается в качестве атрибута. Полимаркер, как и отрезок, явля­ ется стандартным объеi<том в GKS и PHIGS. OpenGL не nоддерживает маркеры

явно, однако предоставляет механизм сохранения маркеров в растровых файлах

ивыведения их на экран. Благодаря этому графическая программа, построенная

на OpenGL, гораздо лучше nереносится на различные платформы. Приведенный ниже образец кода демонстрирует выведение маркера * (звездочка) в PHIGS

иOpenGL.

64 Глава 3. Основные концепции графического программирования

 

• + * ох

 

о~~о~

 

Рис. З.15. Примеры маркеров·

PHIGS

num of point = 10:

pint

/*Количество маркеров для отображения. */

PpointЗ

pointЗ[]

= {

 

 

 

{0.0.

0.0.

0.0}.

 

{10.0. 20.0.

15.0}.

 

{1.0. 3.0. 6.5}}:

/*Координаты маркеров. */

pset_marker_type(PMK_STARJ:

 

!*Тип

маркера

- звездочка. */

ppolymarkerЗ(num_of_point. poiпtЗJ:

/*Построение маркеров по имеющимся данным. */

OpeпGL

GLubyte asterisk[13] = {ОхОО. ОхОО. ОхЗО. Ох18. ОхОс. ОхОс. ОхОс. ОхОс. ОхОс. ОхОс.

ОхОс. Ох18. Ох30}: 1

/* Задание растрового изображения звездочки. Первой рисуется нижняя

строка. затем следующая и т

д.

*/

 

GLsizei

width = 8:

 

 

 

/* Ширина растра в пикселах. */

 

 

GLsizei

height = 13:

 

 

 

/* Высота растра в пикселах. */

 

 

GLfloat

origin_x = 0.0. origiп_y

= 0.0:

 

!*Задание начала отсчета системы координат растра. Положительные

значения смещают начало отсчета

вверх и вправо. отрицательные

вниз

и

влево. */

 

 

 

GLfloat

incre_x = 10.0. iпcre_y

= 0.0:

 

/*Поправки к положению растра после выведения. */

 

Glfloat

white[З] = {1.0. 1.0. 1.0}:

 

/*Задание цвета маркера. */

 

 

 

GLfloat

positioп[2] = {20.5. 20.5}:

 

1* Координаты маркеров. */

 

 

 

glPixelStorei(GL UNPACK ALIGNMENT.1):

 

 

!*Установка режима хранения пикселов. влияющего

 

на

работу glBitmap. */

 

 

 

glColorЗfv(white):

/*Установка белого цвета маркера. */

glRasterPos2fv(position):

/*Установка текущего положения растра. */

glBitmap(width. height. origin_x. origiп_y. incre_x. incre_y. asterisk):

/*Выводит растровую картинку. заданную в последнем аргументе. представляющем собой указатель на эту картинку. Положение и размер растра указываются первыми четырьмя аргументами. */

3.4.4. Текст

Большинство графических библиотек поддерживают два вида текста: текст для

пояснений (экранный или двумерный текст) и трехмерный текст. Текст для по­ яснений всегда располагается в плоскости экрана, поэтому его форма не искажа-

1 Метод задания растровых изображений излагается в книге [121].

растровых картинок, прежде чем их можно будет использовать в OpenGL, точно
так же, как и маркеры.

3.4. Примитивы

65

ется вне зависимости от угла, на который он повернут. Трехмерный текст может

быть расположен на любой плоскости в трехмерном пространстве. Его положе­

ние и ориентация задаются в мировых координатах. Для текста любого вида не­ обходимо задание таких параметров, как шрифт, отношение высоты к ширине и

угол наклона букв, а также положение и направление строки текста. Текст может

быть представлен символами двух видов: аппаратными и программными. Про­ rраммный шрифт строится соответствующими графическими проrраммами, за­

ранее сохраняемыми в памяти компьютера. Построение его занимает больше

времени, чем построение символов аппаратного шрифта, но :аато форма может

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

Приведенный ниже листинг демонстрирует построение текстовой строки АВС

с помощью библиотек PHIGS и OpenGL. Символы необходимо сохранить в виде

PHIGS

direction[2] = {

PvectorЗ

 

{0.0.

0.0.

0.0}.

 

{10.0.

10.0.. 10.0}}:

/* Направление строки текста задается двумя радиус-векторами. */

PpointЗ

position = {5.5. 5.0. 5.0}:

/*nоложение строки текста. */

ptextЗ(&posi ti on. di recti on. ·АВС"):

/*

nостроение строки текста с указанными паранетрами. */

OpenGL

GLubyte а[13] = {ОхОО. ОхОО. ОхЗf. ОхбО. Oxcf. Oxdb. ОхdЗ. Oxdd. ОхсЗ. Ох7е. ОхОО. ОхОО. ОхОО} :

GLubyte

Ь[13] = {ОхОО. ОхОО. ОхсЗ. ОхсЗ. ОхсЗ. ОхсЗ. Oxff. ОхсЗ. ОхсЗ. ОхсЗ. Охбб.

ОхЗс. Ох18}:

Glubyte

с[lЗ] = {ОхОО. ОхОО. ОхfЗ. Охс7. ОхсЗ. ОхсЗ. Охс7. Oxfe. Охс7. ОхсЗ. ОхсЗ.

Охс7. Oxfe}:

/*

Растровые символы А. В и С. Растр задается снизу вверх

построчно. */

GLsizei

width = 8:

!* Ширина растра в пикселах. */

GLsizei

height = 13:

/* Высота растра в пикселах. */

GLfloat origin х = 0.0. origin_y=O.O:

/*ЗаданИе начала отсчета системы координат растра. nоложительные значения смещают начало отсчета вверх и вправо.

отрицательные - вниз и влево. */

GLfloat

incre

х

= 10.0.

incre у

= 0.0:

/*nоправки

к

положению

растра

после выведения. */

GLfloat white[З] = {1.0. 1.0. 1.0}:

1* Задание цвета текста. */

GLfloat position[2] = {20.5. 20.5}:

/* Координаты символов. */

glPixelStorei(GL UNPACK ALIGNMENT.1):

/*Установка режима хранения пикселов. влияющего

на работу glBitmap. */

glColorЗfv(white):

1* Установка белого цвета символов. */

glRasterPos2fv(position):

1* Установка текущего положения растра. */

66

Глава 3. Основные концепции графического программирования

 

 

 

glBitmap(width. height. origin_x. origin_y. incre_x. incre_y. asterisk):

/*Выводит растровую картинку. заданную в nоследнем аргументе.

лредставляющем собой указатель на эту картинку. Положение и размер

растра указываются первыми четырьмя аргументами. */

3.5. Ввод графики

Как уже отмечалось, графической программе может требоваться поддержка ввода

графических элементов, таких как точки, отрезки и многоугольники, а не только

чисел и текстовых строк. Например, если пользователь хочет вычислить пло­

щадь многоугольника на экране или увеличить его размеры, он должен сначала

указать интересующий его многоугольник среди прочих объектов, видимых на

экране. Для ввода графики используется два вида физических устройств: лока­

тор (устройство ввода координат) и кнопка. Локатор (locator) передает графиче­

ской программе информацию о своем положении, то есть о положении курсора.

Киопка (buttoп) сообщает о действиях пользователя (включении и выключении) в месте текущего положения курсора. В наши дни наиболее популярным устрой­ ством графического ввода является мышь, которая выполняет обе функции. Ша­

рик в нижней части корпуса мыши позволяет вводить координаты, а кнопки на­

верху корпуса передают программе действия пользователя.

Устройство графического ввода может работать в трех режимах: опрос, запрос и выбор. В режиме опроса (sampling) осуществляется постоянное считывание со­

стояния устройства ввода, прежде всего положения локатора. Например, если вы

свободно рисуе~е на экране, перемещая мышь, она работает в режиме опроса.

Перемещение мыши приводит к непрерывному перемещению курсора по экрану.

В режиме запроса (requesting) положение локатора считывается только при от~

правке запроса, которая обычно производится при нажатии на кнопку мыши. Что­ бы прояснить различие между режимами опроса и запроса, рассмотрим процесс

построения многоугольника путем графического задания координат его вершин при помощи мыши. В этом случае мы перемещаем мышь до тех пор, пока курсор не окажется в нужном месте, после чего нажимаем кнопку. Курсор перемещается

по экрану согласно движениям мыши, которая находится при этом в режиме оп­

роса. Координаты вершин передаются графической программе в режиме запроса.

У этих режимов есть общее свойство: графической программе передаются коор­ динаты мыши или курсора. В режиме выбора (picking) устройство графического

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

бора очень удобен при редактировании чертежа, уже имеющегося на экране (на­

пример, для удаления многоугольников или изменения координат их вершин).

3.6. Дисплейный файл

Дисплейиый файл (display list)- это группа команд графической библиотеки, со­

храненная для последующего выполнения. Большинство команд графических

библиотек могут либо помещаться в дисплейный файл, либо выполняться не­

медленно. Дисплейный файл обеспечивает удобство и эффективность упорядо­

чения и обработки команд библиотеки. Рассмотрим, например, перемещение

3.7. Матрица преобраэования

67

изображения дома по экрану. Предположим, что рисунок состоит из нескольких

сотен отрезков. Если бы эти отрезки существовали по отдельности, нам при­ шлось бы написать команду персмещения несколько сотен раз - для каждого из

них. Однако если команды построения отрезков, образующих рисунок, объеди­

нены в дисплейный файл, команду персмещения достаточно написать только

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

открыть этот файл перед первой командой, которая должна в него попасть, и за­

крыть его после последней команды (см. пример 'ниже).

OpenGL .

glNewList(AREA FILL. GL COMPILE AND EXECUTEJ:

/*Открытие дисnлейного-файла с-инеiiен AREA_FILL. */

glBegin(GL POLYGON): glVertex2fv<pointlJ: g1Vertex2fv(point2):

glEnd():

/*Оnределение многоугольника. */

gl Endlist():

/*Закрытие дисnлейного файла. */

Дисплейный файл OpeпGL ориентирован на оптимизацию производительности,

в частности, при работе по сети, но не за счет производительности на отдельном компьютере. Оптимизация обеспечивается благодаря тому, что дисплейный файл хранится в виде списка команд, а не в виде динамической базы данных. Другими словами, созданный дисплейный файл изменить уже нельзя. Если бы его можно было изменять, производительность упала бы из-за накладных расхо­

дов на поиск внутри списка и управление памятью. Изменение отдельных частей

дисплейного файла потребовало бы перераспределения памяти, что могло бы привести к ее фрагментации. Дисплейные файлы, как правило, работают так же быстро, как и обычные последовательности команд, не объединенные в группы.

В случае OpenGL дисплейные файлы могут значительно повысить производи­

тельность, в особенности при передаче подпрограмм OpenGL по сети, поскольку файлы эти хранятся на сервере, благодаря чему сокращается сетсвой трафик.

К созданному дисплейному файлу могут быть применсны следующие операции: CJ множественное выполнение (шultiple execution)- один и тот же файл можно

выполнять много раз;

CJ иерархическое выполнение (hierarchical execution) -иерархическим называ­

ется дисплейный файл (родительский), вызывающий другие дисплейные

файлы (дочерние). Иерархические дисплейные файлы удобны для объектов,

состоящих из отдельных компонентов, особенно если некоторые компоненты входят в объект в нескольких экземплярах;

CJ удаление (deletion) -дисплейный файл может быть удален.

3.7. Матрица преобраэования

Как говорилось в разделе 3.2, проецирование точек на объект в трехмерном про­

странстве требует преобразования координат из одной системы в другую. Снача­

ла нужно перевести координаты точеi< объекта из модельной системы в мира-

68

Глава 3. Основные концепции графического программирования

вую. Текущее положение объекта обычно задается через повороты и смещения

относительно исходного положения, в котором модельная система координат

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

получить трансляцией и поворотом соответствующих точек из их исходного по­

ложения, в котором их модельные координаты совпадали с мировыми. Большин­

ство графических библиотек выполняют эти преобразования самостоятельно,

а программнету остается задать только смещение и поворот для интересующего

его объекта. Однако проектировщику все равно нужно знать законы преобразо­

ваний, чтобы рисовать объекты в нужных местах без проб и ошибок, в особенно­ сти если эти объекты перемещаются достаточно сложным образом. В этом разде­

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

его перемещении и повороте.

Получив мировые координаты всех точек объекта в ero текущем положении, мы

должны вычислить координаты этих точек в наблюдательской системе. Перевод координат из одной системы в другую называется отображением (mapping). Отображение между мировой и наблюдательской системами координат обычно также. осуществляется rрафиче<;кой библиотекой самостоятельно, по заданным программистом координатам точки зрения, точки наблюдения и направлению вектора вертикали (в мировых координатах). Матрица преобразования для опе­ рации отображения рассматривается в разделе 3.7.3.

3.7.1. Трансnяция

При трансляции объекта на величины а, Ь и с в направлениях х, у и z соответст­

венно по отношению в начальному положению, в котором модельная система ко­

ординат совпадала с мировой (рис. 3.16), мировые координаты точек объекта в новом положении (Xw, У11" Zu,) вычисляются следующим образом:

Xw =Хт +а;

У.,, =Ут +Ь;

(3.3)

Zw =Zm +с.

 

В этой формуле числа Xm, Ym, Zm являются также модельными координатами

точки.

Формула (3.2) может быть записана в матричной форме1:

[~J[~~!;][~:]

u

(3.4)

Trans( а, Ь, с)

1 Координаты могут быть также представлены в виде строки. Тогда матрица преобразова­

ния записывается после вектора координат. В этом случае матрица преобраэования пред­

ставляет собой транспонированную матрицу из формулы (3.4). В формуле (3.4) мы

следуем соглашениям о записи OpenGL.

3.7. Матрица nреобраэования

69

Zw

Zm

Xw

Рис. 3.16. Трансляция объекта

Легко убедиться, что формулы (3.4) и (3.3) эквивалентны друг другу: для этого достаточно записать (3.4) в развернутом виде. Операцию сложения в (3.3) удалось записать через умножение в (3.4) благодаря использованию однородных координат,

в которых трехмерный вектор записывается через четыре скаляра вместо трех1• Матрица, которую мы получили, называется .матрицей однородиого преобразова­ ния (homogeneoш transfomzation matrix). В данном случае преобразование являет­ ся трансляцией. Если бы преобразование (в частности, трансляцию) нужно было

применить к точке в двумерном пространстве, однородная матрица преобразова­

ния редуцировалась бы до матрицы размерностью 3х3 удалением третьей строки

и третьего столбца из матрицы размерностью 4х4. Новая матрица действовала

бы на вектор координат размерностью 3х1, полученный из вектора 4х1 удалени­

ем z-координаты.

3.7.2. Вращение

Пусть объект поворачивается на угол е вокруг оси х мировой системы координат

вместе со своей модельной системой, которая, как и в предыдущем случае, изна­

чально совпадает с мировой (рис. 3.17). Мировые координаты точки объекта в новом положении (Xr•• Yw, Zп.) могут быть получены из исходных мировых коор­

динат этой точки (Х",, Y,m Zт), совпадающих с ее текущими координатами в мо­ дельной системе.

Соотношение между (Хп" У1,,, Zu.) и (Х",, Ym, Z",) становится очевидным после про­ ецирования рис. 3.17 на плоскость yz. Результат проецирования показав на

рис. 3.18.

1Любой вектор (х, у, z)т трехмерного пространства может быть записан в соответствую­

щих однородных координатах в виде (xw, yw, zw, w)т, где верхний индекс Т обозначает

олерацию транспонирования. Поскольку значение w может быть произвольным, для ка­

ждого вектора существует множество вариантов записи в однородных координатах.

В формуле (3.4) используется значение w = 1.

70

Глава З. Основные концепции графического программирования

 

 

 

Zw

Q' (0, Yw, Zw)

Xw

Рис. 3.17. Вращение вокруг оси х

Zw

Q' (Yw, Zw)

Рис. 3.18. Проекция на плоскость yz

Из рис. 3.18 можно легко получить следующие равенства:

Xu, =Хт;

Уи· = l cos(e +а.)=

= /(cos е cos а. -sin esina.) =

= /cosa.cos8-/sina.sin8 = = у/11 cos е - z/11 sin 8;

Zn, = l sin(8 +а.)=

= /(sin8cos а.+ cos 8sina.) =

=1cos a.sin8 + /sina. cos е= =ут sine + zm cos е.

(3.5)

(3.6)

(3.7)

3.7. Матрица преобразования

 

 

 

 

 

 

 

71

Равенства (3.5), (3.6) и (3.7) могут быть записаны в матричной форме:

 

х

j

[1

о

о

oj[x

j

(3.8)

у:.

 

о

cos е

-sin е

о

У,:

 

 

[z;··

=

~

-s~ne

со;е

~

z;,

·

 

Матрица в правой части формулы (3.8)- это однородная матрица преобразова­ ния вращения вокруг оси х, которая кратко обозначается Rot(x,e). Подобно мат­ рице трансляции, для двумерного объе1па однородная матрица вращения реду­

цируется до размера 3х3.

Однородные матрицы вращения вокруг осей у и z полуЧаются аналогичным об-

разом и записываются так:

Ге-sше

о

cos е

~}

 

 

о

sine

 

 

Rot(y, 8) = ~

1

 

о

 

(3.9)

о

о

 

о

 

 

 

-sine

о

 

 

sine

cose

о

 

(3.10)

Rot(z,e) = Ге~

о

 

1

~l

 

 

 

о

 

о

 

 

 

 

 

 

Мы получили матрицы преобразования, описывающие пЬворот вокруг мировых осей координат. Можно показать, что поворот вокруг любой произвольной оси раскладывается на повороты вокруг осей х, у и z. Таким образом, матрица преоб­ разования для произвольной оси получается перемножением матриц (3.8)-(3.10).

Как уже отмечалось, матрицы преобразования, описываемые в этом разделе, обычно вычисляются соответствующими подпрограммами графических библио­

тек. Приведенный ниже код иллюстрирует .использование подпрограмм PHIGS

и OpenGL.

PHIGS

ptranslateЗ(Pvector* offsetЗ. Pint* error_ind. PmatrixЗ result3):

/* offsetЗ: вектор трансляции

error ind: код ошибки

resultЗ: вычисленная матрица преобразования' */

protate_x(Pfloat angle. Pint* error_ind. PmatrixЗ result3): protate_y(Pfloat angle. Pint* error_ind. PmatrixЗ resultЗJ: protate_z(Pfloat angle. Pint* error_ind. PmatrixЗ result3):

/* angle: угол поворота

error ind: код ошибки

resultЗ: вычисленная матрица преобразования */

OpenGL

glTranslated(GLdouЫe offset_x. GLdouЫe offset_y. GLdouЫe offset_z):

/* Умножает текущую матрицу на матрицу трансляции объекта со смещениями offset_x. offset_y и offset_z по соответствующим осям. */

1 В PHIGS матрица преобразования ставится после вектора-строки.

Соседние файлы в папке книги