Russian Qt Forum
Ноябрь 22, 2024, 12:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] QGLSceneNode текстуры (добавление или изменение)  (Прочитано 18625 раз)
spirits25
Гость
« Ответ #15 : Ноябрь 08, 2012, 10:30 »

Думаю, так не пройдёт. Нужно из проекции меркатора в сферическую пересчитать, простое растяжение тут не поможет.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Ноябрь 08, 2012, 11:34 »

Думаю, так не пройдёт. Нужно из проекции меркатора в сферическую пересчитать, простое растяжение тут не поможет.
Проверил и убедился что Вы правы Улыбающийся Немного посмотрел что такое меркаторская, по-моему всего-навсего Вам надо возвести V (y текстуры) в квадрат. Во всяком случае это легко проверить

Edit: нет, просто в квадрат неправильно. Должно быть совсем просто, щас придет мысля  Улыбающийся
« Последнее редактирование: Ноябрь 08, 2012, 12:06 от Igors » Записан
spirits25
Гость
« Ответ #17 : Ноябрь 08, 2012, 14:00 »

Вот тут http://forum.openstreetmap.org/viewtopic.php?pid=288636 мне подсказали, но я до конца всё равно не разобрался..
Как перевести из проекции меркатора в сферическую?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Ноябрь 08, 2012, 14:48 »

Код ниже рабочий, у меня земля с Вашей текстурой смотрится прилично
ВАЖНО: предполагается что входной параметр iTY (y текстуры) уже посчитан для сферической карты и находится в пределах [0..1]
Код
C++ (Qt)
#include <QtGUI>
#include <math.h>
#include <vector>
 
double Mercant2Sphere( double iTY, const double maxAng = 85.0 )
{
static std::vector <double> vec;
if (!vec.size()) {
vec.push_back(0.0);
double unit = M_PI / 180;
for (double i = 1; i < maxAng; ++i)
vec.push_back(vec[i - 1] + unit / cos(i * unit));
 
// normalize
double scale = M_PI_2 / vec.back();
for (size_t i = 0; i < vec.size(); ++i)
vec[i] *= scale;
}
 
double angle = (iTY * 2 - 1) * M_PI_2; // texture V to angle
double angle_degree = fabs(angle) * 180 / M_PI;
int beg = (int) angle_degree;
double val;
if (beg >= (int) vec.size() - 1)
val = M_PI_2;
else {
double w = angle_degree - beg;
val = vec[beg] * (1.0 - w) + vec[beg + 1] * w;
}
if (angle < 0.0) val = -val;
return (1 + val / M_PI_2) * 0.5; // angle to texture V
}
 
int main( int argc, char **argv )
{
(void) argc;
(void) argv;
return 0;
}
 
Однозначного перевода просто не существует, все зависит от предела (ну вроде видел 85 градусов, их и поставил)

Дв, и в следующий раз говорите тип подготовленной текстуры, просто "квадратная" ни о чем не говорит (напр lightprobe тоже квадратная)
« Последнее редактирование: Ноябрь 08, 2012, 14:54 от Igors » Записан
spirits25
Гость
« Ответ #19 : Ноябрь 08, 2012, 15:09 »

Огромнейшее спасибо!=) Работает на отличненько=)
На будущее учту, но просто я поначалу сам разбирался и не сразу понял, что там именно меркатор. Но признаю, мог бы постараться и точнее объяснить=)

ЗЫ. Не дадите источник, где это нашли? или где информацию для написания этого.. в общем хотелось бы посмотреть там, может ещё что полезное найду=)
Спасибо.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Ноябрь 08, 2012, 15:24 »

ЗЫ. Не дадите источник, где это нашли? или где информацию для написания этого.. в общем хотелось бы посмотреть там, может ещё что полезное найду=)
Не дам потому что нету, это самопальный велосипед  Улыбающийся Можно сделать точнее (на том форуме есть формула для вычисления угла меркатора, я ее не знал). Ну численно посчитать тоже не ошибка. В любом случае нужно держать таблицу т.к. нормировка неизбежна.
Записан
spirits25
Гость
« Ответ #21 : Ноябрь 08, 2012, 15:43 »

Не дам потому что нету, это самопальный велосипед  Улыбающийся Можно сделать точнее (на том форуме есть формула для вычисления угла меркатора, я ее не знал). Ну численно посчитать тоже не ошибка. В любом случае нужно держать таблицу т.к. нормировка неизбежна.
То есть зная
Код:
inline double mercator(double x) {
    return 0.5*log((1.0+sin(x))/(1.0-sin(x)));
}
можно точнее?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Ноябрь 08, 2012, 18:13 »

То есть зная
Код:
inline double mercator(double x) {
    return 0.5*log((1.0+sin(x))/(1.0-sin(x)));
}
можно точнее?
Ну да, x это ведь исходный "угол возвышения" в радианах, просто меняете 1 строку
Код:
// vec.push_back(vec[i - 1] + unit / cos(i * unit));
vec.push_back(mercator(i * unit));
Записан
spirits25
Гость
« Ответ #23 : Ноябрь 09, 2012, 11:48 »

вроде даже точнее получается=) спасибо.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Ноябрь 09, 2012, 12:08 »

Можно и без массива

Код
C++ (Qt)
const double defMercAngle = 85 * M_PI / 180;
const double defMercScale = M_PI_2 / mercator(defMercAngle);
 
double Mercant2SphereAnalytic( double iTY, const double scale = defMercScale, const double maxAng = defMercAngle )
{
double angle = (iTY * 2 - 1) * M_PI_2; // texture V to angle
       double angle2 = fabs(angle);
double val = (angle2 > maxAng) ? M_PI_2 : (mercator(angle2) * scale);
if (angle < 0.0) val = -val;
return (1 + val / M_PI_2) * 0.5; // angle to texture V
}
 
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.089 секунд. Запросов: 23.