Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поворот, растягивание, изображений 
:(
    Опции темы
MONSTER
Дата 22.4.2007, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 29.10.2006

Репутация: нет
Всего: нет



Как можно выводить на экран повёрнутые по определённым углом изображения?
PM MAIL   Вверх
Voldemar2004
  Дата 23.4.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Есть матрицы поворота. Как впрочем и много других для преобразований изображения. Могу показать исходник на Delfi - моя лаба, где происходит вращение пирамиды во всех плоскостях и под любым углом.

А теоретический материал можно взять здесь:Учебник


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
Voldemar2004
  Дата 25.4.2007, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Вот могу привести пример - моя лаба: создай файл matrices3D.pas и кинь его в папку проекта, затем подключи его к проекту. matrices3D.pas:
Код
{типы данных и процедуры для построения трехмерных преобразований координат}

unit matrices3D;

interface

uses Graphics, SysUtils;

                    {используемые типы данных}
type
  //тип данных для описания одной вершины в пространстве
  //в однородных координатах
  TVertex = array [0..3] of double;

  //тип данных для описания матрицы преобразования координат
  //в пространстве
  TTransform = array [0..3, 0..3] of double;



                {Используемые подпрограммы}

//вычисляет матрицу сложного преобразования координат
//[T]:=[T1]*[T2]
procedure CombineTransform(var T : TTransform;
                           const T1, T2 : TTransform);

//осуществляет преобразование матрицы [V] исходных координат
//вершин объекта, умножая ее на матрицу [T]: [TV] = [V]*[T]
procedure ApplyTransform(var V1, V : array of TVertex;
                         const T : TTransform);

//осуществляет нормализацию однородных координат вершин
//фигуры в матрице V, деля координаты каждой вершины на четвертую
//координату H
procedure NormCoors(var V : array of TVertex);


implementation

//вычисляет матрицу сложного преобразования координат
//[T]:=[T1]*[T2]
procedure CombineTransform(var T : TTransform;
                           const T1, T2 : TTransform);
var
  i, j, k: integer;
  Tmp : TTransform;
begin
  //перемножим матрицы [T1] и [T2]
  for i := 0 to 3 do
    for j := 0 to 3 do begin
      Tmp[i, j] := 0;
      for k := 0 to 3 do
        Tmp[i, j] := Tmp[i, j] + T1[i, k] * T2[k, j];
    end;
  //вернем результат
  T := Tmp;
end;

//осуществляет преобразование матрицы [V] исходных координат
//вершин объекта, умножая ее на матрицу [T]: [TV] = [V]*[T]
procedure ApplyTransform(var V1, V : array of TVertex;
                         const T : TTransform);
var
  i, j, k : integer;
  VT : TVertex;
begin
  //пройдем по всем вершинам
  for i := 0 to High(V) do begin
    //вычислим координаты i-й вершины
    for j:= 0 to 3 do begin
      VT[j] := 0;
      //вычислим j-ую координату
      for k := 0 to 3 do VT[j] := VT[j] + V[i, k] * T[k, j];
    end;
    //переместим координаты i-ой вершины из временного
    //массива VT в массив V
    V1[i] := VT;
  end;
end;

//осуществляет нормализацию однородных координат вершин
//фигуры в матрице V, деля координаты каждой вершины на четвертую
//координату H
procedure NormCoors(var V : array of TVertex);
var
  i : integer;
  H : double;
begin
  for i := 0 to High(V) do begin
    H := V[i, 3]; //координата H
    V[i, 0] := V[i, 0] / H; //координата X
    V[i, 1] := V[i, 1] / H; //координата Y
    V[i, 2] := V[i, 2] / H; //координата Z
    V[i, 3] := 1; //координата H становится равной 1
  end;
end;

end.
Код главного модуля - файл Unit1.pas:
Код
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, wire3D, matrices3D, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormPaint(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

  V: array [0..3] of TVertex = (

  (-350, 0, -150, 1),
  (-575, 130, -150, 1),
  (-575, -130, -150, 1),
  (-500, 0, 150, 1) )  ;



  P: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (500, 0, 0, 1) )  ;



  P2: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (-500, 0, 0, 1) )  ;



  C: TTransform = (

  (0, 0, -1, 0),
  (1, 0, 0, 0),
  (0, -1, 0, 0),
  (250, 250, 0, 1) )  ;


  Rz: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;

  Pp: TTransform = (

  (0, 0, 0, -1/500),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;

  T: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;


  L1: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (500, 0, 0, 1) )  ;

  L: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (-500, 0, 0, 1) )  ;



//--------------------------------------------
  // Вправо
  PyRight: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 20, 0, 1) )  ;


  // Влево
  PyLeft: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, -20, 0, 1) )  ;
//--------------------------------------------

  // Вверх
  PzUp: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 20, 1) )  ;

  // Вниз
  PzDown: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, -20, 1) )  ;
//--------------------------------------------

  RxLeft: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;

  RxRight: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;
//--------------------------------------------

//Уменьшение/увеличение (матрица сжатия/растяжения: [0;1] ) объекта:

  RxSmall: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;

  RxBig: TTransform = (

  (1, 0, 0, 0),
  (0, 1, 0, 0),
  (0, 0, 1, 0),
  (0, 0, 0, 1) )  ;




  fi : double = pi / 90;


implementation

{$R *.dfm}

procedure TForm1.FormPaint(Sender: TObject);

  var

  Vp: array [0..3] of TVertex;


begin

Canvas.TextOut(100,100,'кнопки управления: +/-');
Canvas.TextOut(100,120,'кнопки управления: Delete/PageDown');
Canvas.TextOut(100,140,'кнопки управления: Влево/Вправо и Вврех/Вниз');
Canvas.TextOut(100,160,'кнопки управления: Shift + Влево/Вправо и Shift + Вврех/Вниз');

  ApplyTransform(Vp, V, L);

  ApplyTransform(Vp, Vp, Pp);
  NormCoors(Vp);

  ApplyTransform(Vp, Vp, C);


  DrawWireFace(Canvas, Vp[0], Vp[1], Vp[2]);
  DrawWireFace(Canvas, Vp[1], Vp[2], Vp[3]);
  DrawWireFace(Canvas, Vp[2], Vp[3], Vp[0]);
  DrawWireFace(Canvas, Vp[3], Vp[0], Vp[1]);


end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

//ApplyTransForm(V, V, T);

ApplyTransForm(V, V, Rz);
//ApplyTransForm(V, V, Rz);
//ApplyTransForm(V, V, Rz);


Refresh;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin


Rz[0,0] := cos(fi);
Rz[1,0] := -sin(fi);
Rz[1,1] := cos(fi);
Rz[0,1] := sin(fi);

RxLeft[1,1] := cos(fi);
RxLeft[1,2] := sin(fi);
RxLeft[2,1] := -sin(fi);
RxLeft[2,2] := cos(fi);

RxRight[1,1] := cos(-fi);
RxRight[1,2] := sin(-fi);
RxRight[2,1] := -sin(-fi);
RxRight[2,2] := cos(-fi);



// Сжатие:
RxSmall[0,0] := 0.99; //Koefficient;
RxSmall[1,1] := 0.99;
RxSmall[2,2] := 0.99;

// Растяжение:
RxBig[0,0] := 1.01;
RxBig[1,1] := 1.01;
RxBig[2,2] := 1.01;

//CombineTransform(T, P, Rz);
//CombineTransform(T, T, P2);


// Преобразование в локальную систему координат:
ApplyTransform(V, V, L1);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

// Перемещение вдоль локальной оси влево и вправо: (матрица PyLeft и PyRight - слева)
if (Key = VK_LEFT) and (ssShift in Shift) then  CombineTransform(L, PyLeft, L);  //fi := - pi / 90;
if (Key = VK_RIGHT) and (ssShift in Shift) then CombineTransform(L, PyRight, L);  //ApplyTransform(V, V, Py);

// Перемещение: (матрица PyLeft и PyRight - справа)
if Key = VK_LEFT  then CombineTransform(L, L, PyLeft);  //fi := - pi / 90;
if Key = VK_RIGHT then CombineTransform(L, L, PyRight);  //ApplyTransform(V, V, Py);


if Key = VK_UP then  CombineTransform(L, L, PzUp);
if Key = VK_DOWN then CombineTransform(L, L, PzDown);

