Você está na página 1de 16

1

Como criar animaes com o MATLAB

1. Introduo

Quando os movimentos de corpos rgidos so computados, h casos em que queremos


verificar os movimentos por meio de animaes. Este tutorial explica como fazer animaes
de movimentos de corpo rgido com MATLAB.

2. Ideia fundamental da animao

Primeiro, consideramos um caso unidimensional simples para ilustrar a ideia fundamental


da animao.
Suponha que um ponto se mova no eixo x com o tempo. Se as posies do ponto so
dadas por um intervalo de tempo fixo como x = x1, x2, x3, ..., ento uma animao do ponto
de movimento pode ser feita pelo loop seguinte 1-3. Suponha que o ponto representado por
um pequeno crculo. (Ver Figura 1).

Figura 1. Movimento do ponto em uma dimenso.

i. Apague o crculo anterior;


ii. Desenhe o crculo em x = x i
iii. i=i+1
3. Animao de um ponto em movimento
2

O Cdigo abaixo um exemplo de script que produz uma animao de um ponto em


movimento. Para obter uma animao suave, importante definir "Renderer" e "EraseMode"
adequadamente.

% Animao de um ponto em movimento

clear all; close all; clc;

% Criao de dados
t = 0:0.001:1; % Varivel tempo
x = sin(2*pi*t); % Varivel posio

% Desenho da figura inicial


figure(1);
set(gcf,'Renderer','OpenGL');
h = plot(x(1),0,'o','MarkerSize',20,'MarkerFaceColor','b');
set(h,'EraseMode','normal');
xlim([-1.5,1.5]);
ylim([-1.5,1.5]);

% Loop de animao
i = 1;
while i<=length(x)
set(h,'XData',x(i));
drawnow;
i = i+1;
end

4. Sobre a funo PATCH

Para fazer uma animao de um corpo rgido, primeiro temos que criar uma forma que
representa o corpo rgido. No MATLAB podemos usar "patch" para criar uma forma
tridimensional arbitrria. Um patch uma superfcie poligonal definida por trs ou mais
vrtices. Ao combinar vrios patches podemos criar um poliedro arbitrrio.
Por exemplo, o cdigo abaixo um script MATLAB que desenha um patch triangular com
trs vrtices em (1,0,0), (0,2,0) e (0,0,3).

% test_patch.m

clear; close all; clc;

% Vrtices
x(1)=1; y(1)=0; z(1)=0;
3

x(2)=0; y(2)=2; z(2)=0;


x(3)=0; y(3)=0; z(3)=3;

% Desenhar patch
figure(1);
patch(x,y,z,'y');

% Configurao dos eixos


xlabel('x','FontSize',14);
ylabel('y','FontSize',14);
zlabel('z','FontSize',14);
set(gca,'FontSize',14);
axis vis3d equal;
view([142.5,30]);
camlight;
grid on;

O patch desenhado por este script mostrado na Figura 2.

Figura 2. Um patch triangular de vrtices em (1,0,0), (0,2,0) e (0,0,3).

5. Criando uma forma - Bloco (1)

Vamos criar uma forma de bloco combinando seis patches. Consideramos primeiro o caso
em que um dos vrtices coincide com a origem do sistema de coordenadas e cada lado
paralelo ao eixo de coordenadas, como mostrado na Figura 3 (chamamos isso de
"configurao bsica"). Neste caso, se o comprimento de cada lado ( Lx , L y , Lz ) dado, as
coordenadas dos oito vrtices so bvias. Os seis patches so definidos pelas seguintes
combinaes de vrtices:
4

Figura 3. Forma do bloco (Configurao bsica).

1-2-5-3
1-3-6-4
1-4-7-2
4-7-8-6
2-5-8-7
3-6-8-5

O script MATLAB para desenhar um bloco na configurao bsica mostrado no cdigo


abaixo.

% make_block_special.m

clear; close all;

Lx = 0.15;
Ly = 0.05;
Lz = 0.30;

% Vertices
VertexData = [Lx*ones(8,1),Ly*ones(8,1),Lz*ones(8,1)]...
.*[0,0,0;
1,0,0;
0,1,0;
0,0,1;
1,1,0;
0,1,1;
1,0,1;
1,1,1];

% Patches
5

Index_Patch = ...
[1,2,5,3;
1,3,6,4;
1,4,7,2;
4,7,8,6;
2,5,8,7;
3,6,8,5];

n_pat = 6;

for i_pat=1:n_pat

% Patches data
PatchData_X(:,i_pat) = VertexData(Index_Patch(i_pat,:),1);
PatchData_Y(:,i_pat) = VertexData(Index_Patch(i_pat,:),2);
PatchData_Z(:,i_pat) = VertexData(Index_Patch(i_pat,:),3);
end

% Desenhar patches
figure(1);
h = patch(PatchData_X,PatchData_Y,PatchData_Z,'y');
set(h,'FaceLighting','phong','EdgeLighting','phong');
set(h,'EraseMode','normal');

% Configurao dos eixos


xlabel('x','FontSize',14);
ylabel('y','FontSize',14);
zlabel('z','FontSize',14);
set(gca,'FontSize',14);
axis vis3d equal;
view([-37.5,30]);
camlight;
grid on;
xlim([-0.15,0.35]);
ylim([-0.2,0.3]);
zlim([-0.1,0.4]);

O bloco desenhada pelo script cima mostrada na Figura 4, abaixo.


6

Figura 4. Uma forma de bloco feita de patches (na configurao bsica)

6. Criando uma forma Bloco (2)

Como mostrado na Figura 5, um bloco numa configurao geral pode ser definida pela
posio e pela orientao de um quadro de referncia ligado a um dos vrtices e ao
comprimento de cada lado (Lx, Ly, Lz). Se a posio e a orientao da trama de referncia so
r e R, respectivamente, ento as coordenadas dos vrtices so obtidas pela seguinte equao:

Pi=r + R P0i ,i =1,2, , 8

Onde P0i a coordenada do isimo vrtice na configurao bsica. Se as coordenadas dos


vrtices so obtidas, ns podemos fazer uma forma de bloco combinando seis patches da
mesma maneira da seco anterior.
7

Figura 5. Forma de bloco (Configurao geral).

Um script MATLAB para desenhar um bloco na configurao geral mostrado abaixo:

% make_block_general.m

clear; close all;

% Block specification
r = [1,1,1]; % Reference position
A = [-pi/3, 0, pi/6]; % Reference orientation (x-y-z Euler angle)

Lx = 0.15;
Ly = 0.05;
Lz = 0.30;

% Euler angle -> Orientation matrix


a1 = A(1);
a2 = A(2);
a3 = A(3);

R1 = [1, 0, 0;
0, cos(a1), -sin(a1);
0, sin(a1), cos(a1)];

R2 = [cos(a2), 0, sin(a2);
0, 1, 0;
-sin(a2), 0, cos(a2)];

R3 = [cos(a3), -sin(a3), 0;
sin(a3), cos(a3), 0;
0, 0, 1];

R = R1*R2*R3;
8

% Vertices
VertexData_0 = [Lx*ones(8,1),Ly*ones(8,1),Lz*ones(8,1)]...
.*[0,0,0;
1,0,0;
0,1,0;
0,0,1;
1,1,0;
0,1,1;
1,0,1;
1,1,1];

n_ver = 8;

for i_ver=1:n_ver
VertexData(i_ver,:) = r + VertexData_0(i_ver,:)*R';
end

% Patches
Index_Patch = ...
[1,2,5,3;
1,3,6,4;
1,4,7,2;
4,7,8,6;
2,5,8,7;
3,6,8,5];

n_pat = 6;

for i_pat=1:n_pat

% Patches data
PatchData_X(:,i_pat) = VertexData(Index_Patch(i_pat,:),1);
PatchData_Y(:,i_pat) = VertexData(Index_Patch(i_pat,:),2);
PatchData_Z(:,i_pat) = VertexData(Index_Patch(i_pat,:),3);
end

% Draw patches
figure(1);
h = patch(PatchData_X,PatchData_Y,PatchData_Z,'y');
set(h,'FaceLighting','phong','EdgeLighting','phong');
set(h,'EraseMode','normal');

% Axes settings
xlabel('x','FontSize',14);
ylabel('y','FontSize',14);
zlabel('z','FontSize',14);
set(gca,'FontSize',14);
axis vis3d equal;
view([-37.5,30]);
camlight;
grid on;
xlim([0.8,1.3]);
9

ylim([0.9,1.4]);
zlim([0.8,1.3]);

O bloco desenhado pelo script mostrada na figura 6, A varivel A no cdigo o ngulo de


Euler (x-y-z) representando a orientao de referncia.

Figura 6. Forma de bloco feita por patches (Na configurao geral).

7. Criando uma forma Cilindro (1)

Vamos criar uma forma cilndrica com patches. Seja a configurao bsica de um cilindro
uma configurao onde o centro do crculo inferior esteja na origem do Sistema de
coordenadas e o eixo central coincida com o eixo Z. O Script MATLAB para desenhar uma
forma cilndrica mostrada no cdigo abaixo.

% make_cylinder_special.m

clear; close all;

Radius = 0.1;
Height = 0.3;
SideCount = 20;

% Vertices
n_side = SideCount;

for i_ver=1:n_side
VertexData(i_ver,:) = [Radius*cos(2*pi/n_side*i_ver),Radius*sin(2*pi/n_side*i_ver),0];
VertexData(n_side+i_ver,:) =
[Radius*cos(2*pi/n_side*i_ver),Radius*sin(2*pi/n_side*i_ver),Height];
end
10

% Side Patches
for i_pat=1:n_side-1
Index_Patch1(i_pat,:) = [i_pat,i_pat+1,i_pat+1+n_side,i_pat+n_side];
end
Index_Patch1(n_side,:) = [n_side,1,1+n_side,2*n_side];

for i_pat=1:n_side

% Side patches data


PatchData1_X(:,i_pat) = VertexData(Index_Patch1(i_pat,:),1);
PatchData1_Y(:,i_pat) = VertexData(Index_Patch1(i_pat,:),2);
PatchData1_Z(:,i_pat) = VertexData(Index_Patch1(i_pat,:),3);
end

% Draw side patches


figure(1);
h1 = patch(PatchData1_X,PatchData1_Y,PatchData1_Z,'y');
set(h1,'FaceLighting','phong','EdgeLighting','phong');
set(h1,'EraseMode','normal');

% Bottom Patches
Index_Patch2(1,:) = [1:n_side];
Index_Patch2(2,:) = [n_side+1:2*n_side];

for i_pat=1:2

% Bottom patches data


PatchData2_X(:,i_pat) = VertexData(Index_Patch2(i_pat,:),1);
PatchData2_Y(:,i_pat) = VertexData(Index_Patch2(i_pat,:),2);
PatchData2_Z(:,i_pat) = VertexData(Index_Patch2(i_pat,:),3);
end

% Draw bottom patches


figure(1);
h2 = patch(PatchData2_X,PatchData2_Y,PatchData2_Z,'y');
set(h2,'FaceLighting','phong','EdgeLighting','phong');
set(h2,'EraseMode','normal');

% Axes settings
xlabel('x','FontSize',14);
ylabel('y','FontSize',14);
zlabel('z','FontSize',14);
set(gca,'FontSize',14);
axis vis3d equal;
view([-37.5,30]);
camlight;
grid on;
xlim([-0.2,0.2]);
ylim([-0.2,0.2]);
zlim([-0,0.4]);

A forma cilndrica desenhada pelo script acima mostrada na figura 7.


11

Figura 7. Cilindro feito de patches (Configurao bsica).

8. Criando uma forma Cilindro (2)

O script MATLAB para desenhar um cilindro emu ma configurao geral mostrado abaixo:

% make_cylinder_general.m

clear; close all;

% Cylinder specification
r = [1,1,1]; % Reference position
A = [-pi/3, 0, 0]; % Reference orientation (x-y-z Euler angle)

Radius = 0.1;
Height = 0.3;
SideCount = 20;

% Euler angle -> Orientation matrix


a1 = A(1);
a2 = A(2);
a3 = A(3);

R1 = [1, 0, 0;
0, cos(a1), -sin(a1);
0, sin(a1), cos(a1)];

R2 = [cos(a2), 0, sin(a2);
0, 1, 0;
-sin(a2), 0, cos(a2)];

R3 = [cos(a3), -sin(a3), 0;
12

sin(a3), cos(a3), 0;
0, 0, 1];

R = R1*R2*R3;

% Vertices
n_side = SideCount;

for i_ver=1:n_side
VertexData_0(i_ver,:) = [Radius*cos(2*pi/n_side*i_ver),Radius*sin(2*pi/n_side*i_ver),0];
VertexData_0(n_side+i_ver,:) =
[Radius*cos(2*pi/n_side*i_ver),Radius*sin(2*pi/n_side*i_ver),Height];
end

n_ver = 2*n_side;

for i_ver=1:n_ver
VertexData(i_ver,:) = r + VertexData_0(i_ver,:)*R';
end

% Side Patches
for i_pat=1:n_side-1
Index_Patch1(i_pat,:) = [i_pat,i_pat+1,i_pat+1+n_side,i_pat+n_side];
end
Index_Patch1(n_side,:) = [n_side,1,1+n_side,2*n_side];

for i_pat=1:n_side

% Side patches data


PatchData1_X(:,i_pat) = VertexData(Index_Patch1(i_pat,:),1);
PatchData1_Y(:,i_pat) = VertexData(Index_Patch1(i_pat,:),2);
PatchData1_Z(:,i_pat) = VertexData(Index_Patch1(i_pat,:),3);
end

% Draw side patches


figure(1);
h1 = patch(PatchData1_X,PatchData1_Y,PatchData1_Z,'y');
set(h1,'FaceLighting','phong','EdgeLighting','phong');
set(h1,'EraseMode','normal');

% Bottom Patches
Index_Patch2(1,:) = [1:n_side];
Index_Patch2(2,:) = [n_side+1:2*n_side];

for i_pat=1:2

% Bottom patches data


PatchData2_X(:,i_pat) = VertexData(Index_Patch2(i_pat,:),1);
PatchData2_Y(:,i_pat) = VertexData(Index_Patch2(i_pat,:),2);
PatchData2_Z(:,i_pat) = VertexData(Index_Patch2(i_pat,:),3);
end

% Draw bottom patches


13

figure(1);
h2 = patch(PatchData2_X,PatchData2_Y,PatchData2_Z,'y');
set(h2,'FaceLighting','phong','EdgeLighting','phong');
set(h2,'EraseMode','normal');

% Axes settings
xlabel('x','FontSize',14);
ylabel('y','FontSize',14);
zlabel('z','FontSize',14);
set(gca,'FontSize',14);
axis vis3d equal;
view([-37.5,30]);
camlight;
grid on;
xlim([0.8,1.3]);
ylim([1,1.5]);
zlim([0.8,1.3]);

A forma cilndrica desenhada pelo script anterior mostrada na figura 8.

Figura 8. Cilindro feito por patches (Configurao geral).

9. Animao do bloco em movimento Preparao

A ideia fundamental da animao de um corpo rgido em movimento a mesma que a da


