Были или нет американцы на Луне?
13,217,263 109,571
 

  Зумер ( Слушатель )
12 дек 2009 18:27:01

Тред №172268

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

Цитата: codegrinder
Не предоставлен алгоритм проекции на сферу, и далее на экран. Без этого доказательство силы не имеет, и проверить правильность сложно. Стоит выложить и исходники, или хотя бы ключевые куски кода.


Алгоритм элементарнейший. Я не выкладывал пока исходники, самая сложность там не в проектировании, а в разбиении сначала всей фотографии на тайлы 510х510, а затем отображения каждого такого тайла как квадрата 10х10 мини-тайлов по 51х51, чтобы это влезло в любую видеокарту, и хотя бы с тормозами, но показало результат на экране, пусть и после долгих вычислений. Впрочем, на ноутбуке вполне живо в результате двигает картинки со стороной 2К пикселей.

Значит, так, отображение одной (одной из, первой, точнее) вершины, когда координаты вершины есть уже в Src:

glTexCoord2f( (x+dT)/512, (y+dT)/512 );
                     SpherePt := ProjectToSphere( idx,
                         Src.X * MillimetersPerPixel,
                         Src.Y * MillimetersPerPixel );
                     glVertex3fv( @ SpherePt );

Остальные наподобие. Очевидно, что вся соль в функции ProjectToSphere. Ну тут-то как раз никакого секрета:

function TForm1.ProjectToSphere( imgIdx: Integer; X, Y: Single): TPoint3;
var SphereRadius: Single;
   R: Single;
   V: TVector3;
begin
   // Координаты X, Y - в миллиметрах от центра (откорректированного, полагаем,
   // что точного оптического центра) фотографии. В качестве радиуса сферы
   // рассматривается фокальное расстояние текущего изображения. Это та сфера,
   // на которую требуется спроектировать точку каждой фотографии.
   SphereRadius := Images[CurImg].FocalLength;

   // Вектор из фокуса в точку фотографии, расположенной на расстоянии
   // собственной фокальной длины перпендикулярно оптической оси:
   V := Point3( X, Y, Images[imgIdx]http://.FocalLength );

   // Нормализуем и удлиняем до радиуса сферы:
   R := sqrt( sqr( V.x ) + sqr( V.y ) + sqr( V.z ) );
   V := Point3( V.x * SphereRadius / R,
                V.y * SphereRadius / R,
                V.z * SphereRadius / R );

   // V - это и есть проекция на сферу:
   Result := V;
end;

Разница между CurImg и imgIdx только в том, чтобы отобразить все видимые в данный момент фотографии на одну и ту же сферу. Фотографии могут иметь разный FocalLength.

Вот, кстати, анимашка процесса. Снял из самой программы, выехав камерой за пределы сферы. Переключается плоский режим - режим сферы, сначала с каркасом, потом без.
Отредактировано: Зумер - 12 дек 2009 18:51:43
  • +0.00 / 0
  • АУ
ОТВЕТЫ (0)
 
Комментарии не найдены!