变换概述

本主题讨论 Direct2D 转换的基础知识,并包括各种转换的示例。 它包含以下部分:

什么是 Direct2D 转换?

转换指定如何将对象的点从一个坐标空间映射到另一个坐标空间,或者从同一坐标空间中的一个位置映射到另一个位置。 此映射由转换矩阵描述,该矩阵定义为包含三行的集合,其中包含三列 FLOAT 值,如下表所示。

     
M11Default:1.0 M12Default:0.0 0.0
M21Default:0.0 M22Default:1.0 0.0
M31OffsetX:0.0 M32OffsetY:0.0 1.0

 

在此矩阵中,M11、M12、M21 和 M22 成员定义可缩放、旋转或倾斜对象的线性转换;OffsetX 和 OffsetY 成员定义在进行线性转换后要应用的转换。 对于仿射转换,第三列中的值始终为 0.0、0.0 和 1.0。

由于 Direct2D 仅支持仿射 (线性) 转换,因此其转换矩阵定义为 3 乘 2 矩阵,省略上一个转换矩阵中的第三列。 下表显示了 Direct2D 转换矩阵的布局。

   
M11Default:1.0 M12Default:0.0
M21Default:0.0 M22Default:1.0
M31OffsetX:0.0 M32OffsetY:0.0

 

在 Direct2D 中,此 3 乘 2 矩阵由 D2D1_MATRIX_3X2 结构表示。 为了简化常见的矩阵操作,Direct2D 还提供了一个名为 Matrix3x2F 的类,该类派生自 D2D1_MATRIX_3X2 结构。

Matrix3x2F 的默认构造函数使对象保持未初始化状态。 若要检索标识矩阵,请使用 Matrix3x2F::Identity

将标识转换应用于对象时,它不会更改对象的位置、形状或大小。 它类似于将数字乘以 1 不会更改数字的方式。 换句话说,标识转换只保留点的坐标,不会将点移动到新位置。 除标识转换以外的任何转换都将修改对象的位置、形状和/或大小。

转换与坐标有关,了解 Direct2D 坐标空间对于了解转换的使用非常重要。

Direct2D 坐标空间

Direct2D 使用左手坐标空间;也就是说,正 x 轴值向右增大,正 y 轴值向下增加。 屏幕上的所有内容都相对于原点定位,原点是 x 轴和 y 轴 (0,0) 相交的点,如下图所示。 Direct2D 呈现目标使用此坐标空间。

左手坐标空间的 x 轴和 y 轴图示

通过操作转换矩阵中的值,可以旋转、缩放、倾斜和移动 (转换) 对象。 例如,如果将 OffsetX 设置为 100,将 OffsetY 设置为 200,则会将对象向右移动 100 像素,向下移动 200 像素。

若要显示对象移动的效果,需要应用转换来呈现目标、画笔或几何图形。 将转换应用于呈现目标会影响整个屏幕,而将转换应用于画笔或几何图形只会影响该特定画笔或几何图形。 若要创建转换矩阵,请使用 Matrix3x2F 类。

创建转换矩阵

为了创建旋转、缩放、倾斜和平移转换, Matrix3x2F 类提供了下表所示的静态方法。 表的“示例”列包含指向操作方法主题的链接,这些主题演示如何使用每种转换方法。

方法 说明 示例 图示
matrix3x2f::rotate 创建具有指定角度和中心点的旋转转换。 如何旋转对象 围绕原始正方形中心顺时针旋转 45 度的正方形图示
matrix3x2f::scale 创建具有指定比例系数和中心点的缩放转换。 如何缩放对象 正方形比例为 130% 的插图
matrix3x2f::skew 创建具有指定的 x 轴和 y 轴值以及中心点的倾斜转换。 如何倾斜对象 从 y 轴逆时针方向倾斜 30 度的方形图示
matrix3x2f::translation 创建平移转换,并指定 x 轴和 y 轴方向的位移。 如何转换对象 正 x 轴上移动了 20 个单位,沿正 y 轴移动了 10 个单位

 

呈现目标转换

呈现器目标是继承自 ID2D1RenderTarget 接口的资源。 它创建用于绘图的资源并执行实际绘图操作。 它还提供转换坐标空间的方法。 可以调用 ID2D1RenderTarget::SetTransform 方法将指定的转换应用于呈现器目标。 所有后续的绘图操作都发生在转换后的空间中。

若要呈现内容,请使用呈现目标的绘图方法。 在开始绘制之前,请调用 BeginDraw 方法。 若要完成呈现内容,请调用 EndDraw 方法。 有关示例,请参阅 如何将多个转换应用于对象

画笔转换

可以通过调用 SetTransform 调整画笔上的转换。 对于此转换,可以将画笔视为一张大纸,将不同的呈现基元 (文本、几何图形、矩形等) 作为模具。 调整画笔转换时,就像在模具下方滑动大张纸一样,而不更改模具本身的位置。 可以使用此方法使文本从黄色淡入黑色进入 3D 空间。

当画笔转换是标识转换时,画笔显示在与绘制它们所在的呈现目标相同的坐标空间中。 画笔转换使调用方能够更改画笔坐标映射到此空间的方式。

在 Direct2D 中指定画笔空间的方式不同于Windows Presentation Foundation (WPF) 。 在 Direct2D 中,画笔空间不相对于要绘制的对象,而是呈现器目标的当前坐标系,如果存在,则由画笔转换转换。 若要像在 WPF 中那样让画笔填充对象,必须将画笔空间原点转换为对象的边界框的左上角,然后缩放画笔空间,使基磁贴填充对象的边界框。

有关画笔转换的详细信息,请参阅 Direct2D 画笔概述

几何图形转换

缩放、移动、平移或倾斜几何图形时,可以直接将转换应用于特定几何图形,而不是影响整个屏幕的呈现目标转换。 呈现目标转换通常影响几何图形的笔划和填充。 相比之下,几何图形转换仅影响几何图形的填充,因为该转换在笔划之前应用于几何图形。

注意

从Windows 8开始,如果将笔划类型设置为D2D1_STROKE_TRANSFORM_TYPE_FIXED或D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE,世界转换不会影响笔划。

 

可以通过调用 ID2D1Factory::CreateTransformedGeometry 来创建 ID2D1TransformedGeometry 对象来调整几何图形上的转换。 有关几何图形转换的详细信息,请参阅 Direct2D 几何图形概述

呈现目标转换如何影响剪辑

呈现器目标上的转换会影响轴对齐剪辑的边界框的计算方式。 调用 PushAxisAlignedClip 时, clipRect 参数由在呈现器目标上设置的当前世界转换进行转换。 将转换应用到 clipRect 后,将计算 clipRect 的轴对齐边界框。 为了提高效率,内容将剪裁到此轴对齐的边界框,而不是传递到传入的原始 clipRect 。 下图显示了旋转转换如何应用于呈现器目标、生成的 clipRect 和计算轴对齐边界框。

  1. 假设下图中的矩形是与屏幕像素对齐的呈现目标。

    呈现目标)  (矩形的插图

  2. 将旋转转换应用于呈现器目标。 在下图中,黑色矩形表示原始呈现目标,红色虚线矩形表示转换后的呈现目标。

    原始矩形和旋转矩形的插图 (转换的呈现目标)

  3. 调用 PushAxisAlignedClip 后,旋转转换将应用于 clipRect。 在下图中,蓝色矩形表示转换后的 clipRect

    旋转矩形 (转换的呈现目标) 内 (一个较小的蓝色矩形)

  4. 计算轴对齐边界框。 在下图中,绿色虚线矩形表示边界框。 所有内容都剪裁到此轴对齐的边界框。

    蓝色小矩形上绿色边框的插图 (剪贴)

总结

借助 Direct2D,可以使用简化的坐标空间和相关类轻松转换二维对象。 通过使用各种类型的转换,可以平移、旋转、倾斜和缩放对象,以实现许多令人印象深刻的视觉效果。

Direct2D 参考