原文:WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能

      对于CAD图形来说,3D旋转比较常用,具体实现方法在上篇文章《WPF中3D旋转的实现 》中做了讲解,可以参考Daniel。

      今天说一下CAD的2D旋转,2D旋转虽然不如3D那么常用,但也是CAD操作的基本功能需要实现。刚开始的做法是觉得用AxisAngleRotation3D没法实现2D旋转,所以用RotateTransform去实现。但是用它遇到的问题是旋转的transform没有考虑在旋转矩阵里面,旋转矩阵是Daniel的3D Tool里面的代码,只考虑了3D的一些transform,说实话里面的矩阵转换一直没有看懂,根本就不可能进行修改的。就因为这个问题2D旋转一直放着没做。

      前几天CAD的基本操作实现差不多了,又回头看看CAD,仔细看了看《Rotating the Camera with the Mouse》中3D旋转的原理,突然恍然大悟,找到了2D旋转的方法,已经成功实现,就在这里整理一下。

 

原理:

       2D旋转是相对于当前屏幕的旋转,所以旋转轴是Z轴,旋转角度是鼠标点的变化角度。

 

代码:

 

(1)几个变量

        private Transform3DGroup _transform = new Transform3DGroup();
        private AxisAngleRotation3D _axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0, 1, 0), -5.0);
        private RotateTransform3D _rotateTransform3D = null;

 

        private Point3D _rotCenter3D = new Point3D(0.0, 0.0, 0.0);

        private Point _previousPosition2D = new Point(0.0, 0.0);

 

(2)相互关系,定义在构造函数里面

        _rotateTransform3D = new RotateTransform3D(_axisAngleRotation3D);
        _transform.Children.Add(_rotateTransform3D);

        _camera.Transform = _transform;

        这个transform是作用在camera上的。

 

(3)Move函数

        private void OnMouseMove(object sender, MouseEventArgs e)
        {

               Point currentPositonTrans = e.GetPosition(EventSource);

               Rotate2DCad(currentPositonTrans);

               _previousPosition2D = currentPositonTrans;
        }

 

(4)2D旋转CAD

        private void Rotate2DCad(Point newPosition)
        {

            //将旋转中心转换成2D坐标点。
            bool success = false;
            Point rotateCenterPt = Convert3DPointTo2D(_rotCenter3D, out success);
            if (success == false)
                rotateCenterPt = new Point();

 

            //计算旋转角度

            Double currentAngle = 0;
            Double angle1 = Math.Atan2(_previousPosition2D.Y - rotateCenterPt.Y, _previousPosition2D.X - rotateCenterPt.X);
            Double angle2 = Math.Atan2(newPosition.Y - rotateCenterPt.Y, newPosition.X - rotateCenterPt.X);

            if (newPosition.Y > 0 && _previousPosition2D.Y > 0)
            {
                currentAngle = (angle1 - angle2) * 180.0 / Math.PI;
            }
           
            Rotate2D(currentAngle);
        }

 

        private void Rotate2D(Double angle)
        {

            //应用新的旋转变换到当前的变换。
            Quaternion delta = new Quaternion(new Vector3D(0, 0, 1), -angle);
            Quaternion q = new Quaternion(_axisAngleRotation3D.Axis, _axisAngleRotation3D.Angle);

            q *= delta;

            Vector3D zeorVec = new Vector3D(0.0, 0.0, 0.0);
            if (Vector3D.Equals(q.Axis, zeorVec))
                return;

            _axisAngleRotation3D.Axis = q.Axis;
            _axisAngleRotation3D.Angle = q.Angle;
        }

 

注:

(1)旋转中心是CAD的原点,或者可以修改3D旋转中心(代码中的旋转中心为CAD原点(0,0,0))。

(2)Convert3DPointTo2D()函数是来自于3D Tools工具里面,这里不做说明。

WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能的更多相关文章

  1. WPF中使用TranslateTransform3D修改CAD的3D旋转中心

    原文:WPF中使用TranslateTransform3D修改CAD的3D旋转中心        前面一篇文章讲述了2D旋转功能的实现,文章提到了修改3D旋转中心,这一节主要总结一下具体的修改3D旋转 ...

  2. WPF中实现登陆窗口的“记住帐号”功能

    1.在Login.xaml中添加资源: <XmlDataProvider x:Key="XmlDataProvider" Source="pack://applic ...

  3. WPF中TreeView控件的使用案例

    WPF总体来说还是比较方便的,其中变化最大的主要是Listview和Treeview控件,而且TreeView似乎在WPF是一个备受指责的控件,很多人说他不好用.我这个demo主要是在wpf中使用Tr ...

  4. WPF中CAD control的XAML实现

    原文:WPF中CAD control的XAML实现     下面这个XAML文件是cad control里面最重要的一部分,使用Grid包含Viewport,Viewport中包括Camera和mod ...

  5. WPF中的3D特性和常见的几个类

    原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1.  Visual 类      所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...

  6. 在WPF中添加3D特性

    原文:在WPF中添加3D特性 35.4  在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...

  7. WPF中反转3D列表项

    原文:WPF中反转3D列表项 WPF中反转3D列表项                                                         周银辉记得在苹果电脑中有一个很酷的 ...

  8. WPF中的3D Wireframe

    原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能.我已经在程序中实现并成功显示3D Wireframe,并能够进 ...

  9. 3DMax模型输入到WPF中运行

    原文:3DMax模型输入到WPF中运行 其实看看笔者文章之前,可以在网上搜索下将3Dmax模型输入到WPF的办法,大部分结果都是这篇文章.这篇文章呢?有点麻烦,就是我们3Dmax模型转换到Blend的 ...

随机推荐

  1. Javascript学习之Window

    1.confirm:确认对话框. window.confirm("确定要删除吗?");//返回true或false if(window.confirm(“确定要删除吗?”)) { ...

  2. STL MAP取消排序

    class MyLess{public: bool operator()(const CString str1,const CString str2)const { return TRUE; }}; ...

  3. IWorkSpace与IWorkSpaceFactory与IWorkSpaceEdit

    樱木 原文 IWorkSpace与IWorkSpaceFactory与IWorkSpaceEdit 1.IWorkSpace是一个容器,里面存放着各种空间数据和非空间数据,比如Featureclass ...

  4. Lucene学习总结之七:Lucene搜索过程解析 2014-06-25 14:23 863人阅读 评论(1) 收藏

    一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...

  5. 嵌入式linux串口通信自发自收测试程序

     /*串口自收自发程序主函数*/#include"uart_api.h"int main(){ int fd; char buff[BUFFER_SIZE]; char buff2 ...

  6. JasperReport html 导出

    In my last blog post I discussed about Generating jasper reports in different formats using json fil ...

  7. 基于bootstrap的富文本框——wangEditor【欢迎增加开发】

    先来一张效果图: 01. 引言 老早就開始研究富文本框的东西,在写完<深入理解javascript原型与闭包>之后,就想着要去做一个富文本框的插件的样例. 如今网络上开源的富文本框插件许多 ...

  8. [CSS] Re-order the appearance of grid items using the order property

    As with flex items, we can set an order value on grid items. Let’s see how this affects the DOM and ...

  9. style.height、offsetHeight、clientHeight、scrollHeight的差别

    style.height 包含元素的滚动栏,不包含边框 clientHeight 不包含元素的滚动栏和边框 offsetHeight 包含元素的滚动栏和边框 scrollHeight offsetHe ...

  10. [Ramda] Get a List of Unique Values From Nested Arrays with Ramda (flatMap --> Chain)

    In this lesson, we'll grab arrays of values from other arrays, resulting in a nested array. From the ...