2013-12-07 105 views
0

我使用矩陣放大了圖形路徑。我怎麼能設定新的路徑恰好在較小的路徑上,而不在它的旁邊?像長方形的充氣。矩陣和圖形路徑

回答

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); 

還記得 - 矩陣順序(默認)應用於相反。所以你應該從下到上閱讀這些矩陣操作。這可能不完全正確,但至少應該有所幫助。祝你好運!

0

這我如何使用變換

在這種情況下,代碼放在pictureBox1的Paint事件適合圖形成boundning rectange。發送包含在GraphicsPath中的圖形的邊界並將界限映射到用戶函數GetMatrixFitRectInBounds()的矩陣返回,以在繪製之前應用於picturebox的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; 

} 

結果:

enter image description here

由於有可能大量的計算涉及在創建矩陣時,它可能是kep t在繪畫之外並且僅在邊界改變時創建。 GraphicPath也可以在Paint事件之外創建,並且只有在底層數據發生變化時纔會更新。

+0

注意縮放也會縮放線寬。爲了保持原始筆的寬度,可以在繪製縮放的圖形之前通過反比例縮放筆寬來取消它,如下所示:'Pen myPen = new Pen(Color.Blue,linewidth/scale)'。 – flodis