【问题标题】:Move a rectangle using angles使用角度移动矩形
【发布时间】:2014-07-22 18:33:54
【问题描述】:

我需要使用角度移动一个矩形。实际上,当移动矩形到达我在 if 语句中给出的位置时,我想改变移动矩形的方向!

我只需要知道如何将矩形移动到 60、30、60、120、150、270 度的方法!

假设如果

          circle.Y>=this.Height-80

看到这个:

我真的需要使用角度来改变矩形移动的方向!这样在某个位置到达我可以根据自己选择的角度改变矩形方向! 这样:

if(circle.Y>=this.Height-80)
    move in the direction of 90 degrees

if(circle.X>=this.Width-80)
    move in the direction of 60 degree

如您在屏幕截图中所见!

我一直在尝试的是:

public partial class Form1 : Form
{
    Rectangle circle;
    double dx = 2;
    double dy = 2;

    public Form1()
    {
        InitializeComponent();
        circle = new Rectangle(10, 10, 40, 40);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Refresh();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.FillEllipse(new SolidBrush(Color.Red), circle);
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        circle.X += (int)dx;
        circle.Y += (int)dy;
        if (circle.Y>=this.Height-80)
        {
            dy = -Math.Acos(0) * dy/dy; //here i want to change the direction of circle at 90 degrees so that it should go up vertically straight with same speed
        }
        this.Refresh();
    }
}

问题是我一直在尝试将条件更改为:

dy = -Math.Asin(1) * dy;
dx = Math.Acos(0) * dx ;

但在这两种情况下都没有发生任何事情,方向保持不变! 我只想在圆达到

时以 90 度向上倒转移动圆
circle.Y>=this.Height-80

【问题讨论】:

  • 即使是作业,我们仍然会提供帮助。对我们而言,重要的是您在代码中付出的努力。
  • 答案将保持不变,亲爱的,请参阅 dx=dy=2;虽然 dx/dy=dy/dx=1;
  • @user3411946 - 不要添加额外的代码,这些代码一无所获,只会让我们感到困惑。 * dy/dy 显然没有任何目的。请更改代码以反映您实际想要实现的目标。或者用文字解释一下,我们可以告诉你应该怎么计算。
  • 是的,因为我的矩形改变了方向

标签: c# graphics angle drawrectangle


【解决方案1】:

您需要将矩形再次绘制到某个图像上才能显示。我使用您已经定义的circle-rectangle 创建了这段代码,用于在pictureBox1 上移动和绘制矩形:

移动矩形:

public void MoveRectangle(ref Rectangle rectangle, double angle, double distance)
{
   double angleRadians = (Math.PI * (angle) / 180.0);
   rectangle.X = (int)((double)rectangle.X - (Math.Cos(angleRadians) * distance));
   rectangle.Y = (int)((double)rectangle.Y - (Math.Sin(angleRadians) * distance));
}

绘制矩形并将其显示在PictureBox

public void DrawRectangle(Rectangle rectangle)
{
   Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
   using (Graphics g = Graphics.FromImage(bmp))
   {
      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
      g.FillEllipse(new SolidBrush(Color.Red), rectangle);
   }
   pictureBox1.Image = bmp;
}

点击按钮进行演示:

private void Button1_Click(object sender, EventArgs e)
{
   MoveRectangle(ref circle, 90, 5);
   DrawRectangle(circle);
}

【讨论】:

  • 好吧,我不需要整个代码,但我从您的回答赏金中得到了超级想法,谢谢!
【解决方案2】:

Math.Asin(1) * dy 是一个常数值。因此,您应该使用,例如,在您的计时器的每个 Tick 中递增的实例变量。

...和 ​​*dy/dy 无关。

public partial class Form1 : Form
{
    Rectangle circle;
    double dx = 2;
    double dy = 2;
    acum=0; //the new variable

...

private void timer_Tick(object sender, EventArgs e)
    {
        circle.X += (int)dx;
        circle.Y += (int)dy;
        if (circle.Y>=this.Height-300)
        {
            dy = -Math.Acos(acum); 
            acum+=1; //your accumulator
        }
        this.Refresh();
    }

【讨论】:

    【解决方案3】:

    acos 和 asin 是 sin 和 cos 的倒数,因此这两个函数的输出是一个角度(通常以弧度为单位)。这使得代码不正确。

    我强烈建议您阅读矢量和矩阵数学,因为使用欧拉角会变得非常混乱。

    所以,你将有一个位置向量 P 和一个运动向量 M 并且当前位置是:

     P' = P + M.t
    

    其中t是时间,P是原始位置,P'是当前位置。

    然后,当你想改变方向时,你创建一个旋转矩阵,并将运动向量 M 乘以这个旋转矩阵。

    这里的优点是,您可以通过向向量添加 Z 分量并增加矩阵的大小,从 2D 系统逐步过渡到 3D 系统。

    【讨论】:

    • 实际上,在您的示例中,不需要旋转矩阵,假设向上为 +ve y,则新的运动向量将为 (0,1)。
    • 那么我怎样才能真正做到这一点
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2019-01-12
    相关资源
    最近更新 更多