В этом примере показов, как создать интерактивный инструмент, который отображает угол между тремя вершинами в информацию только для чтения полилиний.
Можно изменить угол, щелкнув и перетащив вершины полилинии. Когда информация только для чтения перемещается, он транслирует событие с именем MovingROI. Путем добавления прослушивателя для этого события и функции обратного вызова, которая выполняет, когда событие происходит, инструмент может измерять и отображать изменения угла в реальном времени.
Чтение и отображение изображения.
im = imread('gantrycrane.png');
imshow(im)
Получите размер изображения.
[y,x,~] = size(im);
Получите координаты центра изображения. Пример помещает вершину инструмента измерения угла в центр изображения.
midy = ceil(y/2); midx = ceil(x/2);
Задайте координаты первой точки в информацию только для чтения полилиний. Этот пример помещает первую точку полилинии непосредственно над центром изображения.
firstx = midx; firsty = midy - ceil(y/4);
Задайте координаты третьей точки в информацию только для чтения полилиний. Этот пример помещает третью точку полилинии непосредственно справа от центра изображения.
lastx = midx + ceil(x/4); lasty = midy;
Создайте пустое контекстное меню, чтобы заменить меню по умолчанию.
c = uicontextmenu;
Нарисуйте полилинию красным цветом над изображением. Задайте координаты трех вершин и добавьте метку с инструкциями для взаимодействия с полилинией.
h = drawpolyline("Parent",gca, ... "Position",[firstx,firsty;midx,midy;lastx,lasty], ... "Label","Modify angle to begin...", ... "Color",[0.8,0.2,0.2], ... "UIContextMenu",c);
Добавьте прослушиватель, который слушает движение ROI. Когда прослушиватель обнаруживает движение, он вызывает пользовательскую функцию обратного вызова updateAngle
. Эта пользовательская функция определяется в разделе «Обновление метки угла с использованием функции обратного вызова».
addlistener(h,'MovingROI',@(src,evt) updateAngle(src,evt));
ROI полилиний также поддерживают интерактивное сложение и удаление вершин. Однако инструмент измерения угла требует ровно трех вершин в любой момент, поэтому сложение и удаление вершин являются нежелательными взаимодействиями с информация только для чтения. Добавляйте прослушиватели, которые слушают сложение или удаление вершин. При попытке изменить количество вершин соответствующий прослушиватель вызывает пользовательскую функцию обратного вызова, чтобы подавить изменение. Эти пользовательские функции, storePositionInUserData
и recallPositionInUserData
, определены в разделе «Предотвратить сложение или удаление вершин с помощью функций обратного вызова».
addlistener(h,'AddingVertex',@(src,evt) storePositionInUserData(src,evt)); addlistener(h,'VertexAdded',@(src,evt) recallPositionInUserData(src,evt)); addlistener(h,'DeletingVertex',@(src,evt) storePositionInUserData(src,evt)); addlistener(h,'VertexDeleted',@(src,evt) recallPositionInUserData(src,evt));
Задайте функцию обратного вызова, которая выполняется при перемещении полилинейного информация только для чтения. Эта функция извлекает текущее положение трех вершин, вычисляет угол в степенях между вершинами и обновляет метку, чтобы отобразить текущий угол поворота.
function updateAngle(src,evt) % Get the current position p = evt.CurrentPosition; % Find the angle v1 = [p(1,1)-p(2,1), p(1,2)-p(2,2)]; v2 = [p(3,1)-p(2,1), p(3,2)-p(2,2)]; theta = acos(dot(v1,v2)/(norm(v1)*norm(v2))); % Convert the angle to degrees angleDegrees = (theta * (180/pi)); % Update the label to display the angle src.Label = sprintf('(%1.0f) degrees',angleDegrees); end
Задайте функцию обратного вызова, которая выполняется, когда прослушиватели обнаруживают события 'AddiningVertex' или 'DeletingVertex'. Эти события происходят непосредственно перед добавлением или удалением интересующей вас вершины из полилинии. Сохраните текущие три вершины полилиний в UserData
свойство.
function storePositionInUserData(src,~) src.UserData = src.Position; end
Задайте функцию обратного вызова, которая выполняется, когда прослушиватели обнаруживают события 'VertexAdded' или 'VertexDeleted'. Эти события происходят сразу после добавления или удаления интересующей вершины из полилинии. Восстановите сохраненный набор из трех вершин полилиний в UserData
свойство.
function recallPositionInUserData(src,~) src.Position = src.UserData; end
addlistener
| drawpolyline
| Polyline