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

•  TDictionary Custom Sort  3 225

•  Fast Watermark Sources  2 990

•  3D Designer  4 750

•  Sik Screen Capture  3 259

•  Patch Maker  3 467

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

•  ListBox Drag & Drop  2 903

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

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

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

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

•  Canvas Drawing  2 672

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

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

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

•  Paint on Shape  1 524

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

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

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

•  Пазл Numbrix  1 649

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

•  Игра HIP  1 262

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

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

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

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

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

•  HEX View  1 466

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

•  Задача коммивояжера  1 357

 
скрыть


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

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