· ··--──══[ COOLer issue #1 ]══─---·· ·
ЭФФЕКТ: ANIS by GELTORN/STORM




                  -=========ЭФФЕКТ: ANIS=========-


  Авторское  отступление:  Так  как  я  не  встречал, описания этого
эффекта и соответственно его названия, а называть его как-то надо, я
решил  назвать  его  так.  (С  подачи  одного  моего  друга,  сменив
нецензурное  слово  на  эквивалентное ему научное название + букву u
заменил на i)

  Как  скролить  (вправо-влево, вверх-вниз), надеюсь, вы знаете. Что
такое  полярные  координаты,  наверно  то  же.  Так  вот этот эффект
основан на скролинге, но в полярных координатах.

  Соответственно   скролинг   вдоль  координаты  r  -  выглядит  как
втягивание-вытягивание,  а  изменение  угла  alpha - как повороты по
часовой  стрелке  или  против.  Вот  и  вся  теория. Теперь начнется
практика.

  Пусть  центр  нашего  anis`a  находиться  в центре экрана. Тектуру
которую  мы  хотим  извращать,  возьмем  размером  256x256. Основное
требование  к  этой  текстуре  -  быть  бесшовной, чтобы удобно было
скроллить. Посмотрите на мою текстуру, чтобы понять о чем речь:

в  не  имеющих  названия  единицах,  которых  в  круге  256.  Теперь
сопоставим  углу alpha - координату x в нашей текстуре, а координате
r - y нашей текстуры.

  Теперь,   что   бы   втягивать-вытягивать   и  вращать  текстурку,
достаточно изменить начальные смещения по x и y в нашей текстуры.

Реализуем наши соображения в алгоритме, он разделится на две части:

1) Инициализация.

  Заведем   два  массива  texture  и  anis.  В  первом  храним  нашу
текстурку,  а  во втором (типа unsigned short, размер такой же как у
экрана)  будем  хранить смещения текстуры. Далее в цикле проходим по
всем  точкам  массива anis, преобразуем декартовы координаты текущей
точки  в  полярные, по этим координатам вычисляем смещение от начала
массива texture, и заносим его в текущую ячейку массива anis:

...
  long x,y,u,v,p=0;
  double angle, radius;
  for(y=-100;y<100;y++)
    for(x=-160;x<160;x++)
    {
      radius=sqrt(x*x+y*y);
      if(radius<1) radius=1;
      angle=atan2(y,x)+PI;
      v=radius;
      u=angle*128/PI;
      anis[p++]=(u&0xFF)+((v&0xFF)<<8);
    }
...

2) Рендеринг.

  Для  каждого выводимого кадра решаем насколько нам надо повернуть,
втянуть-вытянуть  нашу текстуру, то есть находим сдвиг по координате
r  и  углу  alpha.  В цикле проходимся по массиву anis, считываем из
него  смещение,  прибавляем  вычисленное  ранее  сдвиг,  и  по этому
смещению  считываем  пиксель  из  массива texture. Записываем его по
текущим координатам в буфер экрана:

...
  long u=256*cos(time);
  long v=512*sin(time);
  long screen_ptr=(long)&screen;
  long i=0;
  for(long k=0;k<64000;k++)
    *((char*)screen_ptr++)=texture[(anis[i++]+u+(v<<8))&0xFFFF];
...

Вроде все, bye...
                                                  ---(Geltorn/Storm)


