Используйте полилинию для создания инструмента измерения угла

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

Можно изменить угол, щелкнув и перетащив вершины полилинии. Когда информация только для чтения перемещается, он транслирует событие с именем 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

См. также

| |

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте