【问题标题】:MATLAB: How to make camera light follow 3D RotationMATLAB:如何使相机光跟随 3D 旋转
【发布时间】:2015-09-04 10:12:03
【问题描述】:

我最近在尝试旋转 3D 对象时遇到了问题。我正在构建一个 GUI,并且我有一个单独的图形,其中绘制了一个对象。在图中,我允许用户使用 MATLAB 的内置旋转按钮来移动对象。但是,我无法让光线也跟随旋转,因为它似乎固定在物体的一部分上。为了创造光,我正在使用

c=camlight('right');
set(c,'style','infinite');

我想到的一个解决方案是在用户释放旋转按钮时添加光,但这不是很好。当按钮在单独的图中时,我也不知道如何使用旋转回调。

有谁知道如何让灯光“跟踪”3D 旋转,从而照亮当前视图?

谢谢!

【问题讨论】:

    标签: matlab user-interface 3d rotation lighting


    【解决方案1】:

    实现自己的轮播功能

    您可以实现自己的功能来同时调整轴和灯光。这样,在旋转轴的同时不断调整光线。

    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 和分配的回调函数。这是“不是很好”的解决方案,但只需要几行代码。

    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
    

    【讨论】:

    • 非常感谢!我会试试这些。我已经实现了类似于你昨晚提出的 rotate3d 解决方案的东西,但是照明变化有点草率。我将尝试您提出的第一个解决方案。
    • 不客气!我看到了您的另一篇文章,并认为您会尝试使用 rotate3d 的解决方案,因为您也想处理缩放。第一个解决方案也适用于缩放!您只需要编写一个自己的缩放功能,并使windowbuttonmotionfcn 的分配依赖于您的gui 中的控制元素。这样您就可以非常轻松地在缩放和旋转之间进行切换。
    • 我尝试了您的第一个解决方案,我比第二个更喜欢它。但是,我的问题是,当用户按下图形工具栏上的旋转按钮或缩放按钮时,我希望它能够工作。我尝试使用rotate3d,但它有点波涛汹涌并且不流畅。您是否知道是否有办法保留该按钮但改用您的实现?
    • 如果您使用实现 1,请确保您未处于 rotate3d 模式(例如,不要使用相机工具栏上的旋转相机按钮)
    猜你喜欢
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2016-06-08
    • 2015-01-08
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    相关资源
    最近更新 更多