MATLAB:如何使相机光线跟随 3D 旋转
MATLAB: How to make camera light follow 3D Rotation
我最近在尝试旋转 3D 对象时遇到了问题。我正在构建一个 GUI,我有一个单独的图形,其中绘制了一个对象。在图中,我允许用户使用 MATLAB 的内置旋转按钮来移动对象。但是,我无法让光线也跟随旋转,因为它似乎固定在物体的一部分上。为了创造光,我使用
c=camlight('right');
set(c,'style','infinite');
我想到的一种解决方案是在用户释放旋转按钮时添加光,但这不是很好。我也不知道当按钮在单独的图中时如何使用旋转回调。
有谁知道如何让灯光"track"进行3D旋转,从而照亮当前视野?
谢谢!
实现自己的旋转功能
您可以实现自己的功能来同时调整轴和灯光。这样,在旋转轴的同时不断调整光线。
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
使用rotate3d
此示例使用内置 rotate3d
和分配的回调函数。这是 'not very nice' 的解决方案,但只需要几行代码。
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
我最近在尝试旋转 3D 对象时遇到了问题。我正在构建一个 GUI,我有一个单独的图形,其中绘制了一个对象。在图中,我允许用户使用 MATLAB 的内置旋转按钮来移动对象。但是,我无法让光线也跟随旋转,因为它似乎固定在物体的一部分上。为了创造光,我使用
c=camlight('right');
set(c,'style','infinite');
我想到的一种解决方案是在用户释放旋转按钮时添加光,但这不是很好。我也不知道当按钮在单独的图中时如何使用旋转回调。
有谁知道如何让灯光"track"进行3D旋转,从而照亮当前视野?
谢谢!
实现自己的旋转功能
您可以实现自己的功能来同时调整轴和灯光。这样,在旋转轴的同时不断调整光线。
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
使用rotate3d
此示例使用内置 rotate3d
和分配的回调函数。这是 'not very nice' 的解决方案,但只需要几行代码。
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