调试一个简单的碰撞处理器

3
我的碰撞处理方法是将速度向量分成两个分量:法向量和切向量,切向量垂直于法向量。法向量平行于连接两个物体中心的线。
然后我将速度分量的法向量分量转换为动量。
动量 = 速度 * 质量。
然后我将A物体的动量传递给B,B再传递给A。
接下来,根据交换的动量和在切向量上不变的速度来找到A和B的对应速度。
对我来说这似乎很合理,并且可以工作!
但问题是有时候会出错。
我使用Visual Studio。
我对调试工具有一点了解,但无法很好地利用它来找到错误。
如果有人能帮忙,我将不胜感激。
我已经从头开始写了整个代码4次。
但是这种同样的方法总是出错。
所以我开始从头开始写整个东西,希望通过组织可以修复它。 请...帮帮我。
class Vector
{

    public double X = 0;
    public double Y = 0;
    public double Z = 0;
    public Vector direction
    {
        get { return new Vector(0.00000001 + X / Math.Abs(X), 0.00000001 + Y / Math.Abs(Y), 0.00000001 + Z / Math.Abs(Z)); }
    }

    public double angle { get { return Math.Atan2(Y, Z); } }

    //scholar operation
    public static Vector operator + (Vector v1 , double s) {
        return new Vector(v1.X + s , v1.Y + s , v1.Z +s );
    }
    public static Vector operator -(Vector v1, double s)
    {
        return new Vector(v1.X - s, v1.Y - s, v1.Z - s);
    }
    public static Vector operator *(Vector v, double s)
    {
        return new Vector(v.X * s, v.Y * s, v.Z * s);
    }
    //vector to vector operation
    public static Vector operator +(Vector a, Vector b)
    {
        return new Vector(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
    }
    public static Vector operator -(Vector a, Vector b)
    {
        return new Vector(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
    }
    public static Vector operator *(Vector a, Vector b)
    {
        return new Vector(a.X * b.X, a.Y * b.Y, a.Z *b.Z);
    }
    //other operations
    public static Vector operator %(Vector a, Vector b)
    {
        return new Vector(a.Y*b.Z - a.Z*b.Y, a.Z*b.X - a.X*b.Z , a.X*b.Y - a.Y*b.X);
    }
    public static double dotProduct(Vector a, Vector b)
    {
        Vector v = a*b;
        return a.X + a.Y + a.Z;
    }
    public static void makeOrthonormalBasic(Vector a, Vector b, Vector c)
    {
        c = b % a;
        if (c.squareMagnitude() != 0)
        {
            a = c % b;
        }
    }

    public Vector()
    {
        X = 0;
        Y = 0;
        Z = 0;
    }
    public Vector(double x, double y, double z)
    {
        X = x;
        Y = y;
        Z = z;
    }
    public Vector (double x , double y )
    {
        X= x;
        Y = y;
    }

    public void flip()
    {
        X *= -1;
        Y *= -1;
        Z *= -1;
    }
    public Vector fliped_vector()
    {
        Vector v = new Vector(X * -1, Y * -1, Z * -1);
        return v;
    }
    public double magnitude()
    {
        return Math.Sqrt(X * X + Y * Y + Z * Z);            
    }
    public double squareMagnitude() {
        return X * X + Y * Y + Z * Z;
    }
    public Vector normalize()
    {
        double m = magnitude();
        if (m > 0)
        {
            Vector v = new Vector();
            v.X = this.X;
            v.Y = this.Y;
            v *= 1 / m;
            return v;
        }
        return new Vector() ;
    }

    public void zero()
    {
        X = 0;
        Y = 0;
    }
    public void set(double x, double y)
    {
        X = x;
        Y = y;
    }
    public void add(double x, double y)
    {
        X += x;
        Y += y;
    }

}

class KCircle
{
    double size = 30;
    #region instant variables
    public Ellipse shape = new Ellipse();
    public Vector force = new Vector();
    public Vector velocity = new Vector();
    public Vector acceleration = new Vector();
    public Vector position = new Vector();
    #endregion
    public double Vector
    {
        get { return Math.Sqrt(velocity.X * velocity.X + velocity.Y * velocity.Y); }
    }
    public double Angle
    {
        get { return Math.Atan2(velocity.Y, velocity.X); }
    }
    public double radius
    {
        get { return shape.Width / 2; }
    }
    public double mass
    {
        get { return Math.PI * radius * radius; }
    }

    public KCircle()
    {
        initialize();
    }
    public void initialize()
    {
        color_normal();
        shape.StrokeThickness = 5;
        shape.Width = shape.Height = size;
    }

    public void change_color()
    {
        shape.Fill = System.Windows.Media.Brushes.Red;
        if (shape.Stroke == System.Windows.Media.Brushes.Red)
        {
            shape.Stroke = System.Windows.Media.Brushes.Blue;
            return;
        }
        shape.Stroke = System.Windows.Media.Brushes.Red;
    }
    public void color_normal()
    {
        shape.Stroke = System.Windows.Media.Brushes.Black;
        shape.Fill = System.Windows.Media.Brushes.White;
    }
}

private void process_object_interactions(){
        for (int i = 0; i < circles.Count; i++)
        {
            KCircle a = circles[i];
            for (int z = i + 1; z < circles.Count; z++)
            {
                KCircle b = circles[z];
                if (collide(a, b)  )
                {
                    a.change_color();
                    b.change_color();

                    Vector d = distance_between(a, b);
                    double angle_n = Math.Atan2(d.Y, d.X);
                    double angle_t = angle_n + 90;
                    double direction_n = 1;
                    double direction_t = 1;
                    if (angle_n < 0)
                    {
                        angle_n += 360;
                    }

                    if (angle_n > 180)
                    {
                        direction_t = -1;
                    }
                    if (angle_n > 90 && angle_n < 270)
                    {
                        angle_t = angle_n - 90;
                        angle_n += 180;
                        direction_n = -1;
                    }
                    if (angle_n > 360)
                    {
                        angle_n -= 360;
                    }
                    KCircle[] c = new KCircle[2];
                    c[0] = a;
                    c[1] = b;
                    double[] direction_n_array = new double[2];
                    direction_n_array[0] = direction_n;
                    direction_n_array[1] = direction_n * -1;
                    double[] direction_t_array = new double[2];
                    direction_t_array[0] = direction_t;
                    direction_t_array[1] = direction_t * -1;
                    double[] velocity_t = new double[2];
                    double[] velocity_n = new double[2];

                    for (int v = 0; v < 2; v++)
                    {
                        double angle = Math.Abs(c[i].velocity.angle - angle_n);
                        velocity_n[v] =(direction_n_array[v]) * (c[v].velocity.magnitude() * Math.Cos(angle));
                        velocity_t[v] = (direction_t_array[v]) *(c[v].velocity.magnitude() * Math.Sin(angle));
                    }
                    Vector[] new_vector_n = new Vector[2];
                    Vector[] momentum = new Vector[2];
                    for (int v = 0; v < 2; v++)
                    {
                        new_vector_n[v] = new Vector(velocity_n[v] * Math.Cos(angle_n), (velocity_n[v] * Math.Sin(angle_n)));
                        momentum[v] = new_vector_n[v];
                        momentum[v] *= c[v].mass;
                    }
                    /**
                    velocity_n_new[0] = normal_velocity_exchange(velocity_n[0], velocity_n[1], c[0].mass, c[1].mass);
                    velocity_n_new[1] = normal_velocity_exchange(velocity_n[1], velocity_n[0], c[1].mass, c[0].mass);
                     * */
                    for (int v = 0; v < 2; v++)
                    {
                        c[v].velocity.X = velocity_t[v] * Math.Cos( angle_t);
                        c[v].velocity.Y = -1* ((velocity_t[v] )* Math.Sin(angle_t)) ;
                    }
                    c[0].velocity += momentum[1] * (1 / c[0].mass);
                    c[1].velocity += momentum[0] * (1 / c[1].mass);
            }
        }
    }
}

1
你能描述一下你遇到的错误吗?这会影响到最优的调试策略。 - Gayot Fow
你能给我们提供KCircle和Vector的实现吗? - Entree
它的wpf程序就停止了,这就是我知道出现错误的方式。 - Bug
Circles是一个包含k个圆的列表,collode函数通过比较两个圆的半径之和来检测它们是否碰撞。如果两个圆之间的距离小于它们的半径之和,则它们会发生碰撞。 - Bug
@user1143720,WPF程序不会突然停止。你是指它卡住了变得无响应吗?具体发生了什么?此外,你是否检查过process_object_interactions()的边界条件?我不是一个三角函数专家,但如果角度为-450会发生什么?难道你不应该使用模运算符吗? - Gayot Fow
显示剩余9条评论
1个回答

1

这个问题有两个部分。

  1. 如何修复代码以使其正常运行?
  2. 如何使用Visual Studio调试器?

本答案将解决第二个问题。

首先,从Visual Studio中以调试模式运行程序。如果顶部工具栏中有一个名为“发布”的条目,则拉下该条目并将其更改为“调试”。然后点击绿色三角形以启动程序。

当遇到错误时,Visual Studio应显示异常助手对话框,如此处所述:http://msdn.microsoft.com/en-us/library/2ww37f14.aspx

这个对话框的标题是什么?它应该指出遇到了什么类型的异常。

在“操作”部分,单击“查看详细信息”以查看关于异常的更多信息。

展开详情并找到堆栈跟踪。在右侧拉下堆栈跟踪以展开它。堆栈跟踪的顶部行将告诉您哪一行源代码导致了错误,以及在此之前的方法调用序列是什么。

使用这些基本的调试信息来帮助确定问题所在,或者将其用于向问题中添加更具体的错误信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接