FAQ по Высадке американцев на Луну
56,621 71
 

  CodeGrinder ( Слушатель )
07 окт 2009 14:27:36

Тред №153049

новая дискуссия Дискуссия  116

Математическая подоплёка.

Цитата: codegrinder от 08.09.2009 02:08:34
Я тут подумал что было бы неплохо пояснить как же работают все эти программы. Для этого я изложу основы 3D графики, их совсем немного.Улыбающийся

Это вид сверху на наблюдателя, экран, объект и т.д.Улыбающийся


Здесь - f - это фокусное расстояние, x, z - две из трёх координат точки относительно наблюдателя, xs - экранная координата точки после проекции на экран.
Легко увидеть, причём действительно легко, что x : xs = z : f. Это подобие треугольников, восьмой класс кажется. Соответственно, xs = f * x / z. Таким образом мы получили экранную координату точки по горизонтали. Совершенно аналогично получаем вертикальную координату: ys = f * y / z. Это так называемая перспективная проекция, зная эти две простых формулы уже можно строить 3D изображения. Ну, а чтобы построить изображение пола, программа производит обратный процесс - она проводит через каждую экранную точку линию, и смотрит в какую точку пола попадает луч. Соответственно, точка на экране имеет цвет этой точки пола. Для поворота используются формулы поворота точки на некоторый угол, выводятся довольно просто через полярную систему координат и формулы синуса и косинуса суммы углов. Если кому надо, они почти наверняка есть в справочнике.
Преобразование перспективной проекции в сферическую производится довольно просто - мы проецируем рисунок на экране на сферу с центром в месте где находится наблюдатель, и радиусом равным расстоянию до экрана. В общем-то несложная задачка по геометрии, я спутался только в одном - параллели на сфере не переходят в горизонтали на экране.
Естественно, обе программы ни фига не неоптимизированы, но свою работу они делают и довольно шустро, меня скорость вполне удовлетворяет. Если кому нужна оптимизация, перевод перспективной проекции в сферическую можно вероятно в несколько раз, или даже сильнее, ускорить за счёт целочисленной арифметики. С оптимизацией текстуры на полу сложнее, целочисленная арифметика там и так уже используется, а уменьшение времени на вычисление тангенсов и арктангенсов во внешнем цикле особого эффекта не даст. Что можно там сделать - запомнить куда именно спроецировались наши точки относительно наблюдателя, и заново их генерировать при подъёме головы, или изменении размеров окна, по идее это должно сильно увеличить кол-во кадров в секунду. В любом случае, в следующий раз я постараюсь уже не делать дурную работу руками (сейчас это было необходимо для уверенности что всё генерируется правильно), а буду использовать какой-нить Direct3D.



Цитата: codegrinder от 09.09.2009 20:05:30
Продолжаем образовательную серию.

Я начну с небольшого уточнения к предыдущей серии. Формула для Ys выводится не совсем аналогично формуле для Xs. Дело в том, что там наличествует поворот, и соответственно стороны треугольника будут не f, ys, z и y, а f / cos α, ys, z / cos α и y. cos α сокращается, поэтому формула правильная, но сам вывод был неточен. Подзабыл за 10 лет конечно, хотя формулами периодически пользовался.

Едем дальше. Сферическая проекция.

Это вид сверху, тут всё совсем просто. Xs = R tg α. Заметьте что гипотенуза равна R / cos α, это понадобится нам в дальнейшем.


Это вид сбоку. Я вначале представлял его аналогично виду сверху, но это неправильно. Здесь тот же самый момент который я уже описал вначале, только немного в другом варианте. На рисунке два прямоугольных треугольника, тот который горизонтальный мы уже видели на предыдущей картинке. Соответственно, нижний катет вертикального будет равен R / cos α. Тогда Ys = R tg β / cos α. Вот и всё. Мы получили формулы которые по углам на сфере дают координаты на экране:

Xs = R tg α
Ys = R tg β / cos α

Для преобразования достаточно пройти с некоторым шагом углы которые попадут в экран и скопировать нужные точки оттуда.
Всё верно? Будьте внимательны.



Цитата: codegrinder от 10.10.2009 15:56:32
Рассмотрим, что же будет происходить при смещении позиции кадра. Зелёная линия - экран, синие - направление одну точку, красные - на другую, вид сверху, наблюдатель в самом низу рисунка.



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

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



Именно за счёт этого мы и может сказать, какая точка на стереопаре к нам ближе, а какая дальше. Что из этого следует? А следует из этого, что мы будем видеть объём до тех пор пока у нас будет разность углов сведения глаз, то бишь, до тех пор пока точки на двух снимках будут смещаться относительно друг друга. Как только их смещение станет меньше не просто 1 точки на снимке, а 1 точки / кол-во градаций цвета которое может различить глаз для этой конкретной разницы цветов (т.к. смещение в полточки выразится в "частичном перетекании" цвета от одной точки к другой), стереоэффект сойдёт на нет, и дальше объём можно будет только вообразить, но не увидеть.

Поскольку, смещение точек выражается формулой Δxs = d*f/z, (Δxs - изменение экранной координаты точки, d - смещение фотографа в сторону, f - фокусное расстояние объектива, z - глубина точки), то если точка на снимке сместилась на 1 точку в сторону, то при уменьшении глубины в два раза она сместится на 2, в 4 - на 4, и так далее.

Теперь, попробуем определить, как меняется разность по глубине с расстоянием.
Предположим, что d*f/z1-d*f/z2 = c. Тогда для z1/n и z2/n получим: n*d*f/z1-n*d*f/z2 = n * с. Это означает, что если смещение для глубин z1 и z2 оказалось достаточным, чтобы мы его заметили, тогда для расстояния в n раз меньше мы заметим разность по глубине в n раз меньшую.

Могу ещё добавить про субпиксельное смещение, но это уже так, для прикола. Всего вышеприведённого уже достаточно.

Отредактировано: CodeGrinder - 20 авг 2014 12:45:42
  • -0.04 / 2
  • АУ
ОТВЕТЫ (0)
 
Комментарии не найдены!