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工具里面,这里不做说明。

原文地址:https://www.cnblogs.com/lonelyxmas/p/9844533.html

时间: 2024-09-29 22:01:19

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

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

原文:WPF中使用TranslateTransform3D修改CAD的3D旋转中心 ?????? 前面一篇文章讲述了2D旋转功能的实现,文章提到了修改3D旋转中心,这一节主要总结一下具体的修改3D旋转中心的实现方法.(这个功能的实现有一段时间了,需要通过代码好好总结一下) ????? TranslateTransform3D以相对容器的偏移移动对象,通过OffsetX.OffsetY.OffsetZ属性来指定偏移量. ? (1)定义对象 ??????? private TranslateTran

在WPF中让ListBox和ComboBox的快速检索功能失效

问题来源: 自定义一个ComboBox,用来显示日期.后台数据使用的是DateTime,经过Converter转化成“2015年01月01日”样子的成字符串用于显示. 但是,在实际使用中,不停的按下“[”键,光标会从以一个元素一下一下的向下移动. 经过调查,这是ComboBox的“快速检索”功能在作祟. 关于快速检索: WPF中ListBox和ComboBox有一个“快速检索”的功能. 比如在ListBox里,按下“a”键,光标会定位到第一个首字母为“a”的Item上. ComboBox也是一样

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

1.在Login.xaml中添加资源: <XmlDataProvider x:Key="XmlDataProvider" Source="pack://application:,,,/5yue.PMS;Component/Config/SysConfig.xml" XPath="SysConfig"/> 2.使用ComboBox实现帐号输入: <ComboBox x:Name="UserName" Width

WPF中TreeView控件的使用案例

WPF总体来说还是比较方便的,其中变化最大的主要是Listview和Treeview控件,而且TreeView似乎在WPF是一个备受指责的控件,很多人说他不好用.我这个demo主要是在wpf中使用TreeView控件实现图片查看功能,简单的Grid布局.TreeView控件添加图标.TreeView控件的一些事件.显示统计.还有就是读取文件操作. 效果图: 前端主要代码: <Window x:Class="TreeViewDemo.MainWindow" xmlns="

WPF中的3D Wireframe

原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能.我已经在程序中实现并成功显示3D Wireframe,并能够进行3D Solid和3D Wireframe的切换. 我在熟悉这个类的基础上,自己定义了3D Wireframe xml文件的格式,用于保存3D Wireframe数据. 格式如下: <Wireframe>? <ScreenSpaceLines3D??? Form="Generic

WPF中的简单水动画

原文 https://stuff.seans.com/2008/08/21/simple-water-animation-in-wpf/ 很多年前(80年代中期),我在一家拥有Silicon Graphics工作站的公司工作.在旨在展示SGI机器高端图形的少数演示中,有一个模拟了一个小线框网格中的波传播.通过更改网格中的点的高度然后让模拟运行来玩游戏非常有趣.并且SGI机器足够快,结果动画只是令人着迷. 在WPF中重新创建这个水模拟似乎是一个很好的方式来学习WPF中的3D图形.(最终结果在这里)

WPF 中的 loaded 事件和 Initialized 事件

在 WPF 中, 控件有 Loaded 和 Initialized 两种事件. 初始化和加载控件几乎同时发生, 因此这两个事件也几乎同时触发. 但是他们之间有微妙且重要的区别. 这些区别很容易让人误解. 这里介绍我们设计这些事件的背景. (不仅适用于 Control 类, 同样在通用类如 FrameworkElement 和 FrameworkContentElement 类也适用.) 下面是个小故事: Initialized 事件只说: 这个元素已经被构建出来,并且它的属性值都被设置好了,所以

WPF中使用VisualBrush的实例

本文实现一个名为"你来我往"的小程序,该程序管理着"张三"和"李四"两位童鞋拥有的现金,一开始,两人均拥有100美元的现金,随着将现金从其中一人转移至另外一人,两人拥有的现金数在不断变化,程序可以跟踪这种变化,并正确显示每人拥有的现金数.每次最多可以转移三张纸币,纸币的金额可以是5美元.10美元或者20美元. 程序运行后的效果如图1所示,我们点击"张三"右边的"5美元""10美元"&qu

WPF中静态引用资源与动态引用资源的区别

WPF中静态引用资源与动态引用资源的区别 WPF中引用资源分为静态引用与动态引用,两者的区别在哪里呢?我们通过一个小的例子来理解. 点击“Update”按钮,第2个按钮的文字会变成“更上一层楼”,而第1个按钮的文字没有变化. 原因是第1个按钮文字用的是静态引用资源,而第2个按钮文字用的是动态引用资源. 前台代码: <Window x:Class="PersonalLearning.StaticDynamicResourceDemo"        xmlns="http