如何在C#中旋转二维对象

How to rotate 2d object in C#

基本上我有一个 windows 表单,用户可以绘制不同的形状(例如正方形、圆形和三角形),用户可以在绘制后突出显示这些形状中的任何一个,然后控制突出显示的形状通过移动或旋转它来塑造形状,我不知道如何旋转形状。任何人都可以提供帮助,这是我的代码(只画一个正方形) PS:用户需要在表单上单击两次以绘制这两个点之间的形状,如下所示我也知道我应该使用 onPaint 方法,但这是任务的要求

谢谢

public Square(Point keyPt, Point oppPt)   // constructor
    {
        this.keyPt = keyPt;
        this.oppPt = oppPt;
    }

    // You will need a different draw method for each kind of shape. Note the square is drawn
    // from first principles. All other shapes should similarly be drawn from first principles. 
    // Ideally no C# standard library class or method should be used to create, draw or transform a shape
    // and instead should utilse user-developed code.
    public void draw(Graphics g, Pen blackPen)
    {
        // This method draws the square by calculating the positions of the other 2 corners
        double xDiff, yDiff, xMid, yMid;   // range and mid points of x & y  

        // calculate ranges and mid points
        xDiff = oppPt.X - keyPt.X;
        yDiff = oppPt.Y - keyPt.Y;
        xMid = (oppPt.X + keyPt.X) / 2;
        yMid = (oppPt.Y + keyPt.Y) / 2;

        // draw square
        g.DrawLine(blackPen, (int)keyPt.X, (int)keyPt.Y, (int)(xMid + yDiff / 2), (int)(yMid - xDiff / 2));
        g.DrawLine(blackPen, (int)(xMid + yDiff / 2), (int)(yMid - xDiff / 2), (int)oppPt.X, (int)oppPt.Y);
        g.DrawLine(blackPen, (int)oppPt.X, (int)oppPt.Y, (int)(xMid - yDiff / 2), (int)(yMid + xDiff / 2));
        g.DrawLine(blackPen, (int)(xMid - yDiff / 2), (int)(yMid + xDiff / 2), (int)keyPt.X, (int)keyPt.Y);
    }

    public void fillSquare(Graphics g, Brush redBrush)
    {
        float xDiff = oppPt.X - keyPt.X;
        float yDiff = oppPt.Y - keyPt.Y;
        float xMid = (oppPt.X + keyPt.X) / 2;
        float yMid = (oppPt.Y + keyPt.Y) / 2;

        var path = new GraphicsPath();
        path.AddLines(new PointF[] {
        keyPt,
        new PointF(xMid + yDiff/2, yMid-xDiff/2),
        oppPt
        });

        path.AddLines(new PointF[] {
        keyPt,
        new PointF(xMid - yDiff/2, yMid + xDiff/2),
        oppPt
        });

        path.CloseFigure();

        // Fill Triangle
        g.FillPath(redBrush, path);

    }
}

}

我已经尝试过这个方法但是缺少一些东西我不知道它是什么

private void itemRotation(PaintEventArgs e)
    {
        Pen blackpen = new Pen(Color.Black);
        Graphics g = e.Graphics;
        Font myFont = new System.Drawing.Font("Helvetica", 9);
        Brush blackwriter = new SolidBrush(System.Drawing.Color.Black);


        if (rotateItem)
        {
            for (int i = 0; i < shapes.Count; i++)
            {
                if (shapes[i].Selected)
                {
                    if (shapes[i].ShapeType == (int)ShapeTypes.Square)
                    {
                        PointF center = new PointF(shapes[i].keyPt.X + (shapes[i].oppPt.X / 2.0F), shapes[i].keyPt.Y + (shapes[i].oppPt.Y / 2.0F));
                        shapes[i].keyPt = new Point(shapes[i].keyPt.X, shapes[i].keyPt.Y);
                        shapes[i].oppPt = new Point(shapes[i].oppPt.X, shapes[i].oppPt.Y);
                        Matrix myMatrix = new Matrix();
                        myMatrix.Rotate(30);
                        g.Transform = myMatrix;
                        ((Square)shapes[i]).draw(g, blackpen);
                        g.DrawString("2nd pos", myFont, blackwriter, shapes[i].keyPt.X, shapes[i].oppPt.X);
                    }
                }
            }
        }
    }

下面是如何将相同形状 (a GraphicsPath) 绘制到不同位置和旋转的示例。

这里的关键是下面两条命令

e.Graphics.TranslateTransform(x, y);
e.Graphics.RotateTransform(-angle);

查看以下结果:

以及用于生成它的代码:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    // This code defines a graphics shape using a GraphicsPath
    // and draws multiple copies along a grid and with various
    // rotation angle angles.
    e.Graphics.SmoothingMode=SmoothingMode.AntiAlias;
    var target = sender as PictureBox;

    // Step 1 - Define a rectangle 20 by 12 pixels, center at origin.
    var gp = new GraphicsPath();
    gp.AddLines(new PointF[] {
        new PointF(-10, -6),
        new PointF( 10, -6),
        new PointF( 10,  6),
        new PointF(-10,  6) });
    gp.CloseFigure();

    // Step 2 - Define a 10×9 grid with two loops
    float angle = 0;
    for (int i = 0; i<9; i++)
    {
        // divide the control height into 10 divisions
        float y = (i+1)*target.Height/10;
        for (int j = 0; j<10; j++)
        {
            // divide the control width into 11 divisions
            float x = (j+1)*target.Width/11;
            // Save the default transformation state
            var state = e.Graphics.Save();

            // Traslate the origin to (x,y), each grid point
            e.Graphics.TranslateTransform(x, y);
            // Rotate shape by an angle (negative = CCW)
            e.Graphics.RotateTransform(-angle);

            // Draw the shape
            e.Graphics.FillPath(Brushes.LightSeaGreen, gp);
            e.Graphics.DrawPath(Pens.Black, gp);

            // Restore the default transformation state
            e.Graphics.Restore(state);

            // Increment the angle by one degree. 
            // The idea is to show all 90 degrees of rotation in a 10×9 grid.
            angle++;
        }
    }
}