Были или нет американцы на Луне?
13,259,885 109,685
 

  CodeGrinder ( Слушатель )
08 сен 2009 02:08:34

Тред №144300

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

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

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


Здесь - f - это фокусное расстояние, x, z - две из трёх координат точки относительно наблюдателя, xs - экранная координата точки после проекции на экран.
Легко увидеть, причём действительно легко, что x : xs = z : f. Это подобие треугольников, восьмой класс кажется. Соответственно, xs = f * x / z. Таким образом мы получили экранную координату точки по горизонтали. Совершенно аналогично получаем вертикальную координату: ys = f * y / z. Это так называемая перспективная проекция, зная эти две простых формулы уже можно строить 3D изображения. Ну, а чтобы построить изображение пола, программа производит обратный процесс - она проводит через каждую экранную точку линию, и смотрит в какую точку пола попадает луч. Соответственно, точка на экране имеет цвет этой точки пола. Для поворота используются формулы поворота точки на некоторый угол, выводятся довольно просто через полярную систему координат и формулы синуса и косинуса суммы углов. Если кому надо, они почти наверняка есть в справочнике.
Преобразование перспективной проекции в сферическую производится довольно просто - мы проецируем рисунок на экране на сферу с центром в месте где находится наблюдатель, и радиусом равным расстоянию до экрана. В общем-то несложная задачка по геометрии, я спутался только в одном - параллели на сфере не переходят в горизонтали на экране.
Естественно, обе программы ни фига не неоптимизированы, но свою работу они делают и довольно шустро, меня скорость вполне удовлетворяет. Если кому нужна оптимизация, перевод перспективной проекции в сферическую можно вероятно в несколько раз, или даже сильнее, ускорить за счёт целочисленной арифметики. С оптимизацией текстуры на полу сложнее, целочисленная арифметика там и так уже используется, а уменьшение времени на вычисление тангенсов и арктангенсов во внешнем цикле особого эффекта не даст. Что можно там сделать - запомнить куда именно спроецировались наши точки относительно наблюдателя, и заново их генерировать при подъёме головы, или изменении размеров окна, по идее это должно сильно увеличить кол-во кадров в секунду. В любом случае, в следующий раз я постараюсь уже не делать дурную работу руками (сейчас это было необходимо для уверенности что всё генерируется правильно), а буду использовать какой-нить Direct3D.
Отредактировано: CodeGrinder - 20 авг 2014 12:57:08
  • +0.00 / 0
  • АУ
ОТВЕТЫ (0)
 
Комментарии не найдены!