Matlab - risanje v 3D in filmi

Matlab - risanje v 3D in filmi

Avtor: Matija Lokar

Od opisne datoteke do funkcije in še risanje v 3D

  • Denimo, da bi radi narisali znamenito sedlo

    • ploskev x2 – y2
  • Risanje v 3D

    • generiranje ustrezne mreže točk

      • [x,y]=meshgrid(-2:1:2,-2:1:2);
      • z = yi.^2 - xi.^2;
    • Ploskev

      • mesh(x,y,z)
        Žični model pobarvan tako, da barva ustreza višini (določeni z z)
      • surf(x,y,z)
        Enako, le da so ploskve v mreži pobarvane

Opisna datoteka

x = -1:0.05:1;
y = x;
[xi, yi] = meshgrid(x,y);
zi = yi.^2 - xi.^2;
mesh(xi, yi, zi)
axis off
figure
surf(xi, yi, zi)
axis off

sedlo1.m

x = -1:0.05:1;
y = x;
[xi, yi] = meshgrid(x,y);
zi = yi.^2 - xi.^2;
mesh(xi, yi, zi)
axis off
figure
surf(xi, yi, zi)
axis off

Rezultat

(slika_matlab56.png) (slika_matlab57.png)

Pretvorimo v funkcijo

function sedloFun(a, b )
%sedlo x^2 - y^2 na območju a x b
    x = linspace(a, b, 100);
    y = x;
    [xi, yi] = meshgrid(x,y); % pravokotno območje točk
    zi = yi.^2 - xi.^2;
    mesh(xi, yi, zi) % 3D žični model
    meshc(xi, yi, zi) % še "obrisne" krivulje
    axis off
end

sedloFun.m

Prikaz

(slika_matlab58.png)

function sedloFun(a, b )
%sedlo x^2 - y^2 na območju a x b
    x = linspace(a, b, 100);
    y = x;
    [xi, yi] = meshgrid(x,y); % pravokotno območje točk
    zi = yi.^2 - xi.^2;
    mesh(xi, yi, zi) % 3D žični model
    meshc(xi, yi, zi) % še "obrisne" krivulje
    axis off
end

Še malo "dodatkov"

function sedloFunNovo(a, b )
%sedlo x^2 - y^2 na območju a x b
    if (nargin() == 1)
        a = -abs(a);
        b = -a; % [-|a|, |a|]
    end
    if (nargin() == 0)
        a = -2;
        b = 2; %
    end
    x = linspace(a, b, 100);
    y = x;
    [xi,yi] = meshgrid(x,y);
    zi = yi.^2 - xi.^2;
    surfc(xi,yi,zi)
    colormap copper % barvna shema
    shading interp  % senčenje
    view([25,15,20]) % točka gledišča
    grid off
    title('Hiperbolični paraboloid z = y^2 – x^2')
    h = get(gca,'Title');
    set(h,'FontSize',12)
    xlabel('x')
    h = get(gca,'xlabel');
    set(h,'FontSize',12)
    ylabel('y')
    h = get(gca,'ylabel');
    set(h,'FontSize',12)
    zlabel('z')
    h = get(gca,'zlabel');
    set(h,'FontSize',12)
    pause(5)
    figure
    contourf(zi), hold on, shading flat
    [c,h] = contour(zi,'k-'); clabel(c,h)
    title('Nivojske krivulje z = y^2 - x^2.')
    h = get(gca,'Title');
    set(h,'FontSize',12)
    xlabel('x')
    h = get(gca,'xlabel');
    set(h,'FontSize',12)
    ylabel('y')
    h = get(gca,'ylabel');
    set(h,'FontSize',12)
end

sedloFunNovo.m

function sedloFunNovo(a, b )
%sedlo x^2 - y^2 na območju a x b
    if (nargin() == 1)
        a = -abs(a);
        b = -a; % će je le en argument, potem naj bo [-|a|, |a|]
    end
    if (nargin() == 0)
        a = -2;
        b = 2; %
    end
    x = linspace(a, b, 100);
    y = x;
    [xi,yi] = meshgrid(x,y);
    zi = yi.^2 - xi.^2;
    surfc(xi,yi,zi)
    colormap copper % barvna shema
    shading interp  % senčenje
    view([25,15,20]) % točka gledišča
    grid off
    title('Hiperbolični paraboloid z = y^2 – x^2')
    h = get(gca,'Title');
    set(h,'FontSize',12)
    xlabel('x')
    h = get(gca,'xlabel');
    set(h,'FontSize',12)
    ylabel('y')
    h = get(gca,'ylabel');
    set(h,'FontSize',12)
    zlabel('z')
    h = get(gca,'zlabel');
    set(h,'FontSize',12)
    pause(5)
    figure
    contourf(zi), hold on, shading flat
    [c,h] = contour(zi,'k-'); clabel(c,h)
    title('Nivojske krivulje ploskve z = y^2 - x^2.')
    h = get(gca,'Title');
    set(h,'FontSize',12)
    xlabel('x')
    h = get(gca,'xlabel');
    set(h,'FontSize',12)
    ylabel('y')
    h = get(gca,'ylabel');
    set(h,'FontSize',12)
