Uwaga. Wszystkie
M-pliki zamieszczone na tej stronie są do pobrania z tabeli znajdującej się na
głównej stronie przykładów
Prosta animacja
obiektów graficznych
Interaktywne sterowanie
rozkładem kolorów
Interaktywne
sterowanie obiektami - użycie własności ButtonDownFcn
Przykład 1. Program robaczek.m. Budowanie „od
zera” obiektów graficznych i prosta animacja.
%ROBACZEK.M
%ilustracja prostej animacji przy
pomocy HANDLE GRAPHICS
%w połączeniu z wysokopoziomowymi
poleceniami graficznymi
a = 2;
ile = 200;
x = linspace(-a,a,ile);
y =
x.^2-a/2;
skala = [-a:1:a];
okno
= figure;
set(gcf,'NumberTitle','Off','MenuBar','None','Name','Robaczek
zjada parabolę');
uklad = newplot;
parabola = plot(x,y,'.');
%sprawdź, co się dzieje, gdy w
linijce niżej ustawisz własność 'Erase' na 'Normal' lub 'xor'
wykres
= line('color','b','marker','o','Erase','Background',
...
'MarkerFace','red','MarkerSize',12,'xdata',x(1:3),'ydata',y(1:3));
set(uklad,'XLim',[-a,a],'XTick',[]);
set(uklad,'YLim',[-a,a],'YTick',[]);
shg;
for k = 5:ile;
set(wykres,'XData',x(k-4:k),'YData',y(k-4:k));
pause(0.02);
drawnow;
end;
cla;
kontrolatempa = [0.1 : 0.02: 1];
for k = kontrolatempa
text(0,0,'Popatrz jak ten napis znika...',...
'FontSize',16,'FontWeight','Bold','HorizontalAlignment','Center','Color',[k
k k]);
pause(0.05);
end;
cla;
set(uklad,'Color',[0 0 0]);
set(gcf,'KeyPressFcn',...
'if double(get(okno,''CurrentCharacter''))==27,close(gcf),end');
text(0,0,'ESC ZAMYKA OKNO','Color','r','FontSize',20,...
'FontWeight','Bold','HorizontalAlignment','Center');
Przykład 2. Program wykresy3d. Zastosowanie
elementów graficznego interfejsu użytkownika. Program rysuje powierzchnie o
równaniach parametrycznych podanych przez użytkownika.
%WYKRESY3D.M
%program ilustrujący mechanizmy
Graphical User Interface Matlaba
%Ilustracja obiektów FIGURE, AXES,
UICONTROL
%program pozwala na wprowadzenie
równań parametrycznych powierzchni w R^3
%-------------------------------------------------------
xstr = 's*cos(t)';
%początkowe równania x(s,t), y(s,t), z(s,t);
ystr = 's*sin(t)';
zstr = 's';
scrsz = get(0,'ScreenSize');%odczytujemy rozmiary ekranu komputera
figure('Position',[0.2
0.2 0.6 0.6].*scrsz([3 4 3 4]));%kreujemy okno
graficzne i ustalamy rozmiar
ezsurf(xstr,ystr,zstr);%rysujemy
powierzchnie daną równaniami
set(gcf,'NumberTitle','Off');%ustalamy
kilka własności okna graficznego - obiekt FIGURE
set(gcf,'Name','Wykresy
3D');
%set(gcf,'MenuBar','None');
set(gca,'Position',[0.05
0.2 0.85 0.7 ]);%ustalamy polozenie obiektu
AXES - układu współrzędnych
pozycjaetykiety = [10 60 50 20];%pozycja pierwszej etykiety pola edycyjnego
przesuniecie = [50 0 50 0];%przesuniecie
pola edycyjnego wzgl. etykiety
skok = [0 -25 0 0];%położenie
nastepnej etykiety
%definiujemy po kolei etykiety pól
edycyjnych i same pola
%----- pole do edycji x(s,t)
tip = 'Wpisz wyrazenie
zmiennych s i t';
uicontrol('Style','text','Position',pozycjaetykiety,'String',...
'y(s,t) = ','ForegroundColor','b','FontWeight','Bold');
polex
= uicontrol('Style','Edit','Position',pozycjaetykiety+przesuniecie,'String',xstr,...
'BackgroundColor','w','HorizontalAlignment','Left','TooltipString',...
tip,'FontWeight','Bold');
%----- pole do edycji y(s,t)
pozycjaetykiety = pozycjaetykiety + skok;
uicontrol('Style','text','Position',pozycjaetykiety,'String',...
'y(s,t) = ','ForegroundColor','b','FontWeight','Bold');
poley
= uicontrol('Style','Edit','Position',pozycjaetykiety+przesuniecie,'String',ystr,...
'BackgroundColor','w','HorizontalAlignment','Left','TooltipString',...
tip,'FontWeight','Bold');
pozycjaetykiety = pozycjaetykiety + skok;
%----- pole do edycji z(s,t)
uicontrol('Style','text','Position',pozycjaetykiety,'String',...
'z(s,t) = ','ForegroundColor','b','FontWeight','Bold');
polez
= uicontrol('Style','Edit','Position',pozycjaetykiety+przesuniecie,'String',zstr,...
'BackgroundColor','w','HorizontalAlignment','Left','TooltipString',...
tip,'FontWeight','Bold');
%definiujemy przyciski
pozycjapola = [10,30,100,20];
pozycjaguzika1 = pozycjaetykiety + przesuniecie +
[200 0 20 20];
pozycjaguzika2 = pozycjaguzika1 + [200 0 20 0];;
guzik1 = uicontrol('Style','PushButton','String','Rysuj teraz',...
'Position',pozycjaguzika1,'Callback',...
'ezsurf(get(polex,''String''),get(poley,''String''),get(polez,''String''))');
guzik2
= uicontrol('Style','PushButton','String','Koniec',...
'Position',pozycjaguzika2,'Callback',...
'close(gcf)');
shg;
Przykład
3. Program ambitnewykresy.m.
Ilustracja obsługi zdarzeń przez zewnętrzną M-funkcję oraz ilustracja użycia
gotowych okien dialogowych Matlaba.
Główny program wyświetla okno graficzne,
w którym rysowane są wykresy funkcji jednej zmiennej. Za pośrednictwem
pomocniczego okna dialogowego użytkownik może zdefiniować wyrażenie określające
funkcję, przedział, w którym ma być narysowana oraz liczbę punktów podziału dla funkcji plot.
Główny program
%AMBITNEWYKRESY.M
%Prosty przyklad graphical user interface
%program rysuje wykres zadanej
funkcji w zadanym przedziale
%dokladnie przestudiuj pliki
parametrydialog.m i rysujwgparametrow.m
%pamietaj, ze po zakonczeniu pracy
tego programu
%okno graficzne jest caly czas
aktywne, a przyciski "wrazliwe" na nacisniecie
h = figure; %otwieramy
nowe okno graficzne
%ilustracja własności
"Modal" - bez zamknięcia okna nie da się używać innych elementów
Matlaba
set(h,'WindowStyle','Modal');
set(h,'NumberTitle','Off');
set(h,'Name','Rysowanie krzywych postaci y = f(x)');
uklad = newplot;%jest
to zalecany sposob kreowania układu wspolrzednych;
set(uklad,'xlim',[0,2*pi],'ylim',[-1,
1]);
axis([0 1 0 1]);
%definiujemy przyciski akcji
ppg = [20 10]; %polozenie
lewego dolnego rogu pierwszego guzika
dlugguzika = 60;
wysguzika = 20;
%definicja przycisku
uruchamiającego okno dialogowe parametrów
guzikparametrow
= uicontrol('Style','PushButton','String','Parametry','Position',...
[ppg, dlugguzika, wysguzika]);
%definicja przycisku ZAMKNIJ
guzikzamknij = uicontrol('Style','PushButton','String','Zamknij','Position',...
[ppg(1)+dlugguzika+5,
ppg(2), dlugguzika, wysguzika]);
%inicjujemy domyślne parametry i
zapisujemy je we własności 'UserData' okna graficznego
biezaceparametry = {'exp(-x/20).*sin(x)';'0';'20*pi';'200'};
%zapamietujemy je we własności
'UserData' okna graficznego
set(gcf,'UserData',biezaceparametry);
%robimy pierwszy rysunek - patrz
M-funkcja wywolywana w nastepnej linijce
obsluga rysuj;
%podlaczamy obsługę zdarzeń do przycisków;
set(guzikparametrow,'Callback','obsluga
parametrydialog');
set(guzikzamknij,'Callback','obsluga
zamknij');
set(guzikzamknij,'Callback','obsluga
zamknij');
Okno
programu ambitnewykresy.m
Poniżej
zamieszczona jest pomocnicza M-funkcja realizująca obsługę zdarzeń polegających
na naciśnięciu jednego z przycisków w oknie programu ambitnewykresy.m.
-----------------------
(Początek M-pliku zawierającego funkcję)
function obsluga(akcja);
%obsluga zdarzeń w oknie głównym
programu AMBITNEWYKRESY
switch akcja
case 'rysuj'
rysujwgparametrow;
case 'parametrydialog'
ustawparametry;
case 'zamknij'
zamknijokno;
end;
function ustawparametry;
Zachety = {'Funkcja
f(x) = ...','Lewy koniec [a, b]',...
'Prawy koniec [a, b]','Liczba
punktow podzialu'};
Tytul = 'Dane do wykresu';
liczbalinijek = 1;
parametry = get(gcbf,'UserData');
%używamy gcbf, ale można też gcf;
%ilustracja wbudowanego w Matlaba
okna dialogowego inputdlg;
noweparametry = inputdlg(Zachety,Tytul,liczbalinijek,parametry);
%jesli user nacisnal Cancel, to noweparametry = {}
if isempty(noweparametry)
return
else
set(gcbf,'UserData',noweparametry);
rysujwgparametrow;
end;
function zamknijokno;
%m.in. ilustracja wbudowanego w
Matlaba okna dialogowego questdlg;
tytul = 'Pytanie:';
wynik = questdlg('Czy
zamknac okno graficzne?',tytul,'Tak','Nie','Nie');
if strcmp(wynik,'Tak')
close(gcf);
end;
%funkcja niżej nie jest
bezpośrednio wywoływana przez zdarzenia
%lecz przez główny program i przez
funkcję USTAWPARAMETRY
function rysujwgparametrow;
nazwypol = {'funkcja','lewykoniec','prawykoniec','ilepunktow'};
parametry
= get(gcf,'UserData');
s =
cell2struct(parametry,nazwypol,1);
%napisz help cell2struct, zeby
zrozumieć,
%dlaczego w ostatnim wywolaniu
dajemy parametr DIM = 1;
x =
linspace(eval(s.lewykoniec),eval(s.prawykoniec),eval(s.ilepunktow));
y = eval(s.funkcja);
plot(x,y,'LineWidth',2);
axis([min(x)
max(x) min(y) max(y)]);
Title(['\bf Wykres funkcji y = ', s.funkcja],'Color','red');
-------------------- (Koniec M-pliku)
Przykład 4 Program
suwakdemo.m. Ilustracja użycia suwaka do sterowania kolorami powierzchni.
%SUWAKDEMO.M
%ilustracja sterowania skalą
kolorów za pomocą suwaka
maksimum = 20;
zakresxy = [0 3 0 2*pi];
wyrx = '2*r*cos(t)';
wyry = 'r*sin(t)';wyrstozek = '3*r';
ezsurf(wyrx,wyry,wyrstozek,zakresxy,30);
colormap
hsv;
caxis([0
maksimum]);
slupek
= colorbar;
view(-37.5,10);
suwak
= uicontrol('Style','Slider','Min',1,'Max',maksimum,...
'Value',maksimum,'Position',[10
10 20 200],'SliderStep',[1/(2*(maksimum-1))
1/(maksimum-1)]);
pole
= uicontrol('Style','Edit','Position',[40,10,80,20],'BackgroundColor','white',...
'Enable','Off','Value',maksimum,'String',num2str(maksimum),'HorizontalAlignment','Left');
akcjasuwaka
= ...
['wartosc =
get(suwak,''Value'');set(pole,''Value'',wartosc);',...
'set(pole,''String'',num2str(wartosc));',...
'caxis([0 wartosc]);colorbar'];
set(suwak,'Callback',akcjasuwaka);
Okno programu suwakdemo.m
Przykład 5. Program buttondown.m. Ilustracja
użycia własności ButtonDownFcn do sterowania obiektami.
Następujący
program kreuje okno graficzne, rysuje wykresy 3 funkcji, a następnie definiuje
obsługę własności ButtonDownFcn dla wykreowanych obiektów AXES oraz
LINE. Kliknięcie w którykolwiek z wykresów zmienia jego grubość. Kliknięcie w
obszar układu współrzędnych poza wykresami rysuje czarny punkt w miejscu
kliknięcia. Kliknięcie w istniejący punkt usuwa go. Obsługą opisanych operacji
zajmuje się funkcja OBSLUGABUTTONDEMO.M. Funkcja ta musi znajdować się na
ścieżce dostępu Matlaba (zaleca się umieszczenie jej w tym samym katalogu, co
główny program).
Uwaga.
Zauważ, że właściwość ButtonDownFcn umożliwia interakcję z obiektami
graficznymi bez użycia funkcji Matlaba ginput.
%BUTTONDOWNDEMO.M
%program ilustrujący użycie
własności ButtonDownFcn obiektów LINE oraz AXES
%aby program działał prawidłowo,
należy na ścieżce Matlaba umieścić
%funkcję obsługi zdarzeń
OBSLUGABUTTONDOWN.M
%-----------------
%PROGRAM RYSUJE WYKRESY 3 FUNKCJI
%KLIKNIECIE W WYKRES ZMIENIA JEGO
GRUBOŚĆ
%KLIKNIĘCIE POZA WYKRESEM
"RYSUJE" CZARNY PUNKT
%KLIKNIĘCIE W NARYSOWANY WCZEŚNIEJ
PUNKT USUWA GO
t =
linspace(0,4*pi,500);
a =
5; b = 10;
y =
[exp(-t/a);-exp(-t/a);exp(-t/a).*sin(b*t)];
h =
plot(t,y,'LineWidth',2);
uklad
= gca;
Title('Kliknij w którąś krzywą lub obszar układu
współrzędnych','FontName','Arial CE','FontWeight','Bold','FontSize',12);
set(h,'ButtonDownFcn','set(gcbo,''LineWidth'',6
- get(gcbo,''LineWidth''))');
set(uklad,'ButtonDownFcn','obslugabuttondown
uklad');
Funkcja
obsługi zdarzeń programu BUTTONDOWNDEMO.M:
%OBSLUGABUTTONDOWN.M
%FUNKCJA OBSŁUGI ZDARZEŃ PROGRAMU
BUTTONDOWNDEMO.M
function obslugabuttondown(akcja);
switch akcja
case 'krzywe'
set(gcbo,'LineWidth',6
- get(gcbo,'LineWidth'));
case 'uklad'
punkt
= get(gca,'CurrentPoint');
x = punkt(1,1); y = punkt(1,2);
line('XData',punkt(1,1),'YData',punkt(1,2),...,
'Marker','o','MarkerFace','k','MarkerSize',6,...,
'EraseMode','Background','ButtonDownFcn','obslugabuttondown punkcik');
case 'punkcik'
delete(gcbo);
end
Rysunek
niżej przedstawia okno programu po kliknięciu przez użytkownika jednej z
krzywych i kilku punktów układu współrzędnych.
Okno programu buttondowndemo.m
Przykład 6. Program
movedemo.m. Ilustracja użycia własności ButtonDownFcn do przesuwania obiektu
graficznego.
Następujący
program kreuje okno graficzne, rysuje czerwoną kropkę na płaszczyźnie, a
następnie definiuje obsługę własności ButtonDownFcn dla obiektu LINE,
którym jest narysowana kropka. Kropkę można przesuwać myszą na zasadzie „drag
and drop”. Kliknięcie w obszar układu współrzędnych poza kropką powoduje jej „przybiegnięcie”
do punktu kliknięcia (spróbuj się tym pobawić: kliknij krótko w biały obszar
poza kropką i ucieknij myszą z tego miejsca; po paru chwilach odniesiesz
wrażenie, że bawisz się z czerwoną kropką w „kotka i myszkę”).
Obsługą
zdarzeń programu zajmuje się funkcja OBSLUGAMOVE.M. Funkcja ta musi znajdować
się na ścieżce dostępu Matlaba (zaleca się umieszczenie jej w tym samym
katalogu, co główny program).
%MOVEDEMO.M
%ILUSTRACJA WŁASNOŚCI
ButtonDownFcn obiektu LINE
h =
figure;
uklad
= newplot;
punkt
= plot(0,0,'o-','MarkerFace','r','MarkerEdge','r','MarkerSize',6,'EraseMode','Background');
set(uklad,'ButtonDownFcn','obslugamove
przyjdzdomnie');
axis([-3
3 -3 3]);
axis
equal;
set(punkt,'ButtonDownFcn','obslugamove
start','Tag','mojpunkt');
Title('Przesuwaj
czerwony punkt myszą. Klikaj też w biały obszar.',...,
'FontWeight','Bold','FontName','Arial CE','Color','b');
Funkcja
obsługi zdarzeń programu MOVEDEMO.M jest niżej. Wytłumacz na podstawie kodu,
dlaczego kulka „przybiega” do punktów kliknięcia z różnymi prędkościami. W
szczególności powiedz, w której linijce można wyczytać prędkość ruchu kulki.
%FUNKCJA OBSŁUGI ZDARZEŃ PROGRAMU
MOVEDEMO.M
function obslugamove(akcja)
switch akcja
case 'start'
set(gcbf,'WindowButtonMotionFcn','obslugamove
ruch');
set(gcbf,'WindowButtonUpFcn','obslugamove stop');
case 'ruch'
pkt
= get(gca,'CurrentPoint');
set(gco,'XData',pkt(1,1));
set(gco,'YData',pkt(1,2));
drawnow;
case 'stop'
set(gcbf,'WindowButtonMotionFcn','');
set(gcbf,'WindowButtonUpFcn','');
case 'przyjdzdomnie'
biezacypkt = get(gca,'CurrentPoint');
nowex = biezacypkt(1,1); nowey = biezacypkt(1,2);
mojobiekt
= findobj('Tag','mojpunkt');
starex =
get(mojobiekt,'XData');
starey =
get(mojobiekt,'YData');
p0 =
[starex starey]; p1 = [nowex nowey];
for t = 0 : 0.001: 1
biezacy = p0+t*(p1-p0);
set(mojobiekt,'XData',biezacy(1),'YData',biezacy(2));
drawnow;
end;
end;%switch