animao de um ponto em movimento discutido nos captulos 2 e 3. A nica diferena que
no caso de um corpo rgido movimento, o objeto a desenhar e apagar uma forma
tridimensional.
Vamos fazer uma animao de um bloco em movimento como um exemplo. Isso pode ser
feito com base no script no Captulo 6 para desenhar a forma de um bloco. Primeiro, vamos
definir as trs funes MATLAB a seguir para tornar o script conciso.
14

Euler2R: converte um ngulo de Euler em uma matriz de orientao (Cdigo 1)


GeoVerMakeBlock: calcula as coordenadas dos vrtices de um bloco (Cdigo 2)
GeoPatMakeBlock: calcula os dados de patches para um bloco (Cdigo 3)

Cdigo 1:
function R = Euler2R(A)

% Euler angle -> Orientation matrix


a1 = A(1);
a2 = A(2);
a3 = A(3);

R1 = [1, 0, 0;
0, cos(a1), -sin(a1);
0, sin(a1), cos(a1)];

R2 = [cos(a2), 0, sin(a2);
0, 1, 0;
-sin(a2), 0, cos(a2)];

R3 = [cos(a3), -sin(a3), 0;
sin(a3), cos(a3), 0;
0, 0, 1];

R = R1*R2*R3;

Cdigo 2:
function VertexData = GeoVerMakeBlock(Location,Orientation,SideLength)

r = Location;
R = Orientation;

Lx = SideLength(1);
Ly = SideLength(2);
Lz = SideLength(3);

VertexData_0 = [Lx*ones(8,1), Ly*ones(8,1), Lz*ones(8,1)]...


.*[0,0,0;
1,0,0;
0,1,0;
0,0,1;
1,1,0;
0,1,1;
1,0,1;
1,1,1];

n_ver = 8;

for i_ver=1:n_ver
15

VertexData(i_ver,:) = r + VertexData_0(i_ver,:)*R';
end

Cdigo 3:
function [PatchData_X,PatchData_Y,PatchData_Z] = GeoPatMakeBlock(VertexData)

Index_Patch = ...
[1,2,5,3;
1,3,6,4;
1,4,7,2;
4,7,8,6;
2,5,8,7;
3,6,8,5];

n_pat = 6;

for i_pat=1:n_pat

PatchData_X(:,i_pat) = VertexData(Index_Patch(i_pat,:),1);
PatchData_Y(:,i_pat) = VertexData(Index_Patch(i_pat,:),2);
PatchData_Z(:,i_pat) = VertexData(Index_Patch(i_pat,:),3);
end

Usando as trs funes MATLAB, ns podemos reescrever o script no captulo 6 para


desenhar um bloco, como no cdigo 4 abaixo:

% make_block.m

clear; close all;

% Block specification
r = [1,1,1]; % Reference position
A = [-pi/3, 0, pi/6]; % Reference orientation (x-y-z Euler angle)

Lx = 0.15;
Ly = 0.05;
Lz = 0.30;

% Euler angle -> Orientation matrix


R = Euler2R(A);

% Vertices
VertexData = GeoVerMakeBlock(r,R,[Lx,Ly,Lz]);

% Patches
[PatchData_X,PatchData_Y,PatchData_Z] = GeoPatMakeBlock(VertexData);

% Draw patches
figure(1);
16

h = patch(PatchData_X,PatchData_Y,PatchData_Z,'y');
set(h,'FaceLighting','phong','EdgeLighting','phong');
set(h,'EraseMode','normal');

% Axes settings
xlabel('x','FontSize',14);
ylabel('y','FontSize',14);
zlabel('z','FontSize',14);
set(gca,'FontSize',14);
axis vis3d equal;
view([-37.5,30]);
camlight;
grid on;
xlim([0.8,1.3]);
ylim([0.9,1.4]);
zlim([0.8,1.3]);