繁体   English   中英

多次使用 Matrix.Rotate C# Winforms

[英]Using Matrix.Rotate more than once C# Winforms

我一直在尝试解决我在旋转椭圆时遇到的问题。 我发布的代码有效,但它模仿了我必须真正使用的代码类型。 意思是,我不能使用 OnPaint 覆盖,而且我只能在主代码中做我能做的事情。 我正在向图形图层添加一个椭圆,我需要能够旋转、移动和调整椭圆的大小。 移动和调整大小工作完美无缺,但旋转不工作,因为我需要它。 如果您点击 9 点钟位置的小方框, 在此处输入图片说明

椭圆将按预期旋转: 在此处输入图片说明

所需的行为是能够点击 12 点钟位置的小框,并让椭圆再次旋转。 这不会发生。 为了让椭圆再次旋转,您需要单击原来的 9 点钟位置。 我真正想要找出的是如何获得 12 点钟位置的盒子坐标(或盒子旋转后最终的位置或位置),以便我可以再次旋转它。 到目前为止,我一直无法弄清楚。 请尝试理解,我正在使用写得不好的旧代码,我不允许对其进行太多更改。 我写的东西必须与已经存在的东西相结合。 下面是演示我在做什么的代码片段。 我知道我错过了一些明显的东西,只是不知道是什么。 谢谢。

 public partial class Form1 : Form
{
    int theAngle = 0;
    Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
    Pen pen3 = new Pen(Color.Green, 4);
    Pen smallPen = new Pen(Color.Black, 1);

    PointF center = new PointF(0, 0);
    Rectangle rectangle = new Rectangle(20, 20, 100, 30);
    Rectangle myRect2 = new Rectangle();
    bool mouseBtnDown = false;
    Graphics gw;

    public Form1()
    {
        InitializeComponent();
        this.MouseDown += mouseDown;
        gw = this.CreateGraphics();
    }

    private void mouseDown(object sender, MouseEventArgs e)
    {


        if (e.Button == MouseButtons.Left)
        {

            if (myRect2.Contains(e.Location))
                theAngle+=90;

            rotate();
        }

        if (e.Button == MouseButtons.Right)
        {
            //oval = false;
            //mouseBtnDown = false;
            theAngle = 0;
            rectangle.X = e.X - 50;
            rectangle.Y = e.Y - 15;
            rectangle.Width = 100;
            rectangle.Height = 30;
            center.X = rectangle.Left + (0.5f * rectangle.Width);
            center.Y = rectangle.Top + (0.5f * rectangle.Height);
            myRect2.Size = new Size(15, 15);
            myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
            drawstuff();
           // Invalidate();
        }

    } 

     public void rotate()
    {
        var matrix = new Matrix();

        matrix.RotateAt(theAngle, center);
        gw.Transform = matrix;
        drawstuff();
    }
    public void drawstuff()
    {


        gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
        gw.DrawEllipse(pen2, rectangle);

        gw.DrawRectangle(smallPen, myRect2);
    }
}

您可以使用Transform矩阵来旋转点。 所以我所做的是获取myRect2的 4 个角点,使用相同的Transform矩阵旋转它们,然后将它们分配给一个矩形。 然后您可以使用这个新矩形来检查位置。 我还在右键单击结束时更改了对drawstuff()的调用以调用rotate() ,这样旋转的矩形可以在第一次放置椭圆时更新,并且图形变换角度更新为 0。

public partial class Form1 : Form
{
  int theAngle = 0;
  Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
  Pen pen3 = new Pen(Color.Green, 4);
  Pen smallPen = new Pen(Color.Black, 1);

  PointF center = new PointF(0, 0);
  Rectangle rectangle = new Rectangle(20, 20, 100, 30);
  Rectangle myRect2 = new Rectangle();
  Rectangle rotatedRect2 = new Rectangle();
  bool mouseBtnDown = false;
  Graphics gw;

  public Form1()
  {
    InitializeComponent();
    this.MouseDown += mouseDown;
    gw = this.CreateGraphics();
  }


  private void mouseDown(object sender, MouseEventArgs e)
  {
    if (e.Button == MouseButtons.Left)
    {
      if (rotatedRect2.Contains(e.Location))
        theAngle += 90;

      rotate();
    }

    if (e.Button == MouseButtons.Right)
    {
      //oval = false;
      //mouseBtnDown = false;
      theAngle = 0;
      rectangle.X = e.X - 50;
      rectangle.Y = e.Y - 15;
      rectangle.Width = 100;
      rectangle.Height = 30;
      center.X = rectangle.Left + (0.5f * rectangle.Width);
      center.Y = rectangle.Top + (0.5f * rectangle.Height);
      myRect2.Size = new Size(15, 15);
      myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
      rotate();
      //drawstuff();
      // Invalidate();
    }
  }

  public void rotate()
  {
    var matrix = new Matrix();

    matrix.RotateAt(theAngle, center);
    gw.Transform = matrix;

    // Get the 4 corner points of myRect2.
    Point p1 = new Point(myRect2.X, myRect2.Y),
      p2 = new Point(myRect2.X + myRect2.Width, myRect2.Y),
      p3 = new Point(myRect2.X, myRect2.Y + myRect2.Height),
      p4 = new Point(myRect2.X + myRect2.Width, myRect2.Y + myRect2.Height);

    Point[] pts = new Point[] { p1, p2, p3, p4 };

    // Rotate the 4 points.
    gw.Transform.TransformPoints(pts);

    // Update rotatedRect2 with those rotated points.
    rotatedRect2.X = pts.Min(pt => pt.X);
    rotatedRect2.Y = pts.Min(pt => pt.Y);
    rotatedRect2.Width = pts.Max(pt => pt.X) - pts.Min(pt => pt.X);
    rotatedRect2.Height = pts.Max(pt => pt.Y) - pts.Min(pt => pt.Y);

    drawstuff();
  }

  public void drawstuff()
  {
    gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
    gw.DrawEllipse(pen2, rectangle);

    gw.DrawRectangle(smallPen, myRect2);
  }
}

有什么需要注意的。 像这样在屏幕上绘制(使用表单创建的图形并使用您自己的绘制函数绘制)意味着椭圆/矩形只绘制一次。 即如果你画了几个然后最小化你的形式,当你把它放回去时,椭圆就会消失。 不确定这是否是您所追求的。 解决此问题的一种方法是将椭圆绘制到位Bitmap ,然后在窗体的Paint事件中将此位图绘制到窗体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM