Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  4 603

•  TDictionary Custom Sort  6 610

•  Fast Watermark Sources  6 388

•  3D Designer  9 335

•  Sik Screen Capture  6 717

•  Patch Maker  7 103

•  Айболит (remote control)  7 107

•  ListBox Drag & Drop  5 970

•  Доска для игры Реверси  97 525

•  Графические эффекты  7 305

•  Рисование по маске  6 595

•  Перетаскивание изображений  5 468

•  Canvas Drawing  5 840

•  Рисование Луны  5 557

•  Поворот изображения  5 072

•  Рисование стержней  3 640

•  Paint on Shape  2 876

•  Генератор кроссвордов  3 770

•  Головоломка Paletto  3 028

•  Теорема Монжа об окружностях  3 841

•  Пазл Numbrix  2 528

•  Заборы и коммивояжеры  3 234

•  Игра HIP  2 200

•  Игра Go (Го)  2 131

•  Симулятор лифта  2 512

•  Программа укладки плитки  2 158

•  Генератор лабиринта  2 650

•  Проверка числового ввода  2 311

•  HEX View  2 643

•  Физический маятник  2 267

 
скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Вращение изображения 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))




Похожие по теме исходники

Изменение цвета изображения

TGIFImage (GIF изображения)

Поворот изображения




Copyright © 2004-2025 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте