在Matlab中旋转贴片以面向相机

时间:2014-07-15 14:31:28

标签: matlab camera rotation geometry

这个简短的代码绘制了一个平面补丁(改编自Matlab的手册):

t = 0:pi/5:2*pi;
figure
x=sin(t); y=cos(t); z=ones(size(x));
patch(x,y,z,'y')
axis equal

这会产生一个面向相机的漂亮补丁:

enter image description here

但是,我想在已绘制的3D对象上绘制此贴片,并将相机设置在固定的任意视图上。我的问题是:如何旋转贴片的坐标,以便贴片面向相机并具有正确的卷筒?正确的解决方案将使补丁在任何给定的任意视图中看起来都相同(允许均匀缩放)。

我想相机的位置,目标和向上矢量都必须考虑在内,但我不清楚它是怎么做的。

1 个答案:

答案 0 :(得分:1)

很有趣,但今天我做的完全相同:)

我的方法如下

  1. 将相机放在X轴正半边的某处,并将相机目标设为(0,0,0)
  2. 以您需要的方式绘制对象
  3. 存储对象的X,Y和Z坐标
  4. 使用rotate3d功能以及ActionPreCallback
  5. ActionPostCallbackrotate3d mode object事件的回调制作
  6. 您还需要为WindowButtonMotionFcn'提供日常工作。活跃人物的事件
  7. 整个逻辑就像这样。 单击rotate3d图标或调用rotate3d函数后,单击轴上的左按钮开始旋转后,会触发ActionPreCallback事件。你必须在旋转开始时设置标志(下面的代码中为WeAreRotating)。然后在' WindowButtonMotionFcn'回调函数使用

    检索摄像机视图位置
    [az,el] = view(ah);
    

    功能并旋转您的对象。旋转很棘手,因为你必须将它的X,Y和Z坐标设置为你之前存储的原始坐标并将rotate函数应用于它。像这样:

    function fig_WindowButtonMotionFcn_callback(obj,evd)
    if getappdata(gca,'WeAreRotating')
        newView = round(get(gca,'View'));
        set( ObjectHandle, ...
            'XData',XData0, ...
            'YData',YData0, ...
            'ZData',ZData0 );
        rotate( ObjectHandle, [1 0 0],-newView(2), RotationOrigin );
        rotate( ObjectHandle, [0 0 1],+newView(1), RotationOrigin );
    end
    end  % if FogProps.SimpleWhenRotated
    

    释放鼠标按钮并完成旋转时会触发ActionPostCallback事件。在那里你必须清除旋转标记,因此移动鼠标不会改变对象,直到你再次开始旋转。

    很抱歉,如果我的解释有点不清楚。 正确排列所有旗帜有点棘手,特别是如果图上有几个轴。 实际上,在你的问题之后,我决定清理我的代码并将其发布到FEX,这样每个人都可以使用它,这样你就可以看到我是如何实现理想行为的。

    <强> UPDATE1

    有关完整示例,请参阅http://www.mathworks.com/matlabcentral/fileexchange/47275-fog3d