Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ № 5 Создание приложений с GUI без среды GU...doc
Скачиваний:
9
Добавлен:
24.11.2019
Размер:
470.53 Кб
Скачать

Рисование кривых мышью

В MATLAB есть функция ginput, которая позволяет задавать точки на осях щелчком мыши и получить их координаты. В справочной системе в разделе Graphics: Creating Specialized Plots: Interactive Plotting приведен пример небольшого приложения, в котором заданные точки соединяются сплайном. В этом приложении предварительно требуется задать все точки и только затем построится сплайн. В этом разделе мы рассмотрим способ рисования кривых без использования функции ginput, при котором задание каждой новой точки сразу же приводит к перестроению проходящей через них кривой (см. рис. 1). Для добавления точек следует делать щелчок с удержанием Ctrl, а щелчок без Ctrl приводит к завершению соединения точек кривой.

Рис. 1. Рисование кривых мышью.

Алгоритм простой — при добавлении первой точки сплайн строить не нужно. Как только появляется вторая точка, следует построить сплайн, а при добавлении третьей, четвертой и т.д. точек нужно перестроить сплайн. Для сохранения данных (координат точек и указателя на линию) заведем структуру данных приложения Line, которую будем получать и сохранять при помощи функции guidata. Для обработки щелчка мыши запрограммируем возникающее при этом событие осей ButtonDownFcn в подфункции BtnDown. В ней проверим, что точка, в которой сделан щелчок, лежит в пределах осей. Координаты точки получим при помощи свойства CurrentPoint осей. Далее определим тип щелчка, для чего задействуем свойство SelectionType графического окна. При обычном щелчке мышью это свойство принимает значение ‘normal’, а при щелчке левой кнопкой с удержанием Ctrl — значение ‘alt’. Если был сделан обычный щелчок, то всем полям структуры Line присвоим пустые массивы, а если был сделан щелчок с удержанием Ctrl, то добавим в этой точке маркер, а координаты точки занесем в Line.X и Line.Y, после чего построим сплайн при помощи функции spline, удалим график предыдущего сплайна и построим график нового.

Иногда возможна ситуация, когда новая точка должна быть добавлена на существующей кривой. При щелчке по кривой событие ButtonDownFcn осей не возникает, поэтому после построения кривой в качестве обработки ее события ButtonDownFcn назначим ту же самую функцию BtnDown.

Ниже приведена функция plotcurve с подфункцией BtnDown.

function plotcurve

figure('Color', 'w') % создаем графическое окно

axes('XLim', [-1 1], 'YLim', [-1 1], 'Box', 'on', ...

'ButtonDownFcn', @BtnDown); % создаем оси

hold on

% заполняем структуру данных приложения

Line.X = []; % абсциссы точек

Line.Y = []; % ординаты точек

Line.h = []; % указатель на линию

guidata(gcf, Line) % сохраняем структуру данных

function BtnDown(src, eventdata)

% Подфункция обработки события щелчка по осям

% получаем координаты текущей точки

C = get(gca,'CurrentPoint');

x = C(1,1);

y = C(1,2);

% узнаем пределы осей

xlim = get(gca, 'XLim');

ylim = get(gca, 'YLim');

% проверяем, был ли щелчок в пределах осей

inaxes = xlim(1)< x & xlim(2) > x & ...

ylim(1)< y & ylim(2) > y;

if inaxes

% узнаем тип щелчка мышью

key = get(gcf, 'SelectionType');

if isequal(key, 'normal')

% обычный щелчок

% присваиваем всем полям структуры данных пустые массивы

Line = guidata(gcf);

Line.X = [];

Line.Y = [];

Line.h = [];

else

% добавляем координаты новой точки

Line = guidata(gcf);

Line.X = [Line.X x];

Line.Y = [Line.Y y];

% рисуем маркер

line(x, y, 'Marker','o', 'MarkerSize', 10,...

'MarkerFaceColor', 'c', 'MarkerEdgeColor', 'm');

% если точек больше одной, то строим сплайн

if length(Line.X) > 1

t = 1 : length(Line.X); % узлы сплайна

tt = 1: 0.1: t(end); % промежуточные точки для вычисления в них значения сплайна

sp = spline(t, [Line.X; Line.Y], tt);

% если есть линия, то удаляем ее

if ~isempty(Line.h)

delete(Line.h)

end

% рисуем новую линию

Line.h = plot(sp(1, :), sp(2, :), 'm');

set(Line.h, 'LineWidth', 2)

set(Line.h, 'ButtonDownFcn', @BtnDown)

end

end

% сохраняем структуру данных

guidata(gcf, Line)

end