Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Rotate plot while dragging with the scroll button?

Subject: Rotate plot while dragging with the scroll button?

From: Pieter

Date: 18 Aug, 2012 21:52:09

Message: 1 of 8

Hi, I really hope it is possible to rotate a MATLAB plot while dragging with the scroll button. With this I mean the foillowing:

1.) Enable rotation mode on the mouse-down event (of the middie/scroll button)
2.) When moving around the mouse, with the scroll button still down/pressed, rotation should occur
3.) Disable rotation mode again on the mouse-up event

In short, I'm just trying the mimic the rotation behaviour of a general design/model application (CAD or Animation related).

The thing is that 1.) and 3.) are rather easy. But after 1.), moving the mouse around doesn't do anything (i.e. no rotation occurs). I assume that normally, another mouse-down event needs to occur after activating the rotation mode (the ordinary way would be by clicking the "rotate" button in the plot toolbar), before you can actually rotate.

Therefore I guess the question becomes, how to "fake" a mouse-down event, such that step 2.) follows directly after step 1.).... ?

The code for 1.) and 3.) is as follows:

% -----------------------------------------------------

function ScrollButtonRotation

clear all;
close all;
clc;

figure('WindowButtonDownFcn', @MouseDown);
axis

function MouseDown(~,~)
if strcmp(get(gcf,'SelectionType'), 'extend')
    disp('Enable Rotation Mode.')
    rotate3d
    
    hManager = uigetmodemanager(gcf);
    set(hManager.WindowListenerHandles,'Enable','off')
    
    set(gcf,'WindowButtonUpFcn',@MouseUp )
end

function MouseUp(~,~)
if strcmp(get(gcf,'SelectionType'), 'extend')
    disp('Disable Rotation Mode.')
    rotate3d
end

% -----------------------------------------------------

Save this as "ScrollButtonRotation.m" to test. In a previous topic I discussed a similar topic, how to enable/disable rotation mode with the keyboard: http://www.mathworks.com/matlabcentral/newsreader/view_thread/322438

Subject: Rotate plot while dragging with the scroll button?

From: Bruno Luong

Date: 19 Aug, 2012 08:06:05

Message: 2 of 8

I don't think you have any choice but hack the source code rotate3d.m

Bruno

Subject: Rotate plot while dragging with the scroll button?

From: Pieter

Date: 19 Aug, 2012 09:49:07

Message: 3 of 8

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <k0q6pd$brj$1@newscl01ah.mathworks.com>...
> I don't think you have any choice but hack the source code rotate3d.m
>
> Bruno

Yep I guess you're right. Hmm, setting the "WindowButtonMotionFcn" of the figure to the subfunction "localRotateOrbitMotionFcn" of rotate3d.m might do the trick (line 885 of rotate3d.m in my case).

However, to be able to access a subfunction from a function I'd need to do something like this: http://www.mathworks.nl/support/solutions/en/data/1-Y84NJ/index.html?product=SL&solution=1-Y84NJ

And furthermore, get the arguments for this function (i.e. rotaObj and evd) right. Any help is welcome, I'll let you know if I managed to come up with something.

Subject: Rotate plot while dragging with the scroll button?

From: matt dash

Date: 19 Aug, 2012 21:04:07

Message: 4 of 8

"Pieter" wrote in message <k0qcqj$qi$1@newscl01ah.mathworks.com>...
> "Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <k0q6pd$brj$1@newscl01ah.mathworks.com>...
> > I don't think you have any choice but hack the source code rotate3d.m
> >
> > Bruno
>
> Yep I guess you're right. Hmm, setting the "WindowButtonMotionFcn" of the figure to the subfunction "localRotateOrbitMotionFcn" of rotate3d.m might do the trick (line 885 of rotate3d.m in my case).
>
> However, to be able to access a subfunction from a function I'd need to do something like this: http://www.mathworks.nl/support/solutions/en/data/1-Y84NJ/index.html?product=SL&solution=1-Y84NJ
>
> And furthermore, get the arguments for this function (i.e. rotaObj and evd) right. Any help is welcome, I'll let you know if I managed to come up with something.

This is not that hard. You can rotate by just setting the view and it'll be MUCH faster than rotate3d. Here's an example:

function buttondownfcn(src,ev)
%src is the axes to be rotated

handles=guidata(src);
[az,el]=view(src);
cp=get(0,'PointerLocation');
set(handles.fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});
set(handles.fig,'windowbuttonupfcn',{@rotate_done});

function rotate_motion(src,ev,ax,cp,az,el)
newpt=get(0,'PointerLocation');

dy=newpt(2)-cp(2);
dx=newpt(1)-cp(1);

%factors of 3 control the conversion from mouse pixels to degrees. adjust for desired rotation speed.
newel=el-dy/3;
newaz=az-dx/3;

if newel<0;newel=0;end
if newel>90;newel=90;end

view(ax,newaz,newel)

function rotate_done(src,ev)
handles=guidata(src);
set(handles.fig,'windowbuttonmotionfcn',@ravedefaultwindowbuttonmotionfcn);
set(handles.fig,'windowbuttonupfcn',[]);

Subject: Rotate plot while dragging with the scroll button?

From: Pieter

Date: 19 Aug, 2012 22:08:06

Message: 5 of 8

"matt dash" wrote in message <k0rkc7$63o$1@newscl01ah.mathworks.com>...

> This is not that hard. You can rotate by just setting the view and it'll be MUCH faster than rotate3d. Here's an example:
>
> function buttondownfcn(src,ev)
> %src is the axes to be rotated
>
> handles=guidata(src);
> [az,el]=view(src);
> cp=get(0,'PointerLocation');
> set(handles.fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});
> set(handles.fig,'windowbuttonupfcn',{@rotate_done});
>
> function rotate_motion(src,ev,ax,cp,az,el)
> newpt=get(0,'PointerLocation');
>
> dy=newpt(2)-cp(2);
> dx=newpt(1)-cp(1);
>
> %factors of 3 control the conversion from mouse pixels to degrees. adjust for desired rotation speed.
> newel=el-dy/3;
> newaz=az-dx/3;
>
> if newel<0;newel=0;end
> if newel>90;newel=90;end
>
> view(ax,newaz,newel)
>
> function rotate_done(src,ev)
> handles=guidata(src);
> set(handles.fig,'windowbuttonmotionfcn',@ravedefaultwindowbuttonmotionfcn);
> set(handles.fig,'windowbuttonupfcn',[]);

% --------------------------------------------------------------------------------

Hi Matt, thanks for you input! But I'm not entirely sure how to use this code? I thought that assigning this new function as the callback function would work, i.e.

figure('WindowButtonDownFcn', @buttondownfcn)

Because the Source (src) and EventData (ev) are default arguments. But it doesn't (I get some errors about the view):

Single scalar argument must be 2 or 3
For this line: [az,el]=view(src);

It would be really helpful if you could provide some more details (or copy some ready-to-use code). Thanks!

Subject: Rotate plot while dragging with the scroll button?

From: dpb

Date: 19 Aug, 2012 22:48:43

Message: 6 of 8

On 8/19/2012 5:08 PM, Pieter wrote:
> "matt dash" wrote in message <k0rkc7$63o$1@newscl01ah.mathworks.com>...
>
>> This is not that hard. You can rotate by just setting the view and
>> it'll be MUCH faster than rotate3d. Here's an example:
>>
>> function buttondownfcn(src,ev)
>> %src is the axes to be rotated
>>
>> handles=guidata(src);
>> [az,el]=view(src);
>> cp=get(0,'PointerLocation');
>> set(handles.fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});
>> set(handles.fig,'windowbuttonupfcn',{@rotate_done});
>>
>> function rotate_motion(src,ev,ax,cp,az,el)
...

> Hi Matt, thanks for you input! But I'm not entirely sure how to use this
> code? I thought that assigning this new function as the callback
> function would work, i.e.
>
> figure('WindowButtonDownFcn', @buttondownfcn)
>
> Because the Source (src) and EventData (ev) are default arguments. But
> it doesn't (I get some errors about the view):
>
> Single scalar argument must be 2 or 3
> For this line: [az,el]=view(src);
...

I'm not sure, but it looks like overlooked an argument in the function
handle definition

set(handles.fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});

whereas the function definition is

function rotate_motion(src,ev,ax,cp,az,el)

I see where ev (I presume 'elent'?) is an argument in the

function buttondownfcn(src,ev)

so I'd try the following to make the function handle list match the
arguments in the function --

OOOhhh..., though I see there's also an 'ax' as well -- I presume that
must be an axis handle but not sure where it came from, either.

I was going to say use the following but I think it's lacking, too...

set(handles.fig,'windowbuttonmotionfcn', ...
            {@rotate_motion,src, ev, cp,az,el});

I've never done any gui stuff and my version predates fully-implemented
function handles so I can't test this out but that mismatch in argument
lists is a problem I'm pretty sure.

The full/correct fix(es) I'm unsure of but maybe that'll be something
you can figure out...

--

Subject: Rotate plot while dragging with the scroll button?

From: matt dash

Date: 19 Aug, 2012 23:35:06

Message: 7 of 8

dpb <none@non.net> wrote in message <k0rqgf$jq7$1@speranza.aioe.org>...
> On 8/19/2012 5:08 PM, Pieter wrote:
> > "matt dash" wrote in message <k0rkc7$63o$1@newscl01ah.mathworks.com>...
> >
> >> This is not that hard. You can rotate by just setting the view and
> >> it'll be MUCH faster than rotate3d. Here's an example:
> >>
> >> function buttondownfcn(src,ev)
> >> %src is the axes to be rotated
> >>
> >> handles=guidata(src);
> >> [az,el]=view(src);
> >> cp=get(0,'PointerLocation');
> >> set(handles.fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});
> >> set(handles.fig,'windowbuttonupfcn',{@rotate_done});
> >>
> >> function rotate_motion(src,ev,ax,cp,az,el)
> ...
>
> > Hi Matt, thanks for you input! But I'm not entirely sure how to use this
> > code? I thought that assigning this new function as the callback
> > function would work, i.e.
> >
> > figure('WindowButtonDownFcn', @buttondownfcn)
> >
> > Because the Source (src) and EventData (ev) are default arguments. But
> > it doesn't (I get some errors about the view):
> >
> > Single scalar argument must be 2 or 3
> > For this line: [az,el]=view(src);
> ...
>
> I'm not sure, but it looks like overlooked an argument in the function
> handle definition
>
> set(handles.fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});
>
> whereas the function definition is
>
> function rotate_motion(src,ev,ax,cp,az,el)
>
> I see where ev (I presume 'elent'?) is an argument in the
>
> function buttondownfcn(src,ev)
>
> so I'd try the following to make the function handle list match the
> arguments in the function --
>
> OOOhhh..., though I see there's also an 'ax' as well -- I presume that
> must be an axis handle but not sure where it came from, either.
>
> I was going to say use the following but I think it's lacking, too...
>
> set(handles.fig,'windowbuttonmotionfcn', ...
> {@rotate_motion,src, ev, cp,az,el});
>
> I've never done any gui stuff and my version predates fully-implemented
> function handles so I can't test this out but that mismatch in argument
> lists is a problem I'm pretty sure.
>
> The full/correct fix(es) I'm unsure of but maybe that'll be something
> you can figure out...
>
> --

Here's a fully working version. You set the buttondownfcn of the axes, not the figure. I'm not sure about how to get it to work with a middle click only but I think you already figured that part out...

function rotatedemo

figure
axes('buttondownfcn',@buttondownfcn)

line(rand(10),rand(10),rand(10),'hittest','off')
view(3)



function buttondownfcn(src,ev)
%src is the axes to be rotated
fig=ancestor(src,'figure');
handles=guidata(src);
[az,el]=view(src);
cp=get(0,'PointerLocation');
set(fig,'windowbuttonmotionfcn',{@rotate_motion,src,cp,az,el});
set(fig,'windowbuttonupfcn',{@rotate_done});

function rotate_motion(src,ev,ax,cp,az,el)
newpt=get(0,'PointerLocation');

dy=newpt(2)-cp(2);
dx=newpt(1)-cp(1);

%factors of 3 control the conversion from mouse pixels to degrees. adjust for desired rotation speed.
newel=el-dy/3;
newaz=az-dx/3;

if newel<0;newel=0;end
if newel>90;newel=90;end

view(ax,newaz,newel)

function rotate_done(src,ev)
fig=ancestor(src,'figure');
set(fig,'windowbuttonmotionfcn',[]);
set(fig,'windowbuttonupfcn',[]);

Subject: Rotate plot while dragging with the scroll button?

From: Pieter

Date: 20 Aug, 2012 16:14:09

Message: 8 of 8

Works great, thanks for your time and effort to post this solution!

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us