Re: Повернуть изображение

From
Michael Ryazanov (2:5030/1006.64)
To
Alexander Hritonenkov
Date
2002-07-03T17:47Z
Area
RU.ALGORITHMS
▐┤E╚°' Alexander!

 AH> Кто что посоветует для поворота изображения на произвольный угол?
 AH> Как вы сами понимаете, важны и скорость, и качество получаемой картинки.

   Тогда аппаратным образом. Там и билинейная фильтрация, и что угодно. :-)

 AH> Что может быть тут полезно?
 AH> Полярные координаты? Или лучше матрица поворота?
 AH> Hy да ладно, поворот - это еще только половина беды.
 AH> Вторая половина - использование прозрачности.
 AH> Ведь получающиеся в результате преобразования координаты будут уже не целыми
 AH> числами, значит надо как-то "размазать" точку по квадрату 2х2, в который попадет эта
 AH> точка после поворота. Или как?

   Всё наоборот -- надо вычислять для каждой точки результата влияющие на неё точки оригинала.

 AH> Кто что посоветует?

   Без сглаживания есть такой более-менее быстрый метод. Поскольку (u, v -- координаты оригинала)

u =    x cos a + y sin a
v =  - x sin a + y cos a

и x, y при сканировании увеличиваются на единицу:

for (int y = y0; y < y1; ++y)
   for (int x = x0; x < x1; ++x) {

то u, v будут увеличиваться на соответствующие cos a и sin a:

float c = cos a,
      s = sin a;
float u0 =   x0 * c + y0 * s,
      v0 = - x0 * s + y0 * c;
for (int y = y_0; y < y_1; ++y) {
   float u = u0,
         v = v0;
   for (int x = x_0; x < x_1; ++x) {
      res[x][y] = orig[u][v];
      u += c;
      v -= s;
   }
   u0 += s;
   v0 += c;
}

таким образом, умножений в цикле вообще не будет.
   float там написано по смыслу, а фактически это обычно тип с фиксированной запятой.
   Если делать не так грубо, то вместо orig[u][v] надо писать соответствующую линейную комбинацию из четырёх orig[u+0,1][v+0,1] с весами, определяемыми дробными частями u, v.

                                                                      |V|uxau/\
--- -- - ·
 * Origin:             Ф И З Ф А К - Ч Е М П И О H !           (2:5030/1006.64)