This example shows the steps need to create a three-point measurement tool using a Polyline ROI
Display an image and a polyline at a right angle. We want to prompt the user to manipulate the polyline to measure angles of interest.
im = imread('gantrycrane.png'); % Display image in the axes imshow(im) % Get size of image m = size(im,1); n = size(im,2); % Get center point of image for initial positioning midy = ceil(m/2); midx = ceil(n/2); % Position first point vertically above the middle firstx = midx; firsty = midy - ceil(m/4); lastx = midx + ceil(n/4); lasty = midy; % Add empty context menu to replace default menu c = uicontextmenu; % Create a two-segment right-angle polyline centered in the image 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);
% Listen to event that fires as the ROI is being moved addlistener(h,'MovingROI',@(src,evt) updateAngle(src,evt)); % Intercept attempts to add or remove vertices 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));
As the user reshapes the polyline, we want to recompute the angle and update the label displayed.
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 it to degrees angleDegrees = (theta * (180/pi)); % Update the Label to display the angle src.Label = sprintf('(%1.0f) degrees',angleDegrees); end
The polyline allows users to add and remove vertices; however, an angle measurement tool assumes that there are only three vertices at any time. We want to add listeners to intercept when a user is attempting to add or remove a vertex. In the callback for the 'AddingVertex' and DeletingVertex' events, the vertex of interest has not yet been added or deleted. We will cached the current polyline position in the UserData property and restore it in the callback for the 'VertexAdded' and 'VertexDeleted' events. This will prevent the user from interactively adding or removing vertices for the polyline.
function storePositionInUserData(src,~) % Before a vertex is added/removed, store the Position in the UserData % property src.UserData = src.Position; end function recallPositionInUserData(src,~) % Restore the previous Position to prevent users from adding/removing % vertices src.Position = src.UserData; end
Polyline
| addlistener
| drawpolyline