球与球碰撞 - 物体粘在一起
本文关键字:在一起 碰撞 | 更新日期: 2023-09-27 18:34:18
我在 c# 中遇到了问题,我正在尝试制作一个碰撞模拟器,用户在其中输入质量、速度和方向的值,但是当他们碰撞时,它们会相互粘连而不会反弹。我认为这是因为程序认为物体的动量为零。
虽然你应该从学习如何调试小程序开始——参见对原始问题的评论——但你在这里的问题不仅仅是你不知道错误在哪里。这里的问题是这个类设计得很糟糕,设计缺陷使其非常容易出错。
设计缺陷具体在于类的大量状态是多余的。您遇到的错误是数据不一致,这是冗余数据的经典问题。当数据冗余时,对其中一个数据的任何更新都会使其与其他数据不一致。然后,您必须编写代码来修复不一致,并且该代码很容易出错。
要消除冗余,请找出系统中的基本属性,然后只跟踪这些属性。按需计算其余部分,而不是存储它们。
在你的例子中,你有速度、速度、方向、质量、动量和位置。你对它们的表示方式不一致:位置是一个向量,但表示为单个坐标,速度和动量表示为向量。动量对质量和速度是多余的。速度和方向对于速度是多余的。因此,任何时候你改变速度,你必须改变速度、方向和动量;如果不这样做,系统就会不一致,因此会出现错误。
只是不要那样做。 创建质量、速度和位置的读写属性。为速度、方向和动量创建只读属性。 只读属性从基本面计算其值。
或者,如果您愿意,可以将质量、速度、方向和位置作为基本值,并从中计算速度和动量。无论什么。无所谓。重要的是,您不会存储可能不一致的信息。
同样,如果将力和加速度作为属性添加到此系统,请从另一个计算其中一个。将力添加为矢量属性,然后根据力和质量计算加速度。
你在构造函数中设置动量向量:
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 和 setters:
public Vector Momentum
{
get{
return new Vector(Velocity.x*mass, Velocity.y*mass);
}
}
你可以像以前使用Momentum.X一样使用它,每次它都会生成一个新的Vector。这可能不是很好,但它适合您已经拥有的代码。最好使用 GetXMomentum(( 和 GetYMomentum(( 来执行计算。