Лучший способ - это циклически перемещаться по местам назначения и для каждого из них читать правильное местоположение источника. Если вы попробуете наоборот (то есть зацикливание на источнике и запись на месте назначения), вы получите пробелы.
Формула вращения проста ...
source_x = dest_x * c + dest_y * s + x0
source_y = dest_x * -s + dest_y * c + y0
, где c
- косинус угла, s
- синус угла, а x0, y0
используются для правильного перевода повернутого изображения. В псевдокоде
for y = 0, 1, ... dest_height
for x = 0, 1, ... dest_width
src_x = c*x + s*y + x0
src_y = -s*x + c*y + y0
copy from source[src_y][src_x] to dest[y][x]
x0, y0
можно вычислить так, чтобы центр источника оказался в центре назначения на
x0 = src_width/2 - c*dest_width/2 - s*dest_height/2
y0 = src_height/2 - c*dest_height/2 + s*dest_width/2
Если вместо использования c = cos(angle)
и s = sin(angle)
вы масштабируете их с коэффициентом k
, результирующее изображение будет повернуто и увеличено вокруг центра.
Обратите внимание, что формулы являются билинейными в x
и y
; это означает, что вы можете использовать полную формулу для полного значения для первого пикселя строки, а затем просто сделать src_x += c
и src_y -= s
для каждого элемента той же строки, потому что именно это происходит при переходе от x
к x+1
.
Также обратите внимание, что в зависимости от размера источника и назначения может оказаться, что вычисленный элемент источника недоступен из-за отсутствия изображения. В этом случае есть несколько обычно используемых опций
- Введите фиксированное значение (например,
false
)
- Не записывайте эту ячейку назначения
- Выполните «зажим», ограничивая обе координаты максимально допустимым значением перед считыванием
- Выполните «мозаику», нормализуя координаты с помощью оператора по модулю