WPF中使用AxisAngleRotation3D实现CAD的2D旋转功能
原文: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旋转功能的更多相关文章
- WPF中使用TranslateTransform3D修改CAD的3D旋转中心
原文:WPF中使用TranslateTransform3D修改CAD的3D旋转中心 前面一篇文章讲述了2D旋转功能的实现,文章提到了修改3D旋转中心,这一节主要总结一下具体的修改3D旋转 ...
- WPF中实现登陆窗口的“记住帐号”功能
1.在Login.xaml中添加资源: <XmlDataProvider x:Key="XmlDataProvider" Source="pack://applic ...
- WPF中TreeView控件的使用案例
WPF总体来说还是比较方便的,其中变化最大的主要是Listview和Treeview控件,而且TreeView似乎在WPF是一个备受指责的控件,很多人说他不好用.我这个demo主要是在wpf中使用Tr ...
- WPF中CAD control的XAML实现
原文:WPF中CAD control的XAML实现 下面这个XAML文件是cad control里面最重要的一部分,使用Grid包含Viewport,Viewport中包括Camera和mod ...
- WPF中的3D特性和常见的几个类
原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1. Visual 类 所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...
- 在WPF中添加3D特性
原文:在WPF中添加3D特性 35.4 在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...
- WPF中反转3D列表项
原文:WPF中反转3D列表项 WPF中反转3D列表项 周银辉记得在苹果电脑中有一个很酷的 ...
- WPF中的3D Wireframe
原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能.我已经在程序中实现并成功显示3D Wireframe,并能够进 ...
- 3DMax模型输入到WPF中运行
原文:3DMax模型输入到WPF中运行 其实看看笔者文章之前,可以在网上搜索下将3Dmax模型输入到WPF的办法,大部分结果都是这篇文章.这篇文章呢?有点麻烦,就是我们3Dmax模型转换到Blend的 ...
随机推荐
- Compmgmtlauncher.exe问题解决方法
修改注册表:HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\Manage\command 原来的默认键值为 ...
- swift学习第十四天:属性监听器
监听属性的改变 在OC中我们可以重写set方法来监听属性的改变 Swift中可以通过属性观察者来监听和响应属性值的变化 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为 ...
- 【u117】队列安排
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一个学校里老师要将班上N个同学排成一列,同学被编号为1-N,他采取如下的方法: 1. 先将1号同学安排 ...
- Windows Phone 8.1 FilePicker API
在 Windows Phone 8.1 中,增加了 FilePicker 的方式与文件打交道,最大的亮点在于这种方式不仅可以浏览手机上的文件,还可以浏览符合协议的应用里的文件! 比如点击 OneDri ...
- Session or Cookie?是否需要用Tomcat等Web容器的Session
Cookie是HTTP协议标准下的存储用户信息的工具,浏览器把用户信息存放到本地的文本文件中. Session是基于Cookie实现的. 2011年4月,武汉群硕面试的时候(实习生),面试官也问过这个 ...
- 小强的HTML5移动开发之路(48)——(小练习)新闻订阅系统【1】
一.总体设计 二.数据库设计 --新闻类别表 create table news_cate( news_cateid int primary key auto_increment, news_icon ...
- Django + Apache + wsgi配置和环境搭建(ubuntu)
上一篇写了Django + nginx + uwsgi配置和环境搭建(ubuntu) 由于公司服务器环境问题,又配置了apache的环境.记录例如以下: 一. 安装环境: #apache sudo a ...
- update中加入select最常用的update语法
update中加入select最常用的update语法 (转) (2010-08-20 11:40:16) 转载▼ 标签: it 分类: SQL 最常用的update语法是:UPDATE <ta ...
- 【u025】贝茜的晨练计划
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 奶牛们打算通过锻炼来培养自己的运动细胞,作为其中的一员,贝茜选择的运动方式是每天进行N(1 <= ...
- [TypeScript] Typescript Interfaces vs Aliases Union & Intersection Types
TypeScript has 'interface' and 'type', so when to use which? interface hasName { firstName: string; ...