Укажите центр поворота C и угол поворота тета.
Затем определите комплексное число R = cos (тета) + i sin (тета).
Функция поворота для каждого пикселя P:
M (P) =R * (P - C) + C
Там, где продукт * включает продукт номера complrx.Вы можете сделать то же самое с 2 × 2 матрицей вращения R, если хотите.
Так что вам просто нужно создать два вложенных цикла и для каждого пикселя P найти свою повернутую позицию, используя M (P).
Вам необходимо определить, что делать, когда повернутое положение выходит за границы целевого изображения.Самое простое решение - пропустить этот пиксель.Полученное повернутое изображение будет обрезано по углам.
Другой подход, конечно, заключается в определении нового размера целевого изображения с использованием повернутых углов входного изображения.Для этого вам нужно применить функцию M к углам, а затем найти max X, max Y, min X и min Y повернутых углов.
C ++ псевдокод:
#include <complex>
struct Point
{
double x, y;
Point(double _x, double _y) : x(_x), y(_y) {};
};
// Rotate a point around a center using complex numbers.
// This is slow
Point transform(const Point& pt, double rot_angle, const Point& rot_center)
{
auto R = std::complex<double>(cos(rot_angle), sin(rot_angle));
auto C = std::complex<double>(rot_center.x, rot_center.y);
auto P = std::complex<double>(pt.x, pt.y);
auto M = R * (P - C) + C;
return Point(M.real(), M.imag());
}
// Pseudocode for rotating the input_image.
// This code cropp the corners outside the bounds.
constexpr double PI = 3.14159265358979323846;
auto center = Point(width/2, height/2);
auto angle = PI / 4.0:
for(int y = 0 ; y < height; ++y)
{
for(int x = 0 ; x < width ; ++x)
{
auto point = transform(Point(x,y), angle, center);
if(point.x < 0 || point.x >= width || point.y < 0 || point.y >= height)
continue;
auto color = input_image.get_pixel(x,y);
output_image.set_pixel((int)point.x, (int)point.y, color);
}
}