原文: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. POJ 3624 Charm Bracelet 0-1背包

    传送门:http://poj.org/problem?id=3624 题目大意:XXX去珠宝店,她需要N件首饰,能带的首饰总重量不超过M,要求不超过M的情况下,使首饰的魔力值(D)最大. 0-1背包入 ...

  2. 【rlz01】完全数

    Time Limit: 3 second Memory Limit: 2 MB 问题描述 所谓完全数,就是这个数除了它本身的约数之和也等于这个数,比如说6的约数有1.2.3,而1+2+3=6,所以6是 ...

  3. hprof教程 分类: B1_JAVA 2015-03-02 12:18 444人阅读 评论(0) 收藏

    大部分内容参考http://www.linuxidc.com/Linux/2012-04/58178.htm J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profili ...

  4. Voronoi Diagram——维诺图

    Voronoi图定义   任意两点p 和q 之间的欧氏距离,记作 dist(p, q) .就平面情况而言,我们有           dist(p, q) =  (px-qx)2+ (py-qy)2 ...

  5. xmpp即时通讯协议的特性---长处和缺点!

    xmpp协议的定义? XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性. 因此.基于XMPP的应用具有超强的可扩展性.经过扩展以后的XMPP能够通过发送扩展的信 ...

  6. 日期和时间的格式化定义(ISO C89)

    格式化定义本质上控制的是占位. 日期 %Y:4位数的年份: %y:2位数的年份: %m:2位数的月份(1-12) %d:2位数的日(01-31) 时间 %H:24小时制(0-23) %I:12小时制( ...

  7. 【24.34%】【codeforces 560D】Equivalent Strings

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. [Flow] More tips about Flow

  9. IDEA 多线程Debug

    一.问题描述 在idea中的进行调试时,代码中有多线程,想对线程中的代码进行跟踪,代码如下: for (int i = 0; i < 5; i++) { final int index = i; ...

  10. Ubuntu安装编译OpenCV一键脚本(带ffmpeg)

    1.切换到用户文件夹 cd ~ 2.新建一个文件.命名为opencv.sh 脚本例如以下: version="$(wget -q -O - http://sourceforge.net/pr ...