| Chapter 8 Примеры интересных программ
8.2  Управление лампами    
Для управления лампами нам понадобится определить функции-обработчики
стрелок: вверх, вниз, влево, вправо. Здесь все точно так же, как и в предыдущем
пункте, за исключением того, что управлять положением лампы гораздо удобнее
в полярных координатах, чем в декартовых. Точка А в полярных координатах
задается следующим образом: бета - угол отклонения вектора ОВ в плоскости XZ,
альфа - угол между вектором ОА и плоскостью XZ и третий параметр радиус - длина вектора.
       
Стрелки влево, вправо будут управлять углом бета, а стрелки вверх, вниз - углом альфа.
Соответственно, лампа будет перемещаться по сфере. Радиус мы изменять не будем.
Для изменения положения лампы нам понадобится выполнить следующие действия:
 
 получить текуищие координаты лампы
 преобразовать их в полярные
 в полярных координатах изменить соответсвующий угол
 преобразовать координаты из полярных в нормальные
 установить новое положение лампы
     
За основу мы возьмем программу с тремя источниками света, направленными на
сферу из главы "Освещение". Создайте новый проект и скопируйте в него файл lamps.c.
Объявите функции-обработчики и отредактируйте соотвествующим образом функцию main.
 
    auxKeyFunc(AUX_LEFT, Key_LEFT);
    auxKeyFunc(AUX_RIGHT, Key_RIGHT);
    auxKeyFunc(AUX_UP, Key_UP);
    auxKeyFunc(AUX_DOWN, Key_DOWN);
Код функции Key_LEFT будет следующим:
void CALLBACK Key_LEFT(void)
{
float nor[4];
float pol[3];
  // получаем текущие координаты лампы
  glGetLightfv(GL_LIGHT3, GL_POSITION, nor);
  // конвертируем их в полярные
  Normal2Polar(nor[0], nor[1], nor[2], pol);
  // уменьшаем угол бета на величину дельта
  pol[1] -= delta;
  // конвертируем обратно в нормальные координаты
  Polar2Normal(pol[0], pol[1], pol[2], nor);
  // устанавливаем новое положение лампы
  glLightfv(GL_LIGHT3, GL_POSITION, nor);
}
После включение заголовочных файлов объявите две константы:
#define M_PI        3.14159265358979323846
float delta=0.1;
Функции перевода из одной системы координат в другую: 
void Polar2Normal(float a, float b, float r, float nor[3])
{
nor[0] = r*cos(a)*cos(b);
nor[1] = r*sin(a);
nor[2] = -r*cos(a)*sin(b);
}
void Normal2Polar(float x, float y, float z, float pol[3])
{
pol[2] = sqrt(x*x+y*y+z*z);
pol[0] = asin(y/pol[2]);
pol[1] = acos(x/sqrt(x*x+z*z));
if(z>0)
 pol[1] = 2*M_PI - pol[1];
}
 |