我在c#中遇到麻烦,我正在尝试制作一个碰撞模拟器,用户可以在其中键入质量,速度和方向的值,但是当它们发生碰撞时,它们会相互粘在一起并且不会反弹。我认为这是因为程序认为对象的动量为零。
答案 0 :(得分:6)
虽然您应该首先学习如何调试小程序 - 请参阅原始问题的评论 - 这里的问题不仅仅在于您不知道错误的位置。这里的问题是这个类的设计很糟糕,而且设计缺陷使得它非常容易出错。
设计缺陷特别是该类的大量状态是冗余。您遇到的错误是数据不一致,这是冗余数据的典型问题。当数据冗余时,对其中一个数据的任何更新都会使其与其他数据不一致。然后,您必须编写代码来修复不一致性,并且该代码很容易出错。
要消除冗余,请确定系统中基础的内容,然后仅跟踪这些属性。按需计算其余部分,而不是存储它们。
在你的例子中,你有速度,速度,方向,质量,动量和位置。你对如何表示它们是不一致的:位置是矢量,但是表示为单独的坐标,速度和动量表示为矢量。动量对质量和速度来说是多余的。速度和方向对速度来说是多余的。因此,每当你改变速度,你必须改变速度,方向和动量;如果不这样做会使系统不一致,从而导致系统不稳定。
不要那样做。为质量,速度和位置创建读写属性。为速度,方向和动量创建只读属性。只读属性根据基本原理计算其值。
或者,如果您愿意,请将质量,速度,方向和位置设为基础,并从中计算速度和动量。随你。无所谓。重要的是你不存储可能不一致的信息。
同样,如果您将力和加速度作为属性添加到此系统,请从另一个计算其中一个。添加力作为矢量属性,然后计算力和质量的加速度。
答案 1 :(得分:1)
您正在构造函数中设置动量矢量:
momentum.x = velocity.x * mass;
momentum.y = velocity.y * mass;
我怀疑这是你设置它的唯一地方?随着速度的变化,你需要重新设置你的momenum向量。
这将是非常糟糕的做法,因为编码员有责任在他改变另一个时记住改变一个。由于动量是一种取决于速度的计算,因此使用" Getter"会更好,所以像这样:
public Vector GetMomentum()
{
return new Vector(Velocity.x*mass, Velocity.y*mass);
}
或者,如果您想像使用属性一样使用它,请使用c#中内置的getter和setter:
public Vector Momentum
{
get{
return new Vector(Velocity.x*mass, Velocity.y*mass);
}
}
你可以像以前使用Momentum.X一样使用它,每次它都会生成一个新的Vector。这可能不是很好,但它适合你已经拥有的代码。使用GetXMomentum()和GetYMomentum()进行计算可能会更好。