![]() |
Модераторы: Rickert |
![]() ![]() ![]() |
|
Rickert |
|
||||||||||||||||||||||||
![]() Ситхи не пройдут! ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3356 Регистрация: 11.7.2006 Где: Лакрима Репутация: 6 Всего: 52 |
Перед тем как приступить, я попрошу вас самостоятельно перегрузить операции сложения, вычитания, умножения и деления для векторов. Движок, движок, движок... Итак, у нас на мази след. пункты:
Можно очень много спорить о том как должен быть построен движок; как будет эффективнее и на чём писать. Я предлагаю след. систему:
![]() Вспомогательный класс Так как мы собираемся работать с графикой, аналитической геометрией, то нам придётся часто производить различные геометрические операции, как то: поиск пересечения линии и плоскости, попадание точки в треугольник, получение нормали к плоскости и т.п. Следовательно нам надо их релизовать. Но вот вопрос: как это лучше сделать? Половина ответят - засунуть функции работы с векторами в класс векторов, а другая половина скажет: засунуть их в отдельный синглтон. Я солидарен со вторыми, хотябы потому что этот метод избавит на от бессмысленного копирования одних и тех же функций тысячи раз, при создании объектов. Итак создаём файл описания нашего вспомогательного класса aAux.cpp:
Нам не нужно чтобы была возможность создавать отдельный экземпляр класса, потому что он у нас является синглтоном, а значит надо как-то предостеречь вариант его создания. Что мы и делаем, записывая конструктор как private.
Функции типа cos / sin оперируют углами не в градусах, а в радианах. Чтобы перевести градус в радины, нам надо умножить его на Пи и разделить на 180. Константа pid = pi/180.0f;
Но иногда требуется обратное преобразование радиан в градусы, которое получается через умножение на 180 и деление на пи, pidi = 180.0f/pi;
Вообще, всем и каждому, кто мало знаком с аналитической геометрией / векторной алгеброй, я советую обзавестись рядом книг или же пошустрить инет на тему основных операций над векторами. Данная функция является одной из фундаметальных - поиск длинны вектора. Помним, что вектор - это направленный отрезок.
Это функция скалярного произведения двух векторов. В плане геометрического смысла, скалярное произведение - это длинна проекции первого вектора на второй. Запомните этот момент, он нам понадобится, когда будет писать функцию проекции вектора на вектор.
Читатель должен чётко понимать смысл всех геометрических преобразований с векторами. Допустим что вычитая один вектор из другого он получает третий, направление которого идёт от второго к первому. Я ещё раз настоятельно рекомендую обрадиться к учебникам, если вы до сих пор не знакомы с векторными операциями и что самое главное их геометрическим смыслом. Итак функция "aaGetVectorProjection(...)" - это функция которая должна вернуть проекцию первого вектора на второй. Как нам её получить? Мы пытаемся умножить вектор vec2 на число. Какое должно быть число? Подумайте.
Очень нужная функция. Давайте задумаемся о том, а что такое вообще "координаты"? x, y, z... Для того чтобы ответить на этот вопрос нам надо разобраться с тем, что такое базисы прямоугольной системы координат. Базисы - это три вектора, которые обозначают направление мировых осей . Самые первые базисы, с которыми все знакомятся: (1.0, 0.0, 0.0) - ось абсцисс, (0.0, 1.0, 0.0) - ось ординат, (0.0, 0.0, 1.0) - ось аппликат. Обозначим их i, j, k - соответственно. Возьмите в руки карандаш и лист бумаги, поставьте в любом месте точку - это будет начало отсчёта координат. Теперь проведите вектор (1.0, 0.0, 0.0) и остальные два. Что у вас получается? Три вектора, каждый из которых направлен перпендикулярно двум остальным. Теперь, запоминаем, что любая точка в трёхмерном пространстве это p = x*i + y*j + z*k. Т.е. получается, точка - это сумма базисных векторов, каждый из которых умножен на координату. А что бывает когда мы умножаем вектор, единичной длинны, на любое число? Правильно - получается вектор длинны равной этому числу. Следовательно получается, что координата - это некий коэффициент для абсциссы, который будет характеризовать её направление. А теперь, чтобы получить точку, в нашей заданной, векторами (абсциссами) i, j, k, прямоугольной системе координат нам надо умножить каждую из этих абсцисс, на каждую из координат: i - на x, j - на y, z - на k. Но ведь можно задать i, j, k не только (1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)? Правильно - и тогда вы получите другую систему координат. Об этом мы ещё поговорим, когда выведем своё первое изображение на экран. Так вот, вернёмся к нашей функции "aaVVVXYZ2pos()" - что она делает, посмотрите и попытайтесь понять сами. Если не сможете - спрашивайте.
Функция, как можно понять из названия возвращает нормаль к каким - то трём векторам. Три точки, три вектора - это минимум, с помощью которого можно конкретно задать плоскость в трёхмерном пространстве. В этой функции очень важен порядок вершин, потому что от него зависит то, в какую сторону будет направлен вектор нормали. И не только порядок но и расположение вершин. Перечислены они должны быть по часово стрелке от первой к третьей. Мы берём разницу первого вектора и второго + разницу первого и третьего - тем самым получаем два вектора, которые выходят из одной вершины. А как известно, векторное произведение дву векторов даёт третий вектор, который будет направлен перпендикулярно двум данным. Всё намного проще, если нарисовать треугольник на бумаге и слева направо - снизу вверх, по часовой стрелке, обозначить вершины vec, vec2, vec3. Теперь смотрим: "(vec2 - vec)": получится вектор, выходящий из vec в vec2; теперь "(vec3 - vec)" - и у нас вектор идущий из vec в vec3. А их векторное произведение - это нормаль, которая перпендикулярна плоскости листа бумаги и направлена от нас. Функцию "aaCrossMultiply()" мы с вами ещё не смотрели, но смысл её прост - она возвращает векторное произведение двух векторов, геометрический смысл которого - получение вектора перпендикулярного двум данным.
Функция проверки лежит ли данная точка "p" на линии, заданной векторами "l1" и "l2". Напишите её сами, предварительно посмотрев описание функций "aaGetLength()" и aaCompareFloat Описание нижеследующих функций будет приведено в файле реализации aAux.cpp
Остановились, отдышались... Переходим к файлу реализации aAux.cpp:
Первых двух частей вам хватит на ближайшую недельку. Обдумайте всё, поиграйтесь с тем, что у нас поулчилось. В след. раз мы напишем класс работы с камерой и инициализируем приложение. Да прибудет с вами великая сила ![]() Это сообщение отредактировал(а) Rickert - 22.1.2010, 10:09 -------------------- Ни что не внушает сна крепче, чем день приисполненный трудов! |
||||||||||||||||||||||||
|
|||||||||||||||||||||||||
mr.DUDA |
|
|||
![]() 3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 7 Всего: 232 |
Да пребудет с тобой великая сила, тоже. Придраться не к чему, только грамматические ошибки поправить не мешало бы. Ну и по мелочам:
Код функций не копируется при создании объекта.
Можно вектором и флоатом задать (нормаль и расстояние от {0,0,0}). P.S. а функцию aaVVVXYZ2pos ты часто используешь? ![]() -------------------- ![]() |
|||
|
||||
Rickert |
|
|||
![]() Ситхи не пройдут! ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3356 Регистрация: 11.7.2006 Где: Лакрима Репутация: 6 Всего: 52 |
Да, когда будем разбирать скелетную анимацию ![]()
По сути - одно и тоже. Разве? -------------------- Ни что не внушает сна крепче, чем день приисполненный трудов! |
|||
|
||||
mr.DUDA |
|
|||
![]() 3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 7 Всего: 232 |
Не сомневайся ![]() Вот тебе пример простой:
Вот скриншоты с адресом вызываемой функции: раз, два, три. Добавлено через 1 минуту и 17 секунд О, вот это тема. ![]() -------------------- ![]() |
|||
|
||||
Rickert |
|
|||
![]() Ситхи не пройдут! ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3356 Регистрация: 11.7.2006 Где: Лакрима Репутация: 6 Всего: 52 |
mr.DUDA, да, действительно. Естественно, я могу делать ошибки и рад что кто-то мне на них указывает. Ведь именно из ошибок состоит путь пограммиста
![]() Это сообщение отредактировал(а) Rickert - 26.11.2008, 08:24 -------------------- Ни что не внушает сна крепче, чем день приисполненный трудов! |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Программирование игр, графики и искуственного интеллекта" | |
|
НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |