Лекція 7 Аффінне перетворення координат при моделюванні динаміки об'єктів



Скачати 155.51 Kb.
Дата конвертації30.12.2016
Розмір155.51 Kb.
ЛЕКЦІЯ 7
Аффінне перетворення координат при моделюванні динаміки об'єктів.
Перетворення координат графічних об'єктів використовуються вельми широко. Основні випадки:

- об'єкт описаний не в декартовій координатній системі

- зображення типових або таких, що повторюються деталей об'єкту

- побудова проекцій тривимірних об'єктів

- направлена деформація при синтезі нових форм

- мультиплікація.

Розрізняють двовимірні ( 2d ) і тривимірні ( 3d)

перетворення координат. Видів перетворень багато, розглянемо тільки так звані аффінні перетворення, коли в отримуваному зображенні об'єкту зберігається прямолінійність і паралельність прямих, а також ділення відрізань в заданих співвідношеннях.

Загальний вид формул двовимірних аффінних перетворень:

x* = a11 x + a12 y + a13



y* = a21 x + a22 y + a23

Тут x, у - координати початкового, а x*, y* - перетвореного об'єкту.

Коефіцієнти перетворень а I J зберігають

у вигляді матриці, розширеної до квадратної, при цьому a11 a12 a13

дуже просто обчислюються коефіцієнти якого-небудь a21 a22 a23

складного перетворення, якщо відомі коефіцієнти 0 0 1

перетворень, його складових. Для цього просто перемножують відповідні матриці коефіцієнтів.
Приклади типових перетворень і відповідні ним матриці: (Ф - початкова фігура, Ф* - перетворена )

Y

dx Ф* Паралельне 1 0 dx



dy перенесення 0 1 dy

Ф 0 0 1


X

Y



Ф*

Масштабування


M

0

0




M = x*/x = y*/y

0

M

0



Ф 0 0 1

X


Y Дзеркальне відображення

:
-1 0 0



Ф* Ф щодо осі Y 0 1 0

0 0 1

X

1 0 0

Ф* щодо осі X

0 -1 0

0 0 1



Y Ф* Y=Х
щодо осі Y=х 0 1 0

Ф 1 0 0

0 0 1

X

Ф* відносно початку -1 0 0

координат 0 -1 0

0 0 1


Y Ф*


Поворот відносно cos a -sin a 0

початку координат sin a cos a 0



Ф 0 0 1

X

Інші перетворення зазвичай представляють у вигляді

комбінацій перерахованих вище простих перетворень.
Наприклад, поворот щодо довільної крапки можна представити як комбінацію трьох перетворень:

- паралельне перенесення, що переводить центр повороту в початок координат

- поворот відносно початки координат

- паралельне перенесення, протилежне первинному.



Перемножування матриць виконується таким чином:



a11

a12

a13




b11

b12

b13




c11

c12

c13

a21

a22

a23

*

b21

b22

b23

=

c21

c22

c23

a31

a32

a33




b31

b32

b33




c31

c32

c33


де з I J = а I 1 * b 1 J + а I 2 * b 2 J + а I 3 * b J 3

тобто для розрахунку елементу матриці, розташованого в I-строчці і

J-столбці, обчислюється сума добутків елементів цього рядка в матриці A на відповідні елементи цього стовпця в матриці

B.
При знаходженні матриці коефіцієнтів складного перетворення координат важливий порядок перемножування: матриці перемножують послідовно від останньої до першої. Для приведеного вище прикладу першому перетворенню відповідає матриця В, другому - А.

У приведеній нижче програмі лінійчата фігура задається у вигляді масивів координат її вершин ха, уа на кресленні ( x, у - в

системі координат екрану ). Ці координати піддаються аффінним перетворенням, коефіцієнти перетворення зберігаються в

двовимірному масиві R. Початковому положенню фігури відповідає одинична матриця R (одиниці на головній діагоналі, останні члени - нулі).

При черговому перетворенні коефіцієнти матриці R перераховуються шляхом множення на неї матриці цього перетворення (А), отримувана матриця (В) знову записується в R. Нові координати x, у обчислюються в процедурі New_xy, яка викликається безпосередньо при виведенні фігури на екран процедурою PICT. Причому якщо встановити для малювання колір фону

то перерахунок координат проводитися не буде, що приведе до стирання старого зображення фігури - це зручно при імітації руху.

Всі прості перетворення координат (перенесення, обертання, масштабування, зрушення), а також деякі типові перетворення як комбінації прості оформлені у вигляді процедур.


uses Graph, Crt;

var Gd, Gm, n, i, j, до, xc, ус: integer;

ха, уа: array[1..50] of real; координати фігури на кресленні }

x, у : array[1..50] of integer; координати фігури на екрані

а, b, r: array[1..3, 1..3] of real; { масиви членів матриць 3*3

{--------------------------------------------------------------------------------------}

PROCEDURE I_r; { привласнення матриці R значення одиничної }
var i, j: integer ; begin


for I:=1 to 3 do begin

{

1

0

0

}

for j:=1

to 3 do

r[ i, j]:=0;




{

0

1

0

}







r[ i, i]:=1;

end; end;

{

0

0

1

}

{--------------------------------------------------------------------------------------}

ПРОЦЕДУРА MULT;

{ множення матриць А і R, результат (матр. В) записується в R }

var z: real; i, j, k: integer;

begin

for i:=1 to 3 do



for j:=1 to 3 do begin z:=0;

for k:=1 to 3 do z:=z+a[ i, k] * r[ k, j];

b[i, j]:=z end;

for i:=1 to 3 do

for j:=1 to 3 do r[ i, j]:=b[ i, j] end;

{---------------------------------------------------------------------------------------



---}

PROCEDURE New_xy;

{ обчислення нових координат фігури по базових коорд. XA, YA з використанням матриці перетворення R }

var i: integer ; begin

for i:=1 to n do begin

x[ i]:=round( xa[ i]* r[1, 1]+ ya[ i]* r[1, 2]+ r[1, 3] );



y[ i]:=round( xa[ i]* r[2, 1]+ ya[ i]* r[2, 2]+ r[2, 3] ) end; end;

{--------------------------------------------------------------------------------------}

PROCEDURE TRAN( dx, dy: real);

{ розрахунок матриць А і R для перенесення об'єкту на dx, dy }


var i, j: integer ; begin

for i:=1 to 3 do begin

{

1

0

dx

}

for j:=1 to 3 do a[i, j]:=0;

{

0

1

dy

}

a[ i, i]:=1 end; { 0 0 1 }



MULT; end;

a[1, 3]:=dx; a[2, 3]:=dy









PROCEDURE SCALE( sx, sy: real );

{ розрахунок матриць А і R для масштабування об'єкту:

по осі Х - множення на sx по осі Y - на sy }
var i, j: integer; begin { sx 0 0 }

for i:=1 to 3 do { 0 sy 0 }

for j:=1 to 3 do a[i, j]:=0; { 0 0 1 }

a[1, 1]:=sx; a[2, 2]:=sy; a[3, 3]:=1;

MULT; end;

{---------------------------------------------------------------------------------------}

PROCEDURE ROTATE( alfa: real );

{ розрахунок матриць А і R для повороту об'єкту на кут alfa(рад.):var c, s: real; i, j: integer;

begin { cos(alfa) -sin(alfa) 0 }

for i:=1 to 3 do { sin(alfa) cos(alfa) 0 }

for j:=1 to 3 do a[ i, j]:= 0; { 0 0 1 }

a[3, 3]:= 1;


c:=cos( alfa);

a[1, 1]:= c;

a[2, 2]:=c;

s:=sin( alfa);

a[1, 2]:=-s;

a[2, 1]:=s;

MULT; end;

{---------------------------------------------------------------------------------------}

PROCEDURE LOOK( alfa, dx, dy, sx, sy: real);

{ переклад об'єкту з локальної системи координат (на кресленні)

у систему координат екрану: - поворот об'єкту на кут alfa(рад.)

- перенесення на dx,dy

- масштабування sx,sy



- перерахунок базових координат ха, уа. }
var xx, yy: real; i: integer;

begin


I_R; ROTATE( alfa); TRAN( dx, dy); SCALE( sx, sy);

for i:=1 to n do begin

xx:=xa[ i] * r[1, 1]+ya[ i] * r[1, 2] + r[1, 3];

yy:=xa[ i] * r[2, 1]+ya[ i] * r[2, 2] + r[2, 3];

xa[ i]:=round( xx);

ya[ i]:=round( yy); end; I_R; end;

{---------------------------------------------------------------------------------------}


PROCEDURE PICT( color: word );

{ малювання фігури по координатах X,y }

var i: integer; begin setcolor( color);

if(color>0) then NEW_XY; { Обчислення нових координат фігури: перерахунок не проводиться при малюванні чорним кольором }

moveto( x[n], y[n] );

for i:=1 to n do lineto( x[ i], y[ i] ); end;

PROCEDURE RS( beta, kx, ky: real );

{ поворот фігури щодо її центру xm, ym на кут beta, а

також її масштабування (kx - коефіцієнт для осі x ky - для у)

без зсуву центру фігури }

var xm, ym: real; i: integer;

begin xm:=0; ym:=0;

for i:=1 to n do begin xm:=xm+x[ i]; ym:=ym+y[ i]; end;

xm:=xm /n; ym:=ym /n; { координати центру фігури }



TRAN(-xm, -ym); {Перенесення центру фігури в початок координат: }

ROTATE( beta);{центр повороту і центр масштабування}

SCALE(kx, ky);{співпадають з центром фігури. }

TRAN(xm, ym); Зворотне перенесення фігури

end;

{---------------------------------------------------------------------------------------}



PROCEDURE ROT_XY( xc, yc, beta: real);

{ поворот фігури щодо точки хс, вус на кут beta }

begin

TRAN(-xc, -yc); Зсув фігури так, щоб її нове положення відносно початку координат було таким же, як старе



положення відносно xc, ус. }

ROTATE( beta); поворот відносно початку координат }

TRAN(xc, ус); зворотний зсув фігури }end;
{---------------------------------------------------------------------------------------}

PROCEDURE AXES( alfa, beta: real);

{ розрахунок матриць А і R зсуву осей координат (деформація зрушення) вісь x зміщується на кут alfa, вісь у - на кут beta}
var i, j: integer; begin

for i:=1 to 3 do begin { 1 tg(beta) 0 }

for j:=1 to 3 do a[i, j]:=0; { tg(alfa) 1 0 }

a[i, i]:=1 end; { 0 0 1 }

a[1, 2]:=sin(beta) /cos( beta);

a[2, 1]:=sin( alfa) /cos( alfa); MULT; end;

{-------------------------------------------------------------------------------------}
PROCEDURE MIRROR( delta: real; index: byte);

{ розрахунок матриць А і R дзеркального відображення фігури

відносно осі паралельною одній з осей координат:
при index=1: щодо осі, -1 0 2*delta

паралельній осі Y 0 1 0

і що проходить через крапку (delta, 0). 0 0 1

при index=2: щодо осі, 1 0 0

паралельній осі Х 0 -1 2*delta



і що проходить через крапку (0,delta). 0 0 1

var i, j: integer; begin

for i:=1 to 3 do begin

for j:=1 to 3 do a[i, j]:=0;

a[i, i]:=1 end;

a[ index, index]:=-1; a[ index, 3]:=2*delta; MULT; end;

{---------------------------------------------------------------------------------------}

Визначаємо плоску фігуру : }


BEGIN

n:=4; { число вершин фігури }

xa[1]:= 5;

ya[1]:= 5;

{ координати вершин фігури на кресленні}

xa[2]:=70;

ya[2]:=20;




xa[3]:= 5;

ya[3]:=35;




xa[4]:=20; ya[4]:=20;

Gd:= Detect; InitGraph(Gd, Gm, ' ' );


LOOK( 0, 0, -70, 1, -1); { перехід до координат екрану }

PICT( 9); { показ початкового положення фігури}


--------- Приклади аффінних перетворень плоскої фігури ----------

SCALE( 4, 2); збільшення по осі х в 4 рази по осі у у 2 рази }

TRAN( 10,60); зсув по осі х на 10 пікселів, по осі у - на 60}

PICT( 14);

readln;

{--------------------Обертання із збільшенням і зсувом ------------------}



for i:=1 to 100 do begin

PICT( 13); виведення фігури }

RS( 0.04, 1.01, 1.01); поворот на 0.04 рад. і збільшення на 1%}

TRAN( 4, 0); delay(20); зсув фігури }

PICT( 0); стирання фігури - чорним по старих координатах }

end;


PICT( 13);

readln;


ClearDevice;

I_R;


{---------------- Обертання навколо центру, що зміщується ------------------}

for i:=1 to 60 do begin

PICT(14);

xc:=xc+3; yc:=yc+2; putpixel(xc, вус, 12); зсув центру xc,yc }

TRAN(3, 2); перенесення фігури відповідно зсуву центру }

Rot_xy(xc, вус, -0.3); поворот на 0.3 рад. відносно xc,yc }

delay(20);

PICT( 0); end;

readln;

Cleardevice;



I_r;

SCALE( 2, 4);

PICT(14);

{-------------- Зсуви осей координат (деформація зрушення) ----------}


AXES( 1, 0); зрушення осі х }PICT( 10); readln;

AXES(-1, 0); повернення PICT( 11);

AXES( 0, 1); зрушення осі у }PICT( 12); readln;

AXES( 0 -1); повернення PICT( 13);

for i:=1 to 100 do begin

AXES( 0.01, 0.01); поступове зрушення обох осей }

PICT( 0);

PICT(14);

delay(10); end;

readln;


Cleardevice;

I_r;


SCALE( 4, 4);

PICT(14);

{------------------- Дзеркальні відображення фігури -----------------------}

MIRROR(250, 1); PICT(10); { відображення щодо вертикалі }

MIRROR(150, 2); PICT(11); { відображення щодо горизонталі}

readln;

CloseGraph;END.





База даних захищена авторським правом ©lecture.in.ua 2016
звернутися до адміністрації

    Головна сторінка