// Перемещение вдоль локальной оси вверх и вниз: (матрица PzUp и PzDown - слева)
if (Key = VK_UP) and (ssShift in Shift) then  CombineTransform(L, PzUp, L);  //fi := - pi / 90;
if (Key = VK_DOWN) and (ssShift in Shift) then CombineTransform(L, PzDown, L);  //ApplyTransform(V, V, Py);


// Поворот влево
if Key = VK_DELETE then  CombineTransform(L, RxLeft, L);

// Поворот вправо:
if Key = VK_NEXT then CombineTransform(L, RxRight,L);


// Уменьшить объект:
if Key = 189 then
begin
CombineTransform(L, L, RxSmall);
end;

// Увеличить объект:
if Key = 187 then
begin
CombineTransform(L, L, RxBig);
end;


//FormCreate(Sender);


end;

end.



Подключи файл Wire3D.pas в папку проекта:
Код
  {модуль содержит процедуры для каркасного изображения трехмерных объектов}

unit wire3D;

interface

uses Types, SysUtils, Graphics, matrices3D;

//Рисует треугольную грань по координатам проекций ее трех вершин V0, V1, V2.
//Координаты заданы в пространственной системе координат, плосокость Oxy,
//начало и оси x и y которой совпадают соответственно с плоскостью экрана,
//началом и осями x и у экранной системы координат
procedure DrawWireFace(const Canvas : TCanvas;
                       const V0, V1, V2 : TVertex);

//Рисует ребро по координатам его концевых вершин V0 и V1.
//Координаты заданы в пространственной системе координат, плосокость Oxy,
//начало и оси x и y которой совпадают соответственно с плоскостью экрана,
//началом и осями x и у экранной системы координат
procedure DrawEdge(const Canvas : TCanvas;
                   const V0, V1 : TVertex);
                       

implementation

//Рисует треугольную грань по координатам проекций ее трех вершин V0, V1, V2.
//Координаты заданы в пространственной системе координат, плосокость Oxy,
//начало и оси x и y которой совпадают соответственно с плоскостью экрана,
//началом и осями x и у экранной системы координат
procedure DrawWireFace(const Canvas : TCanvas;
                       const V0, V1, V2 : TVertex);
begin
  Canvas.Polyline([
    Point(round(V0[0]),round(V0[1])),
    Point(round(V1[0]),round(V1[1])),
    Point(round(V2[0]),round(V2[1])),
    Point(round(V0[0]),round(V0[1]))
  ]);
end;

//Рисует ребро по координатам его концевых вершин V0 и V1.
//Координаты заданы в пространственной системе координат, плосокость Oxy,
//начало и оси x и y которой совпадают соответственно с плоскостью экрана,
//началом и осями x и у экранной системы координат
procedure DrawEdge(const Canvas : TCanvas;
                   const V0, V1 : TVertex);
var
  i : integer;
begin
  Canvas.Polyline([
    Point(round(V0[0]),round(V0[1])),
    Point(round(V1[0]),round(V1[1]))
  ]);
end;


end.
В данный момент нет под рукой Delfi, но думаю, что работать должно smile 

Это сообщение отредактировал(а) Voldemar2004 - 25.4.2007, 11:55


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
Alexeis
Дата 25.4.2007, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 5
Всего: 459



Voldemar2004, это немного из другой области smile Поворот картинок делается несколько по другому. Действия производятся в обратном порядке. Пусть есть исходная битовая карта и результирующая, тогда для каждой точки из результирующей производят поворот на назад, т.е. отображают ее на исходную матрицу. Естественно эта точка там попадает между четырьмя точками, тогда используя, например билинейную интерполяцию по 4м точкам вычисляют цвет этой точки, иногда для ускорения используют цвет ближайшей к ней точки, но качество хуже чем для билинейной. Наилучшее качество получиться при построении кубического сплайна.

Добавлено через 1 минуту и 35 секунд
  Примерчик есть только на делфи, так что извини  smile 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Voldemar2004
Дата 25.4.2007, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Цитата(Alexeis @  25.4.2007,  13:07 Найти цитируемый пост)
Примерчик есть только на делфи, так что извини 
Все равно выкладывай, интересно же, а перевести в С++ проблемы не составит ! smile  smile 



--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.0762 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.