Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  166

•  TDictionary Custom Sort  3 340

•  Fast Watermark Sources  3 093

•  3D Designer  4 849

•  Sik Screen Capture  3 348

•  Patch Maker  3 554

•  Айболит (remote control)  3 663

•  ListBox Drag & Drop  3 016

•  Доска для игры Реверси  81 711

•  Графические эффекты  3 946

•  Рисование по маске  3 250

•  Перетаскивание изображений  2 631

•  Canvas Drawing  2 754

•  Рисование Луны  2 584

•  Поворот изображения  2 191

•  Рисование стержней  2 169

•  Paint on Shape  1 569

•  Генератор кроссвордов  2 237

•  Головоломка Paletto  1 767

•  Теорема Монжа об окружностях  2 232

•  Пазл Numbrix  1 685

•  Заборы и коммивояжеры  2 057

•  Игра HIP  1 282

•  Игра Go (Го)  1 230

•  Симулятор лифта  1 475

•  Программа укладки плитки  1 218

•  Генератор лабиринта  1 548

•  Проверка числового ввода  1 366

•  HEX View  1 497

•  Физический маятник  1 358

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Основы 3D математики - Работа с камерой



Проецирование

Например, у нас задан в пространстве треугольник ABC, у каждой вершины, ес-сно, заданы координаты x,y,z. Как все это безобразие спроецировать на экранную плоскость? Я буду описывать в данной статье только перспективное проецирование.

Существуют стандартные фомулы проецирования:


x` = x*FOV/z + xRes/2
y` = y*FOV/z + yRes/2

  • x`, y` - координаты искомой точки на плоскости;
  • x,y,z - координаты исходной точки в пространстве;
  • xRes,yRes - графическое разрешение экрана;
  • FOV - угол обзора камеры.

камера находится в (0;0;0), и направлена по оси z, такая камера называется "стандартной".

Произвольная камера

Вас устраивает камера, всегда расположенная в начале координат, и повернутая в одном направлении? :) нет конечно :) Камера, расположенная произвольно в пространстве и повернутая под произвольным углом называется "произвольной".

Что требуется сделать для использования произвольной камеры? Правильно, составить матрицу, приводящую произвольную камеру к стандартной. Требуется помножить матрицы параллельного переноса для точки, где располагается камера, на матрицы поворотов - углы поворотов - углы, задающие направление камеры, а полученную матрицу последовательно перемножить со всеми точками на 3D-сцене.

Z-Отсечение

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

Если Вам требуется спроецировать только одну-лишь точку, не связанную ни с чем - все просто - Вы можете при z <= 0 просто отказаться от ее проецирования. Но если это - вершина треугольника? Ее отбросить никак нельзя. Решение этой проблемы - в отсечении полигона по оси Z.

Вот алгоритм такого отсечения(берем, к примеру, треугольник, как самый простой полигон):

  1. Проверяем z-координаты всех вершин, если есть точки, у которых z-координаты <=0 - проводим отсечение (если у всех вершин полигона z-координата <= 0 - вообще пропускаем этот полигон).
  2. Последовательно проверяем каждую вершину (по или против часовой стрелки). Если сторона, которую образует эта вершина и след. по порядку, пересекается с осью z - находим координаты точки пересечения стороны с осью, они будут координатами одной из вершин искомого полигона; eсли следующая точка после рассматриваемой лежит в положительной полуплоскости z (или, что правильнее, xy)- тогда сохраняем координаты след. точки после просматриваемой в искомые; если сторона не пересекает ось z, лежит в отрицательной полуплоскости - пропускаем ее.

Немного запутанное объяснение, но - вернемся к нашему примеру с треугольником ABC, отсечем его по оси z.

Начнем с точки A, след. точкой будет точка B. Сторона AB лежит в отрицательной полуплоскости, пропускаем. Дальше - точка B, следующая - C. Сторона BC пересекается с осью z, т.к., просто-напросто, у точки B координата z < 0, а у точки C координата z > 0; находим точку пересечения стороны с осью z. добавляем эту точку в список искомых; так как точка C лежит в положительной полуплоскости - добавляем ее в список искомых. Дальше рассматриваем точку C, следующая точка - A. Сторона CA, опять же, пересекает ось z, находим точку пересечения этой стороны с осью z... опять же добавляем ее в список искомых. Все, мы "обошли" все вершины полигона, найденые вершины B'CA' как раз и образуют отсеченный по оси z полигон.

Небольшое примечание - отсекать надо не по оси z, т.е. координата z линии отсечения = 0, а по линии, находящейся очень близко к оси z, и лежащей в положительной полуплоскости (например, z=0,0001) - чтобы избежать деления на 0 при проецировании.

2D-Отсечение

Мы уже можем управлять камерой, корректно проецировать полигоны на экранную плоскость.. не хватает одного в работе с камерой - 2D-отсечения. Экранные координаты ограничены разрешением экрана, например, 800x600. И, к примеру, спроецированный полигон получился такой (ABC):

Мы воспользуемся аналогичным описанному выше алгоритмом, только сейчас мы будем отсекать прямые не по плоскости, а по прямым. Фактически, мы будем отсекать полигон последовательно по левой, нижней, правой, верхней границам экрана точно также, как и отсекали полигон по плоскости z - единственное, искать пересечение для точки будем уже не для 3D, а для 2D случая.

Для данного полигона:

  1. отсекаем по левой границе. полигон ABC.
  2. отсекаем по нижней границе. полигон AA`B`C
  3. отсекаем по правой границе. полигон AA`B`B``C`
  4. отсекаем по верхней границе. полигон AA`B`B``C`.

существуют и другие способы отсечения, но этот - один из самых известных. этот алгоритм носит название алгоритм Сазерленда-Ходжмана(Sutherland-Hodgman algorithm).

В принципе, вот и все о работе с камерой.





Похожие по теме исходники

Nstruct (работа с DBF)

Работа с принтером

fwZIP - Работа с ZIP архивами




Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте