【问题标题】:Moving rectangle is not moving according to coordinates given移动矩形没有根据给定的坐标移动
【发布时间】:2013-03-09 20:40:13
【问题描述】:

我有一个以图片为背景的图片框(实际上是一张地图),我在其上生成矩形。这些矩形应该移动给定的点。矩形以指定的速度移动,在到达(或接近)其中一个点后,它开始移动到下一个点。然而我的问题是,矩形并没有直接移动到给定点,它只是继续接近其中一个坐标,所以在某些情况下,矩形的 Y 坐标和点的 Y 坐标是一样,但矩形是 60 像素,不会移动。 下面我添加一张图片作为运动的例子。蓝色是预期路线,红色是实际路线。我已经检查了一百次坐标,它们是正确的,矩形只是在其他地方移动。注意:这只发生在某些地方。

这是我用来计算矩形相对于 X 轴和 Y 轴的移动的代码。

public void Move_calculate(Graphics g)
    {
        if (points[passed].X == 0 || points[passed].Y == 0) // this happens when the rectangle reaches it final point - it stays where it is (working fine)
        {
            Redraw(g);
            return;
        }
        speed = randomNumbers.Next(7, 13);
        if (points[passed].X > x_coordinate && points[passed].Y > y_coordinate)
        {
            Bx = points[passed].X;
            By = points[passed].Y;
            distanceForAlfaX = Bx - x_coordinate; // x_coordinate is the x coordinate of the rectangle
            distanceForAlfaY = By - y_coordinate;
            if (distanceForAlfaX <= 20 || distanceForAlfaY <= 20) speed = 5; // slowing down when approaching the point
            if (distanceForAlfaX + distanceForAlfaY <= 15) passed += 1;
            alpha = (distanceForAlfaY / distanceForAlfaX); // tangent alpha
            x_change = (int)(speed * (Math.Cos(alpha))); // get distance moved relative to axis X
            y_change = (int)Math.Sqrt(((speed * speed) + (x_change * x_change))); // again distance for axis Y, using Pythagoras theorem
            x_coordinate += x_change;
            y_coordinate += y_change;
        }
        else if (points[passed].X > x_coordinate && points[passed].Y < y_coordinate)
        {
            Bx = points[passed].X;
            By = points[passed].Y;
            distanceForAlfaX = Bx - x_coordinate;
            distanceForAlfaY = y_coordinate - By;
            if (distanceForAlfaX <= 20 || distanceForAlfaY <= 20) speed = 5;
            if (distanceForAlfaX + distanceForAlfaY <= 15) passed += 1;
            alpha = (distanceForAlfaY / distanceForAlfaX);
            x_change = (int)(speed * (Math.Cos(alpha)));
            y_change = (int)Math.Sqrt(((speed * speed) + (x_change * x_change)));
            x_coordinate += x_change;
            y_coordinate -= y_change;
        }
        else if (points[passed].X < x_coordinate && points[passed].Y > y_coordinate)
        {
            Bx = points[passed].X;
            By = points[passed].Y;
            distanceForAlfaX = x_coordinate - Bx;
            distanceForAlfaY = By - y_coordinate;
            if (distanceForAlfaX <= 20 || distanceForAlfaY <= 20) speed = 5;
            if (distanceForAlfaX+distanceForAlfaY <= 15) passed += 1;
            alpha = (distanceForAlfaY / distanceForAlfaX);
            x_change = (int)(speed * (Math.Cos(alpha)));
            y_change = (int)Math.Sqrt(((speed * speed) + (x_change * x_change)));
            x_coordinate -= x_change;
            y_coordinate += y_change;
        }
        else if (points[passed].X < x_coordinate && points[passed].Y < y_coordinate)
        {
            Bx = points[passed].X;
            By = points[passed].Y;
            distanceForAlfaX = x_coordinate - Bx;
            distanceForAlfaY = y_coordinate - By;
            if (distanceForAlfaX <= 20 || distanceForAlfaY <= 20) speed = 5;
            if (distanceForAlfaX + distanceForAlfaY <= 15) passed += 1;
            alpha = (distanceForAlfaY / distanceForAlfaX);
            x_change = (int)(speed * (Math.Cos(alpha)));
            y_change = (int)Math.Sqrt(((speed * speed) + (x_change * x_change)));
            x_coordinate -= x_change;
            y_coordinate -= y_change;
        }
        else
        {
            MessageBox.Show("Something went wrong"); // just notify me that it isnt working again..
        }
        Pen p = new Pen(Color.Turquoise, 2);
        r = new Rectangle(x_coordinate, y_coordinate, 5, 5); // redraw the rectangle
        g.DrawRectangle(p, r);
        p.Dispose();
    }

我不知道为什么会发生这种情况,有人可以帮忙吗? 附言 运动绝对不需要平滑,矩形的位置将使用定时器每两秒更新一次。现在它暂时设置为一个按钮。

编辑: 这是foreach代码。标签只是图片框旁边显示的坐标

                     foreach (aircraft acft in aircrafts) // aircraft is an array aircrafts[]
                {
                        label2.Text = "xp" + acft.points[acft.passed].X;
                        label3.Text = "yp" + acft.points[acft.passed].Y;
                        label4.Text = acft.passed.ToString();
                        label5.Text = "y" + acft.y_coordinate.ToString();
                        //MessageBox.Show(acft.points[0].X.ToString());
                        acft.Move_calculate(e.Graphics);
                        spawn = string.Empty;
                    }

EDIT2:aircraft 类中的所有变量

        public string callsign;
    public int speed;
    public double heading;
    public bool moving = false;
    public Point[] points;
    public double alpha;
    public int x_change;
    public int y_change;
    public int x_coordinate;
    public int y_coordinate;
    public int Bx;
    public int By;
    public double distanceForAlfaX;
    public double distanceForAlfaY;
    public int passed = 0;
    public Rectangle r;

【问题讨论】:

  • 要检查坐标,在 PictureBox 旁边我还显示当前坐标、经过的点和下一个点的坐标。当矩形像到达终点时,它通常完全在其他地方。如果需要,我可以分享整个代码,现在大约 300 行长。
  • 这个方法是循环调用还是什么?一旦到达某个点/点,还有什么会触发点移动..?看起来你缺少一些相关的代码..
  • 这个方法是从 PictureBox1.Paint 在 foreach 循环中调用的(对于每个矩形)。点击按钮后触发PictureBox1.Paint(按钮使PictureBox失效)
  • 您应该显示 foreach 循环代码,这将有助于查看您在该循环中所做的事情。我还注意到您是Unregistering Events with the x_coordinate -= x_change;` ...等等其中一个可能会导致问题..
  • 'if' 块中有大量不必要的代码重复。考虑重构它以删除重复,您将更有可能找到您的错误并避免未来的错误。

标签: c# winforms


【解决方案1】:

我猜,有一个数学错误

y_change = (int)Math.Sqrt(((speed * speed) + (x_change * x_change)));

此外...

// again distance for axis Y, using Pythagoras theorem

让毕达哥拉斯先生成为,我宁愿用和X轴一样

y_change = (int)(speed * (Math.Sin(alpha)));

【讨论】:

    【解决方案2】:

    你检查过你的坐标系吗? (https://web.archive.org/web/20140710074441/http://bobpowell.net/coordinatesystems.aspx)

    抱歉,您的问题的链接错误。尝试使用 Control.PointToClient 进行调试,以确保所有坐标都在客户端空间中表示。 (https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.pointtoclient)

    你可以试试:

        Point cPoint = this.PointToClient(new Point(x_coordinate, y_coordinate));
        Size cSize = new Size(5,5);
        r = new Rectangle(cPoint, cSize); // redraw the rectangle
        g.DrawRectangle(p, r);
    

    您能否发布变量的数据类型以澄清您的代码?您可能会在某处丢失精度,尤其是在使用整数除法时。

    (DJ KRAZE 的注意事项,a -= b;在 C# 中也可以表示 a = a - b;上下文很重要。)

    【讨论】:

    • PointToClient 不存在,我需要包含什么?至于数据类型,aircraft类中的所有变量:`public string callsign;公共 int 速度;公共双标题;公共布尔移动=假;公共点[]点;公开双 alpha;公共 int x_change;公共 int y_change;公共 int x_coordinate;公共 int y_coordinate;公共诠释 Bx;公共 int 由; public double distanceForAlfaX; public double distanceForAlfaY;公共 int 通过 = 0;公共矩形 r;`
    • 休,这种格式很糟糕。将其添加到问题本身.. 为了精确 - 我正在将某些东西转换为 int,所以它当然不会完全精确,但不是这么多
    • PointToClient 是一个 Control 方法,因此它应该出现在您的表单中。有关详细信息,请参阅msdn.microsoft.com/en-us/library/…。对不起,我没有尽快回复你,很高兴看到你得到你的答复。如果您一再丢失信息,累积错误真的会让人失望。例如,10/3 的整数除法 = 3。和 (float)(10/3) = 3.0,但是 ((float)10)/((float)3) 给出了预期的结果,尽管仍然有一些微小的损失精度。
    猜你喜欢
    • 2013-03-21
    • 2016-06-19
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多