end

In rezultat

(slika_matlab59.png) (slika_matlab60.png)

Nekaj zgledov

[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
mesh(X,Y,Z,'EdgeColor','black')
(slika_matlab61.png)

zgled3D_1.m

% Zgled 3D
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
mesh(X,Y,Z,'EdgeColor','black')

Nekaj zgledov

[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
surf(X,Y,Z)
colormap hsv
colorbar
(slika_matlab62.png)

zgled3D_2.m

% Zgled 3D
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
surf(X,Y,Z)
colormap hsv
colorbar

Nekaj zgledov

[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
surf(X,Y,Z)
colormap hsv
alpha(0.4)
(slika_matlab63.png)

zgled3D_3.m

% Zgled 3D
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
surf(X,Y,Z)
colormap hsv
colorbar

Nekaj zgledov

[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
surf(X,Y,Z,'FaceColor','red',
'EdgeColor','none')
camlight left;
lighting phong
(slika_matlab64.png)

zgled3D_4.m

% Zgled 3D
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
surf(X,Y,Z,'FaceColor','red','EdgeColor','none')
camlight left;
lighting phong

Filmi (animacije)

  • Film je zaporedje slik

    • In če jih menjamo dovolj hitro, "vidimo" gibanje
  • Ideja

    • Znotraj zanke for ustvarjamo zaporedje slik
    • Posamezne slike "posnamemo"

      • Ukaz: getframe
    • Zaporedje slik predvajamo

      • movie

Shema "snemalne knjige"

for sl = 1:n % n sličic
  % risanje grafa
  % dobimo sl-to sliko
  film(sl) = getframe; % zapomnimo si sl-to sliko
end

Predvajanje

movie (film)

Zgled

function film = Snemanje(n)
%Snemanje posname n sličic "filma"
    x = 0 : 0.01 : 2*pi;
    for i = 1 : n
        plot(x, sin(i*x));
        axis([0, 2*pi, -1, 2]);
        film(i) = getframe;
    end
end

Snemanje.m

function film = Snemanje(n)
%Snemanje posname n sličic "filma"
    x = 0 : 0.01 : 2*pi;
    for i = 1 : n
        plot(x, sin(i*x));
        axis([0, 2*pi, -1, 2]);
        film(i) = getframe;
    end
end

Malček "olepšan"

function film = filmMatlab(n)
%Snemanje posname n sličic "filma"
  if (nargin == 0)
     n = 19;
  end
  x = linspace(0, 2*pi, 100);
  for t=1:n % n posameznih slik
    i = t;
    if (i > n/2) % od pol dalje gremo nazaj
      i = n + 1 - i;
    end
    h1_line = plot(x,sin(i*x));
        set(h1_line,'LineWidth',1.5,'Color','m')
    grid
    title('Sin(kx), k = 1, 2, 3, ... ')
    h = get(gca,'Title');
    set(h,'FontSize',12)
 xlabel('x')
 k = num2str(i);
 if i > 1
   s = strcat('sin(',k,'x)');
 else
   s = 'sin(x)';
 end
 ylabel(s)
 h = get(gca,'ylabel');
 set(h,'FontSize',12)
 film(t) = getframe; % zapomnimo si sliko
 if (n < 10)
    pause(1);
     % počakamo sekundo s sliko, a le,
     % če jih je malo
 end
end
end

filmMatlab.m

function film = filmMatlab(n)
%Snemanje posname n sličic "filma"
    if (nargin == 0)
        n = 19;
    end
    x = linspace(0, 2*pi, 100);
    for t=1:n % n posameznih slik
        i = t;
        if (i > n/2) % od pol dalje gremo nazaj
            i = n + 1 - i;
        end
        h1_line = plot(x,sin(i*x));
        set(h1_line,'LineWidth',1.5,'Color','m')
        grid
        title('Funkcije sin(kx), k = 1, 2, 3, 4, 5 ... ')
        h = get(gca,'Title');
        set(h,'FontSize',12)
        xlabel('x')
        k = num2str(i);
        if i > 1
            s = strcat('sin(',k,'x)');
        else
            s = 'sin(x)';
        end
        ylabel(s)
        h = get(gca,'ylabel');
        set(h,'FontSize',12)
        film(t) = getframe; % zapomnimo si sliko
        if (n < 10)
            pause(1); % počakamo sekundo s sliko, a le, če jih je malo
        end
   end
end

"Dodatki"

  • Ponavljanje filma

    • movie(film, n)
    • Film izveden n-krat
  • Vnaprej pripravimo prostor

    • film = moviein(nframes);

Pa še en z drsnikom in Fourierjevo transformacijo

h = uicontrol('style','slider','position',...
    [10 50 20 300],'Min',1,'Max',16,'Value',1);
for k = 1:16
    plot(fft(eye(k+16)))
    axis equal
    set(h,'Value',k)
    fiM(k) = getframe(gcf);
    pause(0.5);
end
clf
axes('Position',[0 0 1 1])
movie(fiM)

filmPrimer_1.m

h = uicontrol('style','slider','position',...
  [10 50 20 300],'Min',1,'Max',16,'Value',1);
for k = 1:16
  plot(fft(eye(k+16)))
  axis equal
  set(h,'Value',k)
  fiM(k) = getframe(gcf);
    pause(0.5);
end
clf
axes('Position',[0 0 1 1])
movie(fiM)

Zgled v 3D

Z = peaks; surf(Z);
axis tight
set(gca,'nextplot','replacechildren');
% Posnamimo film
for j = 1:20
    surf(sin(2*pi*j/20)*Z,Z)
    F(j) = getframe;
end
% predvajajmo ga 10x
movie(F,10)

filmPrimer_2.m

Z = peaks; surf(Z);
axis tight
set(gca,'nextplot','replacechildren');
% Posnamimo film
for j = 1:20
  surf(sin(2*pi*j/20)*Z,Z)
  F(j) = getframe;
end
% predvajanjmo ga 10x
movie(F,10)

Še en v 3D z dvema slikama

r = subplot(2,1,1) % dve sliki v enem oknu
Z = peaks; surf(Z);
axis tight
set(gca,'nextplot','replacechildren');

s = subplot(2,1,2)  % dve sliki v enem oknu
Z = peaks; surf(Z);
axis tight
set(gca,'nextplot','replacechildren');
% Posnemimo film
for j = 1:20
    axes(r)
    surf(sin(2*pi*j/20)*Z,Z)
    axes(s)
    surf(sin(2*pi*(j+5)/20)*Z,Z)
    F(j) = getframe(gcf);
    pause(.0333)
end
h2 = figure;
% Tehnična podrobnost!
% če ne bi uporabili h2, bi film "padel" ven iz okvira
movie(h2,F,10)
(slika_matlab65.png)

filmPrimer_3.m

r = subplot(2,1,1) % dve sliki v enem oknu
Z = peaks; surf(Z);
axis tight
set(gca,'nextplot','replacechildren');

s = subplot(2,1,2)  % dve sliki v enem oknu
Z = peaks; surf(Z);
axis tight
set(gca,'nextplot','replacechildren');
% Posnemimo film
for j = 1:20
  axes(r)
    surf(sin(2*pi*j/20)*Z,Z)
  axes(s)
  surf(sin(2*pi*(j+5)/20)*Z,Z)
    F(j) = getframe(gcf);
  pause(.0333)
end
h2 = figure;
% Tehnična podrobnost!
% Če ne bi uporabili h2, bi film "padel" ven iz okvira
movie(h2,F,10)

In za konec še potujoči "eksponentni sinus"

function film = filmMatlab_2(nframes)
    %Snemanje posname n slieic "filma"
    if (nargin == 0)
        nframes = 40;
    end
    x=linspace(-2,2,50);
    y=exp(-8*x.*x);
    plot(x,y);
    lim=axis;

    film = moviein(nframes); % pripravimo prostor

    dt=2/nframes;
    for it=1:nframes
        z=x-sin(2*pi*it*dt);
        y=exp(-8*z.*z);
        plot(x,y)
        axis(lim)
        drawnow;
        film(it)=getframe;
    end
end
(slika_matlab66.png)

filmMatlab_2.m

function film = Snemanje(n)
%Snemanje posname n sličic "filma"
    x = 0 : 0.01 : 2*pi;
    for i = 1 : n
        plot(x, sin(i*x));
        axis([0, 2*pi, -1, 2]);
        film(i) = getframe;
    end
end
0%
0%