Вход

Просмотр полной версии : Поворот картинки тремя сдвигами



Reobne
12.07.2022, 01:24
Любой поворот можно сделать 3-мя сдвигами. Например горизонтальным, вертикальным, и опять горизонтальным.
Для 90 градусов, эти сдвиги будут с коэффициентом 1, а значит точные.
Немного наглядности, для квадратика 4х4

abcd
efgh исходный квадрат
ijkl
mnop

abcd
fghe <
klij <<
pmno <<< - сдвигаем строки влево

0123 - сдвигаем столбцы вниз
amie
fbnj
kgco
plhd

miea >>> - сдвигаем строки вправо
njfb >>
okgc >
plhd
и получили повёрнутый квадрат

Для 8х8 аналогично получается. Вертикальные сдвиги можно проводить поэтапно: сначала сдвинуть на 1 биты по маске 55H; потом на 2 по маске 33H; и на 4 по маске 0FH.

Для углов не кратных 90 сдвиги будут давать некоторую погрешность. Но поскольку при сдвигах, ни один пиксель не потеряется, то погрешность отразится на их положении, но не на плотности.

Sandro
12.07.2022, 06:52
Да, это знатный метод. Первым его распропагандировал Alan Paeth в статье "A Fast Algorithm for General Raster Rotation".
Коэффициенты скашивания такие:
Для первого и третьего сдвигов: -tg(phi/2)
Для второго: sin(phi)

Для приведённого выше случая с поворотом на pi/2 (90 градусов) это будут -1 и 1, как и показано на перестановках.

Однако, надо иметь в виду, что для углов более pi/2 алгоритм применять нежелательно, так как дальше тангенс очень быстро растёт и при pi достигает бесконечности. Поэтому для таких углов лучше текстуру отдельно повернуть на пол-оборота и потом доворачивать на остаток. Или завести отдельный маппер, который сам поворачивает так текстуру.