Цитата: 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.
Вот, кстати, анимашка процесса. Снял из самой программы, выехав камерой за пределы сферы. Переключается плоский режим - режим сферы, сначала с каркасом, потом без.