全局转换和本地转换

全局转换是适用于由给定 Graphics 对象绘制的所有项目的转换。 相比之下,局部转换是适用于要绘制的特定项的转换。

全球变革

若要创建全局转换,请构造 Graphics 对象,然后操作其 Transform 属性。 Transform 属性是一个 Matrix 对象,因此它可以保存任意序列的仿射转换。 存储在 Transform 属性中的转换称为世界转换。 Graphics 类提供了几种用于构建复合世界转换的方法:MultiplyTransformRotateTransformScaleTransformTranslateTransform。 以下示例将椭圆绘制两次:先是在创建世界变换之前绘制一次,然后再绘制一次。 转换首先在 y 方向上缩放 0.5 倍,然后在 x 方向上平移 50 个单位,然后旋转 30 度。

myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);
myGraphics.ScaleTransform(1, 0.5f);
myGraphics.TranslateTransform(50, 0, MatrixOrder.Append);
myGraphics.RotateTransform(30, MatrixOrder.Append);
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50)
myGraphics.ScaleTransform(1, 0.5F)
myGraphics.TranslateTransform(50, 0, MatrixOrder.Append)
myGraphics.RotateTransform(30, MatrixOrder.Append)
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50)

下图显示了转换中涉及的矩阵。

将缩放、平移和旋转矩阵组合,以形成全局转换的插图。

注释

在前面的示例中,椭圆围绕坐标系的原点旋转,该原点位于客户端区域的左上角。 这与围绕椭圆自身中心旋转所产生的结果不同。

局部转换

本地转换适用于要绘制的特定项。 例如,GraphicsPath 对象具有 Transform 方法,可用于转换该路径的数据点。 以下示例绘制一个没有转换的矩形,以及一个具有旋转转换的路径。 (假设没有世界转型。

Matrix myMatrix = new Matrix();
myMatrix.Rotate(45);
myGraphicsPath.Transform(myMatrix);
myGraphics.DrawRectangle(myPen, 10, 10, 100, 50);
myGraphics.DrawPath(myPen, myGraphicsPath);
Dim myMatrix As New Matrix()
myMatrix.Rotate(45)
myGraphicsPath.Transform(myMatrix)
myGraphics.DrawRectangle(myPen, 10, 10, 100, 50)
myGraphics.DrawPath(myPen, myGraphicsPath)

可以将世界转换与本地转换相结合,以实现各种结果。 例如,可以使用世界转换来修改坐标系,并使用本地转换来旋转和缩放在新坐标系上绘制的对象。

假设你想要一个坐标系,其原点距离工作区左边缘为 200 像素,距离工作区顶部为 150 像素。 此外,假设你希望度量单位是像素,x 轴指向右侧,y 轴指向上。 默认坐标系的 y 轴指向下,因此需要跨水平轴执行反射。 下图显示了此类反射的矩阵。

绕水平轴反射的矩阵的插图。

接下来,假设你需要向右平移 200 个单位,然后向下平移 150 个单位。

以下示例通过设置 Graphics 对象的世界转换来建立刚刚描述的坐标系。

Matrix myMatrix = new Matrix(1, 0, 0, -1, 0, 0);
myGraphics.Transform = myMatrix;
myGraphics.TranslateTransform(200, 150, MatrixOrder.Append);
Dim myMatrix As New Matrix(1, 0, 0, -1, 0, 0)
myGraphics.Transform = myMatrix
myGraphics.TranslateTransform(200, 150, MatrixOrder.Append)

以下代码(放置在前面的示例末尾)创建一个路径,该路径由一个矩形组成,该矩形的左下角位于新坐标系的原点。 矩形在没有局部转换的情况下填充一次,在有局部变换的情况下填充一次。 局部转换包括水平缩放 2 倍,然后旋转 30 度。

// Create the path.
GraphicsPath myGraphicsPath = new GraphicsPath();
Rectangle myRectangle = new Rectangle(0, 0, 60, 60);
myGraphicsPath.AddRectangle(myRectangle);

// Fill the path on the new coordinate system.
// No local transformation
myGraphics.FillPath(mySolidBrush1, myGraphicsPath);

// Set the local transformation of the GraphicsPath object.
Matrix myPathMatrix = new Matrix();
myPathMatrix.Scale(2, 1);
myPathMatrix.Rotate(30, MatrixOrder.Append);
myGraphicsPath.Transform(myPathMatrix);

// Fill the transformed path on the new coordinate system.
myGraphics.FillPath(mySolidBrush2, myGraphicsPath);
' Create the path.
Dim myGraphicsPath As New GraphicsPath()
Dim myRectangle As New Rectangle(0, 0, 60, 60)
myGraphicsPath.AddRectangle(myRectangle)

' Fill the path on the new coordinate system.
' No local transformation
myGraphics.FillPath(mySolidBrush1, myGraphicsPath)

' Set the local transformation of the GraphicsPath object.
Dim myPathMatrix As New Matrix()
myPathMatrix.Scale(2, 1)
myPathMatrix.Rotate(30, MatrixOrder.Append)
myGraphicsPath.Transform(myPathMatrix)

' Fill the transformed path on the new coordinate system.
myGraphics.FillPath(mySolidBrush2, myGraphicsPath)

下图显示了新的坐标系和两个矩形。

新坐标系与两个矩形的图示。

另请参阅