本主题描述如何向 Windows Presentation Foundation (WPF) 图形系统中的三维模型应用变换开发人员可以借助于变换功能来对模型进行重定位调整大小和重定向而无需更改用来定义模型的基值 三维坐标空间 Windows Presentation Foundation (WPF) 中的三维图形内容封装在 ViewportD 元素中该元素可以参与二维元素结构该图形系统将 ViewportD 视为一个像 Windows Presentation Foundation (WPF) 中的许多其他元素一样的二维可视化元素ViewportD 充当三维场景中的一个窗口(视区)更准确地说它是三维场景所投影到的图面 尽管可以将 ViewportD 与其他二维绘图对象用在同一个场景关系图中但是不能在 ViewportD 中渗透二维和三维对象以下讨论中所描述的坐标空间包含在 ViewportD 元素中 二维图形的 Windows Presentation Foundation (WPF) 坐标系将原点定位在呈现图面(通常是屏幕)的左上角在二维系统中x 轴上的正值朝右增加y 轴上的正值朝下增加但是在三维坐标系中原点位于屏幕的中心x 轴上的正值朝右增加但是 y 轴上的正值朝上增加z 轴上的正值从原点向外朝向观察者增加 坐标系比较 由这些轴定义的空间是三维对象在 Windows Presentation Foundation (WPF) 中的固定参考框架当您在该空间中生成模型并创建光源和照相机以查看这些模型时一定要在向每个模型应用变换时将固定参考框架或全局空间与您为该模型创建的局部参考框架区分开另请记住根据光源和照相机设置全局空间中的对象可能会看上去完全不同或者根本不可见但是照相机的位置不会改变对象在全局空间中的位置 变换模型 当您创建模型时它们在场景中具有特定的位置为了在场景中移动旋转这些模型或者更改这些模型的大小而更改用来定义模型本身的顶点是不切实际的相反正如在二维对象中一样您可以向模型应用变换 每个模型对象都有一个可用来对模型进行移动重定向或调整大小的 Transform 属性当您应用变换时实际上是按照由变换功能指定的向量或值(以适用者为准)来偏移模型的所有点换言之您已经变换了在其中定义模型的坐标空间(模型空间)但是您尚未更改在整个场景的坐标系(全局空间)中构成模型几何形状的值 平移变换 三维变换继承自抽象基类 TransformD这些变换包括仿射变换类 TranslateTransformDScaleTransformD 和 RotateTransformDWindows Presentation Foundation (WPF) 三维系统还提供一个 MatrixTransformD 类使用该类可以用更简明的矩阵操作来指定同样的变换 TranslateTransformD 沿着您用 OffsetXOffsetY 和 OffsetZ 属性指定的偏移向量所指示的方向来移动 ModelD 中的所有点例如假设立方体的一个顶点位于 ()则偏移向量 () 会将该顶点 () 移到 ()该立方体的顶点在模型空间中仍位于 ()但是现在该模型空间与世界空间的关系已经发生改变因此模型空间中的 () 是世界空间中的 () 带有偏移的平移 下面的代码示例演示如何应用平移 缩放变换 ScaleTransformD 沿着指定的缩放向量相对于中心点来更改模型的比例可以指定等比缩放即在 XY 和 Z 轴上将模型缩放同样的值来按比例更改模型的大小例如将该变换的 ScaleXScaleY 和 ScaleZ 属性设置为 会将此模型二等分将这些属性设置为 会将此模型在所有这三个轴上的值放大一倍 ScaleVector 示例 通过指定非等比变换(XY 和 Z 值不相等的缩放变换)可以使模型在一个或两个维度上拉伸或收缩而不会影响其他维度例如如果将 ScaleXScaleY 和 ScaleZ 分别设置为 和 则将导致变换模型的高度增加一倍但是 X 和 Z 轴上的值仍保持不变 默认情况下ScaleTransformD 会导致顶点围绕原点 () 拉伸或收缩但是如果要变换的模型不是从原点绘制的那么在从原点缩放模型时模型将不会就地缩放相反当模型的顶点与缩放向量相乘时缩放操作对模型的平移和缩放都会产生影响 缩放中心示例 若要就地缩放模型请通过设置 ScaleTransformD 的 CenterXCenterY 和 CenterZ 属性来指定模型的中心这可确保图形系统缩放模型空间然后平移该空间使其在指定的 PointD 上居中相反如果模型是围绕原点生成的而且您指定了一个不同的中心点则将看到模型会背离原点平移 旋转变换 可以通过几种不同的方法来旋转三维模型典型的旋转变换指定一个轴以及围绕该轴的旋转角度使用 RotateTransformD 类可以用 Rotation 属性来定义 RotationD然后可以在 RotationD(在本例中为 AxisAngleRotationD)上指定 Axis 和 Angle 属性来定义变换下面的几个示例围绕 Y 轴将模型旋转 度 注意Windows Presentation Foundation (WPF) 三维是一个右手系统这意味着如果旋转角度为正数则将围绕该轴逆时针旋转 对于指定了轴和角度的旋转来说如果没有为 RotateTransformD 上的 CenterXCenterY 和 CenterZ 属性指定值则假设围绕原点旋转与缩放时一样一定要记住旋转时会变换模型的整个坐标空间如果模型不是围绕原点创建的或者它以前经过平移则旋转可能会围绕原点转动而不是就地旋转 在指定了新中心的情况下旋转 若要就地旋转模型请将模型的实际中心指定为旋转中心由于几何形状通常是围绕原点建模的因此在依次执行下列操作时通常将获取一组预期的变换结果调整模型大小(缩放该模型) 然后设置模型方向(旋转该模型)最后将模型移到所需的位置(平移该模型) 旋转示例 指定了轴和角度的旋转非常适于静态变换和某些动画但是请考虑围绕 X 轴将立方体模型旋转 度然后围绕 Z 轴将其旋转 度您可以将这种变换描述为两个离散的仿射变换也可以将其描述为一个矩阵但是对于按照这种方式定义的旋转可能很难平滑地进行动画处理尽管按照这两种方法计算的模型起始位置和结束位置相同但是从计算的角度来看该模型经过的中间位置是不确定的四元数提供了一种用来在旋转的起始位置和结束位置之间计算内插值的替代方法 四元数表示三维空间中的一个轴以及围绕该轴的旋转例如四元数可以表示 () 轴以及 度的旋转角度四元数在定义旋转方面的价值在于可以针对它们执行的两个运算合成和内插应用于一个几何形状的两个四元数的合成是指围绕 axis 将几何形状旋转 rotation 度然后围绕 axis 将其旋转 rotation 度通过使用合成运算可以将应用于几何形状的两个旋转合成在一起以便获得一个代表合成结果的四元数由于四元数内插可以计算出从一个轴和方向到另一个轴和方向的平滑而又合理的路径因此您可以从原始位置到合成的四元数之间进行内插以便实现从一个位置到另一个位置的平滑过渡从而可以对该变换进行动画处理对于要进行动画处理的模型可以通过针对 Rotation 属性使用 QuaternionRotationD 来为旋转指定目标 Quaternion 使用变换集合 在生成场景时通常会向模型应用多个变换向 TransformDGroup 类的 Children 集合中添加变换从而方便地将多个变换组合在一起以应用于场景中的各种模型通常可以很方便地在几个不同的组中重用某个变换这与通过向每个实例应用一组不同的变换来重用模型大体相同请注意将变换添加到该集合中的顺序至关重要集合中的变换是按照从第一个到最后一个的顺序应用的 对变换进行动画处理 Windows Presentation Foundation (WPF) 三维实现与二维图形参与同一个计时和动画系统换言之若要对三维场景进行动画处理需要对其模型的属性进行动画处理可以直接对基元的属性进行动画处理但是通常很容易对用来更改模型位置或外观的变换进行动画处理由于可以向 ModelDGroup 对象及其各个模型应用变换因此可以向 ModelDGroup 的子级应用一组动画向一组对象应用另一组动画 若要对 Windows Presentation Foundation (WPF) 中的对象进行动画处理可以创建时间线定义动画(实际上是随着时间的推移而更改某个属性值)并指定要向其应用动画的属性此属性必须是 FrameworkElement 的属性由于三维场景中的所有对象都是 ViewportD 的子级因此要应用于场景的任何动画所面向的属性都是 ViewportD 属性的属性一定要仔细设计动画的属性路径因为语法可能会极为冗长 假设您希望就地旋转某个对象而且还希望应用摆动动作以公开要查看的对象的更多内容您可以选择向模型应用 RotateTransformD并对模型从一个向量旋转到另一个向量时所围绕的轴进行动画处理下面的代码示例演示如何将 VectorDAnimation 应用于该变换的 RotationD 的 Axis 属性并假设 RotateTransformD 是应用于具有 TransformGroup 的模型的几个变换之一 使用类似的语法可以将其他变换属性作为目标来移动或缩放该对象 例如可以在进行缩放变换时将 PointDAnimation 应用于 ScaleCenter 属性以便使模型的形状平滑地扭曲 尽管上面的几个示例对 GeometryModelD 的属性进行变换但是还可以对场景中其他模型的属性进行变换 例如可以通过对应用于 Light 对象的平移进行动画处理来创建移动灯光和阴影效果 这些效果可以显着改变模型的外观 由于照相机也是模型因此也可以对照相机的属性进行变换 尽管您确实可以通过改变照相机的位置或平面距离来改变场景的外观(实际上是变换整个场景的投影)但应注意对于观察者来说以这种方法实现的许多效果不如将变换应用于场景中模型的地点或位置更有视觉意义 |