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];
}