0

我使用矩阵扩大了图形路径。我如何设置新路径正好在较小的路径上而不是在它的一侧?就像带有矩形的 Inflate。

4

2 回答 2

1

GraphicsPath 的核心是一些带有控制点的点,这些点指定如何混合这些点(当施加张力时)。当您将矩阵运算应用于图形路径时,它会根据您在矩阵中执行的运算更新所有这些点。

请记住,如果我正确理解了这个问题,您可以从获取图形路径的边界开始:

var graphicsBounds = myPath.GetBounds();

从那里您可以创建一个矩阵,将边界偏移到以 (0, 0) 为中心,缩放(将在 x/y 方向上缩放),然后偏移回屏幕上的原始位置。这应该在原始边界的中心对称地扩展路径。该矩阵代码看起来像:

Matrix myMatrix = new Matrix();

myMatrix.TranslateTransform(graphicsBounds.X + graphicsBounds.Width/2.0f, graphicsBounds.Y + graphicsBounds.Height/2.0f);
myMatrix.Scale(scaleX, scaleY);
myMatrix.TranslateTransform(-graphicsBounds.X - graphicsBounds.Width/2.0f, -graphicsBounds.Y - graphicsBounds.Height/2.0f);

也请记住 - 矩阵顺序(默认)反向应用。所以你应该从下到上阅读这些矩阵运算。这可能并不完全正确,但至少它应该有所帮助。祝你好运!

于 2013-12-07T19:40:37.940 回答
0

这就是我如何使用 Transform 将图形拟合到边界矩形中

在这种情况下,代码被放入pictureBox1 的Paint 事件中。将 GraphicsPath 中包含的图形边界和图片框边界发送给用户函数 GetMatrixFitRectInBounds() 会返回一个矩阵,以便在绘制之前将其应用于图片框的 Graphics.Transform 属性。

这说明了使用矩阵进行转换的一般思想:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    //GraphicsPath is a great to store for graphics if repainted frequently
    var myPath = new GraphicsPath();

    //Add simple ellipse
    myPath.AddEllipse(new Rectangle(0, 0, 50, 50));

    //Get transform to fit a rectange within a bounding rectange 
    var T = GetMatrixFitRectInBounds(myPath.GetBounds(), new RectangleF(pictureBox1.ClientRectangle.Location, pictureBox1.ClientRectangle.Size));

    //Apply transformation matrix
    e.Graphics.Transform = T;

    // Create a pen for the path
    Pen myPen = new Pen(Color.Black, 1);

    //Draw path to picturebox
    e.Graphics.DrawPath(myPen, myPath); 
}

-

//Return Matrix to scale a rectange within a rectangle
private Matrix GetMatrixFitRectInBounds(RectangleF fitrect, RectangleF boundsrect)
{
    var T = new Matrix();

    var bounds_center = new PointF(boundsrect.Width / 2, boundsrect.Height / 2);

    //Set translation centerpoint
    T.Translate(bounds_center.X, bounds_center.Y);

    //Get smallest size to scale to fit boundsrect
    float scale = Math.Min(boundsrect.Width / fitrect.Width, boundsrect.Height / fitrect.Height);

    T.Scale(scale, scale);

    //Move fitrect to center of boundsrect
    T.Translate(bounds_center.X - fitrect.X - fitrect.Width / 2f, bounds_center.Y - fitrect.Y - fitrect.Height / 2f);

    //Restore translation point
    T.Translate(-bounds_center.X, -bounds_center.Y);

    return T;

}

结果:

在此处输入图像描述

由于创建矩阵可能涉及大量计算,因此可以将其保留在绘图之外,并且仅在边界更改时才创建。GraphicPath(s) 也可以在 Paint 事件之外创建,并且仅在基础数据更改时更新。

于 2016-04-01T13:33:08.743 回答