БОЛЬШОЙ FAQ ПО DELPHI



Вращение изображения 2

...я думаю над принудительным грубым методом, но его эффективность может быть сомнительна, и не вздумайте пробовать его без сопроцессора!

Сделайте наложение пиксель-на-пиксель из исходного изображение на целевой (используя свойство Canvas.Pixels). Для каждого пикселя осуществите преобразование полярных координат, добавьте компенсирующий угол к полярной координате, затем спозиционируйте это обратно на координаты прямоугольника, и разместите пиксель с новыми координатами на целевом изображении. Также вы можете добавлять какой-либо псевдослучайный пиксель через определенное их количество, если хотите задать какую-то точность вашей операции.

Для преобразования X- и Y-координат объявлены следующие переменные:

X,Y    = старые координаты пикселя
 X1,Y1  = новые координаты пикселя
 T      = угол вращения (в радианах)
 
 R, A   - промежуточные величины, представляющие собой полярные координаты
 
 R = Sqrt(Sqr(X) + Sqr(Y));
 
 A = Arctan(Y/X);
 
 X1 = R * Cos(A+T);
 
 Y1 = R * Sin(A+T);
Я отдаю себе отчет, что это не оптимальное решение, поэтому, если вы найдете еще какое-либо решение, дайте мне знать. В действительности мой метод работает, но делает это очень медленно.

Создайте наложение пиксель-на-пиксель исходного изображение на целевое (используя свойство Canvas.Pixels).

...это хорошее начало, но я думаю другой способ будет немного лучшим. Создайте наложение пиксель-на-пиксель целевого изображения на исходное так, чтобы нам было нужно вычислять откуда брать нужные пиксели, а не думать над тем, куда их нужно поместить.

Для начала вот мой вариант формулы вращения:

x, y = координаты в целевом изображении
 t = угол
 u, v = координаты в исходном изображении
 
 x = u * cos(t) - v * sin(t)
 y = v * cos(t) + u * sin(t)
Теперь, если я захочу решить эти уравнения и вычислить u и v (привести их к правой части уравнения), то формулы будут выглядеть следующим образом (без гарантии, по этой причине я и включил исходные уравнения!):
      x * cos(t) + y
 u = --------------------
     sqr(cos(t)) + sin(t)
 
 v =   y * cos(t) - x
     --------------------
     sqr(cos(t)) + sin(t)

Так, подразумевая, что вы уже знаете угол вращения, можно вычислить константы cos(t) и 1/sqr(cos(t))+sin(t) непосредственно перед самим циклом; это может выглядеть примерно так (приблизительный код):


 ct := cos(t);
 ccst := 1/sqr(cos(t))+sin(t);
 for x := 0 to width do
 
 for y := 0 to height do
 dest.pixels[x,y] := source.pixels[Round((x * ct + y) * ccst),
 Round((y * ct - x) * ccst)];
 

Если вы хотите ускорить этот процесс, и при этом волнуетесь за накопление ошибки округления, то вам следует обратить внимание на используемую нами технологию: мы перемещаем за один раз один пиксель, дистанция между пикселями равна u, v содержит константу, определяющую колонку с перемещаемым пикселем. Я использую расчитанные выше переменные как рычаг с коротким плечом (с вычисленной длиной и точкой приложения). Просто поместите в (x,y) = (1,0) и (x,y) = (0,1) и уравнение, приведенное выше:


 duCol := ct * ccst;
 dvCol := -ccst;
 
 duRow := ccst;
 dvRow := ct * ccst;
 
 uStart := 0;
 vStart := 0;
 
 for x := 0 to width do
 begin
   u := uStart;
   v := vStart;
   for y := 0 to height do
   begin
     dest.pixels[x, y] := source.pixels[Round(u), Round(v)];
     u := u + rowdu;
     v := v + rowdv;
   end;
   uStart := uStart + duCol;
   vStart := vStart + dvCol;
 end;
 

Приведенный выше код можно использовать "как есть", и я не даю никаких гарантий отностительно его использования!

Если вы в душе испытатель, и хотите попробовать вращение вокруг произвольной точки, попробуйте поиграться со значенияим u и v:

Xp, Yp (X-sub-p, Y-sub-p) точка оси вращения, другие константы определены выше
 x = Xp + (u - Xp) * cos(t) - (y - Yp) * sin(t)
 y = Yp + (y - Yp) * cos(t) - (x - Xp) * sin(t)
Оригинальные уравнения:
  x = u * cos(t) - v * sin(t)
   y = v * cos(t) + u * sin(t)
верны, но когда я решаю их для u и v, я получаю это:
      x * cos(t) + y * sin(t)
   u = -----------------------
      sqr(cos(t)) + sqr(sin(t))
 
 
       y * cos(t) - x * sin(t)
   v = ------------------------
       sqr(cos(t)) + sqr(sin(t))



<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Видеокурс ВЗЛОМ