MATLAB: How to Take a Snapshot of a Camera after 3D Rotation
I recently ran into a problem while trying to rotate 3D objects. I am creating a GUI and I have a separate shape on which an object is drawn. In the figure, I am allowing the user to use the built-in MATLAB rotate button to move the object around. However, I cannot get the light to follow the turn, as it seems to be fixed to one part of the object. To create light, I use
c=camlight('right');
set(c,'style','infinite');
One solution I was thinking about is adding light when the user releases the rotate button, but that's not very nice. I also don't know how to use rotation callbacks when the button is on a separate shape.
Does anyone know how to make the light "track" the 3D rotation so that the current view is highlighted?
Thank!
source to share
Implement your own rotation functions
You can implement your own functionality to adjust axes and lights at the same time. Thus, the light is continuously adjusted as the axes rotate.
function follow_me_1
figure
axes('buttondownfcn', @buttondownfcn); % assign callback
set(gca,'NextPlot','add'); % add next plot to current axis
surf(peaks,'hittest','off'); % hittest -> off is important
view(3); % view to start from
c = camlight('headlight'); % add light
set(c,'style','infinite'); % set style of light
function buttondownfcn(ax,~)
fig = ancestor(ax,'figure'); % get figure handle
[oaz, oel] = view(ax); % get current azimuth and elevation
oloc = get(0,'PointerLocation'); % get starting point
set(fig,'windowbuttonmotionfcn',{@rotationcallback,ax,oloc,oaz,oel});
set(fig,'windowbuttonupfcn',{@donecallback});
end
function rotationcallback(~,~,ax,oloc,oaz,oel)
locend = get(0, 'PointerLocation'); % get mouse location
dx = locend(1) - oloc(1); % calculate difference x
dy = locend(2) - oloc(2); % calculate difference y
factor = 2; % correction mouse -> rotation
newaz = oaz-dx/factor; % calculate new azimuth
newel = oel-dy/factor; % calculate new elevation
view(ax,newaz,newel); % adjust view
c = camlight(c,'headlight'); % adjust light
end
function donecallback(src,~)
fig = ancestor(src,'figure'); % get figure handle
set(fig,'windowbuttonmotionfcn',[]); % unassign windowbuttonmotionfcn
set(fig,'windowbuttonupfcn',[]); % unassign windowbuttonupfcn
end
end
Using rotate3d
This example uses built-in rotate3d
and assigned callback functions. This is a "not-so-nice" solution, but it only takes a few lines of code.
function follow_me_2
surf(peaks); % Load demo data
c = camlight('headlight'); % Create light
set(c,'style','infinite'); % Set style
h = rotate3d; % Create rotate3d-handle
h.ActionPostCallback = @RotationCallback; % assign callback-function
h.Enable = 'on'; % no need to click the UI-button
% Sub function for callback
function RotationCallback(~,~)
c = camlight(c,'headlight');
end
end
source to share