我使用矩阵扩大了图形路径。我如何设置新路径正好在较小的路径上而不是在它的一侧?就像带有矩形的 Inflate。
2 回答
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);
也请记住 - 矩阵顺序(默认)反向应用。所以你应该从下到上阅读这些矩阵运算。这可能并不完全正确,但至少它应该有所帮助。祝你好运!
这就是我如何使用 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 事件之外创建,并且仅在基础数据更改时更新。