이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Is it possible to create an interactive / editable 2D rectangle or polygon without additional toolboxes?
조회 수: 9 (최근 30일)
이전 댓글 표시
Sonomatic Australia
2013년 5월 29일
Hi all, I am trying to create a simple GUI which allows the user to draw shapes (rectanges / polygons) over an image. Drawing the shape is easy enough however I am battling to make them editable. From searching the net it appears that this is very easy to do if you have the image processing toolbox. I can't justify purchasing the whole toolbox just for this so I'm curious as to whether or not there is a simple alternative. I am not an advanced programmer but I am comfortable with callback function basics and keen to improve.
Perhaps there are some examples of this out there already?
Thank you, Tyron
채택된 답변
Image Analyst
2013년 5월 31일
You can use rbbox(). It's not in any toolbox - it's in base MATLAB. Since it doesn't have little handles to drag around and doesn't require clicks to finish and ask for confirmation, after the user draws the box you just ask them if it's okay or if they want to redraw it. This will do a rectangle. Or you can use dragrect().
There is nothing like impoly() that's in base MATLAB that I know of.
댓글 수: 1
Sonomatic Australia
2013년 5월 31일
Thank you for that Image Analyst. Practically your suggestion is fine and normally this would do the trick. However I would like to make the rectangle slightly more user friendly (drag and resize instead of redraw). It sounds fussy but we need to make our tools attractive to our technicians to get their buy in. I am happy to stick with rectangles now instead of polygons.
Here is my code again, I didn't post it correctly last time:
function InteractiveRectangle(x)
if nargin <1
x = 'start';
end
switch x
case 'start'
figure(1);
clf
axes('nextplot','replacechildren')
axis([0 5 0 5])
set(gca,'Units','Normalized') %or Pixels
set(gcf,'Units','Normalized') %or Pixels
%%Draw initial rectanlge
title('click and drag to draw rectangle')
set(gcf,'Pointer','crosshair')
k = waitforbuttonpress;
point1 = get(gca,'CurrentPoint'); % button down detected
finalRect = rbbox; % return figure units
point2 = get(gca,'CurrentPoint'); % button up detected
point1 = point1(1,1:2); % extract x and y
point2 = point2(1,1:2);
p1 = min(point1,point2); % calculate locations
offset = abs(point1-point2); % and dimensions
set(gcf,'Pointer','arrow')
x = round([p1(1) p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1)]);
y = round([p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2) p1(2)]);
%force line to be within axis limits (this should be moved to a separate
%function)
x_lims = get(gca, 'xlim');
y_lims = get(gca, 'ylim');
x(x<min(x_lims))=min(x_lims);
x(x>max(x_lims))=max(x_lims);
y(y<min(y_lims))=min(y_lims);
y(y>max(y_lims))=max(y_lims);
%Plot rectangle as rectangle object
% r1=rectangle('Position',rect,...
% 'LineWidth',1,...
% 'EdgeColor','red',...
% 'HandleVisibility','callback');
% Plot rectangle as line object
l1 = line(x,y);
set(l1,'Tag','Line1')
title('')
%%set(l1,'Buttondownfcn','drag2(''start'')') %Syntax for setting function in separate m file
%set(l1,'Buttondownfcn',{@drag2 ; 'start'}) %Syntax for setting function in the same m file
set(gcf,'WindowButtonMotionFcn',@wbmf)
% set(gca,'ButtonDownFcn','InteractiveRectangle(''gcf_bdf'')')
case 'gcf_bdf'
% disp('button pressed')
end
end
function in_bounds = getBounds(ax1, position)
% % Description : Return the bounds of the supplied axes and identify whether
% % supplied position is contained within axes bounds
x_lims = get(ax1, 'xlim');
y_lims = get(ax1, 'ylim');
in_bounds = (position(1,1) >= x_lims(1)) && ...
(position(1,1) <= x_lims(2)) && ...
(position(1,2) >= y_lims(1)) && ...
(position(1,2) <= y_lims(2));
end
function wbmf(src,evnt)
FP=get(src,'CurrentPoint');
pos1=get(gca,'Position');
% if FP(1) > pos1(1) & FP(1) < pos1(1)+pos1(3) & FP(2) > pos1(2) & FP(2) < pos1(2)+pos1(4) % cursor within axes
axlims=get(gca,'XLim');
aylims=get(gca,'YLim');
xscale=abs(diff(axlims))/pos1(3);
yscale=abs(diff(aylims))/pos1(4);
fp=[(FP(1)-pos1(1))*xscale , (FP(2)-pos1(2))*yscale];
l1 = findobj('tag','Line1');
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
[IN ON]=inpolygon(fp(1),fp(2),XData,YData);
if IN
set(gcf,'Pointer','fleur')
title('click and drag to move rectangle')
set(gca,'Buttondownfcn',{@drag1 ; 'start'}) %set windowbuttonmotionfnc to drag rectangle
else
set(gcf,'Pointer','arrow')
set(gca,'Buttondownfcn','')
end
%Cursor over vertices
if any(round(fp(1)*10)==round(XData*10)) & any(round(fp(2)*10)==round(YData*10))
set(l1,'Marker','o')
title('click and drag to resize rectangle')
set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner
%%Write code to distinguish rectangle corners
if round(fp(1)*10)==round(min(XData)*10) & round(fp(2)*10)==round(min(YData)*10)
set(gcf,'Pointer','botl')
set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner
elseif round(fp(1)*10)==round(max(XData)*10) & round(fp(2)*10)==round(max(YData)*10)
set(gcf,'Pointer','topr')
set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner
elseif round(fp(1)*10)==round(min(XData)*10) & round(fp(2)*10)==round(max(YData)*10)
set(gcf,'Pointer','topl')
set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner
elseif round(fp(1)*10)==round(max(XData)*10) & round(fp(2)*10)==round(min(YData)*10)
set(gcf,'Pointer','botr')
set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner
end
else
set(l1,'Marker','none')
end
%Cursor over edges (For rectangles not any polygon)
if round(fp(1)*10)==round(min(XData)*10) & fp(2) < max(YData) & fp(2) > min(YData)
set(gcf,'Pointer','left')
setappdata(gcf,'iedge',[1,2]);
set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side
elseif round(fp(1)*10)==round(max(XData)*10) & fp(2) < max(YData) & fp(2) > min(YData)
set(gcf,'Pointer','right')
setappdata(gcf,'iedge',[3,4]);
set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side
elseif round(fp(2)*10)==round(min(YData)*10) & fp(1) < max(XData) & fp(1) > min(XData)
set(gcf,'Pointer','bottom')
setappdata(gcf,'iedge',[1,4]);
set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side
elseif round(fp(2)*10)==round(max(YData)*10) & fp(1) < max(XData) & fp(1) > min(XData)
set(gcf,'Pointer','top')
setappdata(gcf,'iedge',[2,3]);
set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side
end
end
function drag1(src,evnt,action) % drag entire shape
switch(action)
case 'start',
set(gcf,'Pointer','hand')
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1);
Y = currPt(1,2);
%find closest vertex
[minxy ixy]=min(sqrt((X-XData).^2+(Y-YData).^2));
setappdata(gcbf,'ixy',ixy);
fixedoffset=[currPt(1,1)-XData(ixy),currPt(1,2)-YData(ixy)];
setappdata(gcbf,'fixedoffset',fixedoffset);
WBMF_0=get(gcbf,'WindowButtonMotionFcn');
setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag1 ; 'move'})
set(gcbf,'WindowButtonUpFcn',{@drag1 ; 'stop'})
case 'move'
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
ixy=getappdata(gcf,'ixy');
fixedoffset=getappdata(gcf,'fixedoffset');
XData=XData+(currPt(1,1)-XData(ixy)-fixedoffset(1));
YData=YData+(currPt(1,2)-YData(ixy)-fixedoffset(2));
set(l1,'Xdata',XData);
set(l1,'Ydata',YData);
case 'stop'
WBMF_0=getappdata(gcbf,'WBMF_0');
set(gcbf,'WindowButtonMotionFcn',WBMF_0)
set(gcbf,'WindowButtonUpFcn','')
set(gcf,'Pointer','fleur')
l1 = findobj('tag','Line1');
%Force line to be within axis limits
x = get(l1,'Xdata');
y = get(l1,'Ydata');
x_lims = get(gca, 'xlim');
y_lims = get(gca, 'ylim');
x(x<min(x_lims))=min(x_lims);
x(x>max(x_lims))=max(x_lims);
y(y<min(y_lims))=min(y_lims);
y(y>max(y_lims))=max(y_lims);
set(l1,'Xdata',x)
set(l1,'Ydata',y)
set(l1,'selected','off')
end
end
function drag2(src,evnt,action) % drag individual vertex
switch(action)
case 'start',
pntr=get(gcf,'Pointer');
setappdata(gcf,'pntr',pntr);
set(gcf,'Pointer','hand')
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1);
Y = currPt(1,2);
%find closest vertex
[minxy ixy]=min(sqrt((X-XData).^2+(Y-YData).^2));
setappdata(gcf,'ixy',ixy);
WBMF_0=get(gcbf,'WindowButtonMotionFcn');
setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag2 ; 'move'})
set(gcbf,'WindowButtonUpFcn',{@drag2 ; 'stop'})
case 'move' %moves closest vertex from original click
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1);
Y = currPt(1,2);
ixy=getappdata(gcf,'ixy');
XData(ixy)=X;
YData(ixy)=Y;
set(l1,'Xdata',XData)
set(l1,'Ydata',YData)
case 'stop'
WBMF_0=getappdata(gcbf,'WBMF_0');
set(gcbf,'WindowButtonMotionFcn',WBMF_0)
set(gcbf,'WindowButtonUpFcn','')
% pntr=getappdata(gcf,'pntr');
% set(gcf,'Pointer',pntr)
set(gcf,'Pointer','arrow')
l1 = findobj('tag','Line1');
%Force line to be within axis limits
x = get(l1,'Xdata');
y = get(l1,'Ydata');
x_lims = get(gca, 'xlim');
y_lims = get(gca, 'ylim');
x(x<min(x_lims))=min(x_lims);
x(x>max(x_lims))=max(x_lims);
y(y<min(y_lims))=min(y_lims);
y(y>max(y_lims))=max(y_lims);
set(l1,'Xdata',x)
set(l1,'Ydata',y)
set(l1,'selected','off')
end
end
function drag3(src,evnt,action) % drag rectangle corner
switch(action)
case 'start',
pntr=get(gcf,'Pointer');
setappdata(gcf,'pntr',pntr);
set(gcf,'Pointer','hand')
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1);
Y = currPt(1,2);
%find closest vertex
[minxy ixy]=min(sqrt((X-XData).^2+(Y-YData).^2));
setappdata(gcf,'ixy',ixy);
WBMF_0=get(gcbf,'WindowButtonMotionFcn');
setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag3 ; 'move'})
set(gcbf,'WindowButtonUpFcn',{@drag3 ; 'stop'})
case 'move' %moves closest vertex from original click
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1);
Y = currPt(1,2);
ixy=getappdata(gcf,'ixy');
if ixy==1 | ixy==5
XData([1,2,5])=X;
YData([1,4,5])=Y;
elseif ixy == 2
XData([1,2,5])=X;
YData([2,3])=Y;
elseif ixy == 3
XData([3,4])=X;
YData([2,3])=Y;
elseif ixy == 4
XData([3,4])=X;
YData([1,4,5])=Y;
end
set(l1,'Xdata',XData)
set(l1,'Ydata',YData)
case 'stop'
WBMF_0=getappdata(gcbf,'WBMF_0');
set(gcbf,'WindowButtonMotionFcn',WBMF_0)
set(gcbf,'WindowButtonUpFcn','')
% pntr=getappdata(gcf,'pntr');
% set(gcf,'Pointer',pntr)
set(gcf,'Pointer','arrow')
l1 = findobj('tag','Line1');
%Force line to be within axis limits
x = get(l1,'Xdata');
y = get(l1,'Ydata');
x_lims = get(gca, 'xlim');
y_lims = get(gca, 'ylim');
x(x<min(x_lims))=min(x_lims);
x(x>max(x_lims))=max(x_lims);
y(y<min(y_lims))=min(y_lims);
y(y>max(y_lims))=max(y_lims);
set(l1,'Xdata',x)
set(l1,'Ydata',y)
set(l1,'selected','off')
end
end
function drag4(src,evnt,action) % drag rectangle edges
switch(action)
case 'start',
pntr=get(gcf,'Pointer');
setappdata(gcf,'pntr',pntr);
set(gcf,'Pointer','hand')
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
%find closest edge
%This has actually been done already in "wbmf"
WBMF_0=get(gcbf,'WindowButtonMotionFcn');
setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag4 ; 'move'})
set(gcbf,'WindowButtonUpFcn',{@drag4 ; 'stop'})
case 'move' %moves closest vertex from original click
l1 = findobj('tag','Line1');
set(l1,'Selected','on')
XData = get(l1,'Xdata');
YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1);
Y = currPt(1,2);
% Retrieve edge
iedge=getappdata(gcf,'iedge');
if all(iedge == [1,2])
XData([1,2,5])=X;
elseif all(iedge == [2,3])
YData([2,3])=Y;
elseif all(iedge == [3,4])
XData([3,4])=X;
elseif all(iedge == [1,4])
YData([1,4,5])=Y;
end
set(l1,'Xdata',XData)
set(l1,'Ydata',YData)
case 'stop'
WBMF_0=getappdata(gcbf,'WBMF_0');
set(gcbf,'WindowButtonMotionFcn',WBMF_0)
set(gcbf,'WindowButtonUpFcn','')
% pntr=getappdata(gcf,'pntr');
% set(gcf,'Pointer',pntr)
set(gcf,'Pointer','arrow')
l1 = findobj('tag','Line1');
%Force line to be within axis limits
x = get(l1,'Xdata');
y = get(l1,'Ydata');
x_lims = get(gca, 'xlim');
y_lims = get(gca, 'ylim');
x(x<min(x_lims))=min(x_lims);
x(x>max(x_lims))=max(x_lims);
y(y<min(y_lims))=min(y_lims);
y(y>max(y_lims))=max(y_lims);
set(l1,'Xdata',x)
set(l1,'Ydata',y)
set(l1,'selected','off')
end
end
추가 답변 (1개)
Sonomatic Australia
2013년 5월 31일
I've managed to make a draggable, resize-able rectangle. This is far from perfect but it is a good start to what I need. I guess it's very "inefficient" coding but I'm not worried about that at this stage. Here is the code in case anybody finds it useful or in case anybody is willing to provide some advice for the proper way to go about this kind of programming.
function InteractiveRectangle(x) if nargin <1 x = 'start'; end
switch x case 'start' figure(1); clf axes('nextplot','replacechildren') axis([0 5 0 5]) set(gca,'Units','Normalized') %or Pixels set(gcf,'Units','Normalized') %or Pixels
%% Draw initial rectanlge title('click and drag to draw rectangle') set(gcf,'Pointer','crosshair') k = waitforbuttonpress; point1 = get(gca,'CurrentPoint'); % button down detected finalRect = rbbox; % return figure units point2 = get(gca,'CurrentPoint'); % button up detected point1 = point1(1,1:2); % extract x and y point2 = point2(1,1:2); p1 = min(point1,point2); % calculate locations offset = abs(point1-point2); % and dimensions set(gcf,'Pointer','arrow') x = round([p1(1) p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1)]) y = round([p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2) p1(2)])
%force line to be within axis limits (this should be moved to a separate %function) x_lims = get(gca, 'xlim'); y_lims = get(gca, 'ylim'); x(x<min(x_lims))=min(x_lims); x(x>max(x_lims))=max(x_lims); y(y<min(y_lims))=min(y_lims); y(y>max(y_lims))=max(y_lims);
%Plot rectangle as rectangle object % r1=rectangle('Position',rect,... % 'LineWidth',1,... % 'EdgeColor','red',... % 'HandleVisibility','callback');
% Plot rectangle as line object l1 = line(x,y); set(l1,'Tag','Line1') title('') %%set(l1,'Buttondownfcn','drag2(''start'')') %Syntax for setting function in separate m file %set(l1,'Buttondownfcn',{@drag2 ; 'start'}) %Syntax for setting function in the same m file set(gcf,'WindowButtonMotionFcn',@wbmf)
% set(gca,'ButtonDownFcn','InteractiveRectangle(''gcf_bdf'')') case 'gcf_bdf' % disp('button pressed') end end
function in_bounds = getBounds(ax1, position) % % Description : Return the bounds of the supplied axes and identify whether % % supplied position is contained within axes bounds x_lims = get(ax1, 'xlim'); y_lims = get(ax1, 'ylim');
in_bounds = (position(1,1) >= x_lims(1)) && ...
(position(1,1) <= x_lims(2)) && ...
(position(1,2) >= y_lims(1)) && ...
(position(1,2) <= y_lims(2));
end
function wbmf(src,evnt) FP=get(src,'CurrentPoint'); pos1=get(gca,'Position');
% if FP(1) > pos1(1) & FP(1) < pos1(1)+pos1(3) & FP(2) > pos1(2) & FP(2) < pos1(2)+pos1(4) % cursor within axes axlims=get(gca,'XLim'); aylims=get(gca,'YLim'); xscale=abs(diff(axlims))/pos1(3); yscale=abs(diff(aylims))/pos1(4); fp=[(FP(1)-pos1(1))*xscale , (FP(2)-pos1(2))*yscale];
l1 = findobj('tag','Line1'); XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
[IN ON]=inpolygon(fp(1),fp(2),XData,YData);
if IN set(gcf,'Pointer','fleur') title('click and drag to move rectangle') set(gca,'Buttondownfcn',{@drag1 ; 'start'}) %set windowbuttonmotionfnc to drag rectangle else set(gcf,'Pointer','arrow') set(gca,'Buttondownfcn','') end
%Cursor over vertices if any(round(fp(1)*10)==round(XData*10)) & any(round(fp(2)*10)==round(YData*10)) set(l1,'Marker','o') title('click and drag to resize rectangle') set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner %%Write code to distinguish rectangle corners if round(fp(1)*10)==round(min(XData)*10) & round(fp(2)*10)==round(min(YData)*10) set(gcf,'Pointer','botl') set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner elseif round(fp(1)*10)==round(max(XData)*10) & round(fp(2)*10)==round(max(YData)*10) set(gcf,'Pointer','topr') set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner elseif round(fp(1)*10)==round(min(XData)*10) & round(fp(2)*10)==round(max(YData)*10) set(gcf,'Pointer','topl') set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner elseif round(fp(1)*10)==round(max(XData)*10) & round(fp(2)*10)==round(min(YData)*10) set(gcf,'Pointer','botr') set(l1,'Buttondownfcn',{@drag3 ; 'start'}) %set windowbuttonmotionfnc to drag corner end
else set(l1,'Marker','none') end
%Cursor over edges (For rectangles not any polygon) if round(fp(1)*10)==round(min(XData)*10) & fp(2) < max(YData) & fp(2) > min(YData) set(gcf,'Pointer','left') setappdata(gcf,'iedge',[1,2]); set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side elseif round(fp(1)*10)==round(max(XData)*10) & fp(2) < max(YData) & fp(2) > min(YData) set(gcf,'Pointer','right') setappdata(gcf,'iedge',[3,4]); set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side elseif round(fp(2)*10)==round(min(YData)*10) & fp(1) < max(XData) & fp(1) > min(XData) set(gcf,'Pointer','bottom') setappdata(gcf,'iedge',[1,4]); set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side elseif round(fp(2)*10)==round(max(YData)*10) & fp(1) < max(XData) & fp(1) > min(XData) set(gcf,'Pointer','top') setappdata(gcf,'iedge',[2,3]); set(l1,'Buttondownfcn',{@drag4 ; 'start'}) %set windowbuttonmotionfnc to drag side end
end
function drag1(src,evnt,action) % drag entire shape switch(action) case 'start', set(gcf,'Pointer','hand') l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1); Y = currPt(1,2);
%find closest vertex [minxy ixy]=min(sqrt((X-XData).^2+(Y-YData).^2)); setappdata(gcbf,'ixy',ixy);
fixedoffset=[currPt(1,1)-XData(ixy),currPt(1,2)-YData(ixy)]; setappdata(gcbf,'fixedoffset',fixedoffset);
WBMF_0=get(gcbf,'WindowButtonMotionFcn'); setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag1 ; 'move'}) set(gcbf,'WindowButtonUpFcn',{@drag1 ; 'stop'})
case 'move' l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint'); ixy=getappdata(gcf,'ixy'); fixedoffset=getappdata(gcf,'fixedoffset');
XData=XData+(currPt(1,1)-XData(ixy)-fixedoffset(1)); YData=YData+(currPt(1,2)-YData(ixy)-fixedoffset(2));
set(l1,'Xdata',XData); set(l1,'Ydata',YData);
case 'stop' WBMF_0=getappdata(gcbf,'WBMF_0'); set(gcbf,'WindowButtonMotionFcn',WBMF_0) set(gcbf,'WindowButtonUpFcn','') set(gcf,'Pointer','fleur') l1 = findobj('tag','Line1'); %Force line to be within axis limits x = get(l1,'Xdata'); y = get(l1,'Ydata'); x_lims = get(gca, 'xlim'); y_lims = get(gca, 'ylim'); x(x<min(x_lims))=min(x_lims); x(x>max(x_lims))=max(x_lims); y(y<min(y_lims))=min(y_lims); y(y>max(y_lims))=max(y_lims); set(l1,'Xdata',x) set(l1,'Ydata',y) set(l1,'selected','off') end end
function drag2(src,evnt,action) % drag individual vertex switch(action) case 'start', pntr=get(gcf,'Pointer'); setappdata(gcf,'pntr',pntr); set(gcf,'Pointer','hand') l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1); Y = currPt(1,2);
%find closest vertex [minxy ixy]=min(sqrt((X-XData).^2+(Y-YData).^2)); setappdata(gcf,'ixy',ixy);
WBMF_0=get(gcbf,'WindowButtonMotionFcn'); setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag2 ; 'move'}) set(gcbf,'WindowButtonUpFcn',{@drag2 ; 'stop'})
case 'move' %moves closest vertex from original click l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint'); X = currPt(1,1); Y = currPt(1,2);
ixy=getappdata(gcf,'ixy');
XData(ixy)=X; YData(ixy)=Y;
set(l1,'Xdata',XData) set(l1,'Ydata',YData)
case 'stop' WBMF_0=getappdata(gcbf,'WBMF_0'); set(gcbf,'WindowButtonMotionFcn',WBMF_0) set(gcbf,'WindowButtonUpFcn','') % pntr=getappdata(gcf,'pntr'); % set(gcf,'Pointer',pntr) set(gcf,'Pointer','arrow') l1 = findobj('tag','Line1'); %Force line to be within axis limits x = get(l1,'Xdata'); y = get(l1,'Ydata'); x_lims = get(gca, 'xlim'); y_lims = get(gca, 'ylim'); x(x<min(x_lims))=min(x_lims); x(x>max(x_lims))=max(x_lims); y(y<min(y_lims))=min(y_lims); y(y>max(y_lims))=max(y_lims); set(l1,'Xdata',x) set(l1,'Ydata',y) set(l1,'selected','off') end end
function drag3(src,evnt,action) % drag rectangle corner switch(action) case 'start', pntr=get(gcf,'Pointer'); setappdata(gcf,'pntr',pntr); set(gcf,'Pointer','hand') l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint');
X = currPt(1,1); Y = currPt(1,2);
%find closest vertex [minxy ixy]=min(sqrt((X-XData).^2+(Y-YData).^2)); setappdata(gcf,'ixy',ixy);
WBMF_0=get(gcbf,'WindowButtonMotionFcn'); setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag3 ; 'move'}) set(gcbf,'WindowButtonUpFcn',{@drag3 ; 'stop'})
case 'move' %moves closest vertex from original click l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint'); X = currPt(1,1); Y = currPt(1,2);
ixy=getappdata(gcf,'ixy');
if ixy==1 | ixy==5 XData([1,2,5])=X; YData([1,4,5])=Y; elseif ixy == 2 XData([1,2,5])=X; YData([2,3])=Y; elseif ixy == 3 XData([3,4])=X; YData([2,3])=Y; elseif ixy == 4 XData([3,4])=X; YData([1,4,5])=Y; end
set(l1,'Xdata',XData) set(l1,'Ydata',YData)
case 'stop' WBMF_0=getappdata(gcbf,'WBMF_0'); set(gcbf,'WindowButtonMotionFcn',WBMF_0) set(gcbf,'WindowButtonUpFcn','') % pntr=getappdata(gcf,'pntr'); % set(gcf,'Pointer',pntr) set(gcf,'Pointer','arrow') l1 = findobj('tag','Line1'); %Force line to be within axis limits x = get(l1,'Xdata'); y = get(l1,'Ydata'); x_lims = get(gca, 'xlim'); y_lims = get(gca, 'ylim'); x(x<min(x_lims))=min(x_lims); x(x>max(x_lims))=max(x_lims); y(y<min(y_lims))=min(y_lims); y(y>max(y_lims))=max(y_lims); set(l1,'Xdata',x) set(l1,'Ydata',y) set(l1,'selected','off') end end
function drag4(src,evnt,action) % drag rectangle edges switch(action) case 'start', pntr=get(gcf,'Pointer'); setappdata(gcf,'pntr',pntr); set(gcf,'Pointer','hand') l1 = findobj('tag','Line1'); set(l1,'Selected','on') %find closest edge %This has actually been done already in "wbmf"
WBMF_0=get(gcbf,'WindowButtonMotionFcn'); setappdata(gcbf,'WBMF_0',WBMF_0)
set(gcbf,'WindowButtonMotionFcn',{@drag4 ; 'move'}) set(gcbf,'WindowButtonUpFcn',{@drag4 ; 'stop'})
case 'move' %moves closest vertex from original click l1 = findobj('tag','Line1'); set(l1,'Selected','on') XData = get(l1,'Xdata'); YData = get(l1,'Ydata');
currPt=get(gca,'CurrentPoint'); X = currPt(1,1); Y = currPt(1,2);
% Retrieve edge iedge=getappdata(gcf,'iedge');
if all(iedge == [1,2]) XData([1,2,5])=X; elseif all(iedge == [2,3]) YData([2,3])=Y; elseif all(iedge == [3,4]) XData([3,4])=X; elseif all(iedge == [1,4]) YData([1,4,5])=Y; end
set(l1,'Xdata',XData) set(l1,'Ydata',YData)
case 'stop' WBMF_0=getappdata(gcbf,'WBMF_0'); set(gcbf,'WindowButtonMotionFcn',WBMF_0) set(gcbf,'WindowButtonUpFcn','') % pntr=getappdata(gcf,'pntr'); % set(gcf,'Pointer',pntr) set(gcf,'Pointer','arrow') l1 = findobj('tag','Line1'); %Force line to be within axis limits x = get(l1,'Xdata'); y = get(l1,'Ydata'); x_lims = get(gca, 'xlim'); y_lims = get(gca, 'ylim'); x(x<min(x_lims))=min(x_lims); x(x>max(x_lims))=max(x_lims); y(y<min(y_lims))=min(y_lims); y(y>max(y_lims))=max(y_lims); set(l1,'Xdata',x) set(l1,'Ydata',y) set(l1,'selected','off') end end
Thank you, Tyron
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)
