我能';找不到什么';在python中,这个圆反弹计算是错误的

我能';找不到什么';在python中,这个圆反弹计算是错误的,python,debugging,physics,bounce,Python,Debugging,Physics,Bounce,我有一个程序,在这个程序中,圆圈可以相互碰撞。我按照这里的方向旋转矢量,并根据碰撞角度缩放大小: 我用python编写了这段代码(0索引表示x坐标): 问题是它有时有效,但在其他时间无效。谁能告诉我为什么?看起来,如果球以正确的角度碰撞,那么它们的退出轨迹就会互换或发生什么变化。我在codeskulptor浏览器中写道: 有人能指出我哪里出了错吗 编辑:这可能是我处理碰撞的方式吗?以下是步骤: 1) Draw the balls on the screen 2) Create s

我有一个程序,在这个程序中,圆圈可以相互碰撞。我按照这里的方向旋转矢量,并根据碰撞角度缩放大小:

我用python编写了这段代码(0索引表示x坐标):

问题是它有时有效,但在其他时间无效。谁能告诉我为什么?看起来,如果球以正确的角度碰撞,那么它们的退出轨迹就会互换或发生什么变化。我在codeskulptor浏览器中写道:

有人能指出我哪里出了错吗

编辑:这可能是我处理碰撞的方式吗?以下是步骤:

    1) Draw the balls on the screen
    2) Create set of unique pairs of collidable objects 
    3) For each ball, move the ball's position 1 frame forward according to the velocity:
        ->1) Check to see if the ball is hitting a wall
        ->2) For each pairset, if the ball in question is a member of the pair:
             -->1) If distance between centers is less than sum of radii:
                    -->1)  Calculate rebound trajectories
                    ---2)  Find N such that position + rebound trajectory *N is out of collision zone

在线模拟真的很酷!我没有详细研究您的完整代码,只是您在问题中发布的代码片段。通过快速浏览,可以正确计算切向和法向单位向量、旧法向和切向速度以及新法向速度。但在那之后,你似乎有点迷路了。正如关于碰撞的文档中所解释的,切向速度在碰撞过程中不会改变,因此无需计算
new_tan_vect1/2
。我也不明白你为什么要计算新的new\u norm\u vect1,法向量在碰撞过程中不会改变

其他一些小评论:

  • 为什么在代码中都使用
    float()
    ?这通常是不需要的。如果这样做的原因是为了得到正确的除法结果,那么您确实应该在代码顶部添加一个来自uuu future uuu导入除法的
    ,因为您似乎正在使用Python2。有关更多信息,请参阅

  • 你所称的
    norm\u vect
    实际上是未规范化的法向量,而你所称的
    unit\u vect
    实际上是规范化的法向量。我会称之为norm_vect,以便更清楚地区分法线和切线。单位向量是长度为1的任何向量,因此将其用作法向量有点误导

  • <> >如果你计划做更多的这种模拟,你应该考虑学习<代码> NUMPY < /C>。这允许您编写矢量化计算,而不是手动写出
    x
    y
    的所有方程式。例如,
    norm\u vect=pos2-pos1;norm\u vect/=np.linalg.norm(norm\u vect)
    or
    object1.vel=norm\u vect*new\u vel1\u norm+tang\u vect*vel1\u tang

我会编写您的代码片段,大致如下(未经测试的代码):


我重命名了一些变量以使其更清晰。

您最后一行的object2.2是什么?输入错误:)我的实际代码与我的类有点不同,因此我必须在这里重写一些。错过了那个!如果你只是想解决这个问题,而不在乎从第一原理来解决它,那么你可以用一个物理引擎来代替。tan_vect和tang_vect是不是意味着是一回事?是的,出于某种原因,当我写它的时候,我把它写成“tang”而不是“tan”,然后当我在这里复制它的时候,我想解决这个问题,而不是装傻。。。就这么多!现在我觉得我在python中搞砸了,因为速度在变化,但出于某种原因,全局类状态没有改变。请看这里:是不是因为codeskulptor是一个非常有限的Python实现,人们可以学习交互的基础知识,所以我不能从
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu看看你在碰撞函数中打印的速度,似乎当一个轻球与一个重球碰撞时,速度会像它应该的那样翻转,但紧接着它又朝相反的方向翻转,所以实际上什么也没有发生。错误出现在
match_objects
函数中,您将每对对象添加两次,一次向前,一次向后。然后,从object1和object2两次检测到每个碰撞,这两个碰撞会相互抵消。这似乎奏效了(球有时会卡住):啊,这很有道理。我认为在set()中,(a,b)与(b,a)是相同的,因此不会添加两次。非常感谢你!你帮了大忙!!不,元组(a,b)不同于元组(b,a)。还有一件事我要改变:在
冲突中
,在迭代集合时从集合中删除一对。在迭代过程中对序列进行变异可能会导致错误。我不会在球对象的
move_frame
函数中循环所有对,而是在模拟的主循环中对所有对进行显式迭代,类似于
对于范围内的I(n-1):对于范围内的j(1+1,n):检查对(I,j)…
。这将省去从集合中删除对的麻烦。
    1) Draw the balls on the screen
    2) Create set of unique pairs of collidable objects 
    3) For each ball, move the ball's position 1 frame forward according to the velocity:
        ->1) Check to see if the ball is hitting a wall
        ->2) For each pairset, if the ball in question is a member of the pair:
             -->1) If distance between centers is less than sum of radii:
                    -->1)  Calculate rebound trajectories
                    ---2)  Find N such that position + rebound trajectory *N is out of collision zone
from __future__ import division  # move this to the top of your program

# calculate normal and tangential unit vectors
norm_vect = [(object2.pos[0] - object1.pos[0]), 
             (object2.pos[1] - object1.pos[1])]  # stil un-normalized!
norm_length = sqrt((norm_vect[0]**2) + (norm_vect[1]**2))
norm_vect = [norm_vect[0] / norm_length, 
             norm_vect[1] / norm_length]  # do normalization
tang_vect = [-norm_vect[1], norm_vect[0]]  # rotate norm_vect by 90 degrees

# normal and tangential velocities before collision
vel1 = object1.vel
vel2 = object2.vel
vel1_norm = vel1[0] * norm_vect[0] + vel1[1] * norm_vect[1]
vel1_tang = vel1[0] * tang_vect[0] + vel1[1] * tang_vect[1]
vel2_norm = vel2[0] * norm_vect[0] + vel2[1] * norm_vect[1]
vel2_tang = vel2[0] * tang_vect[0] + vel2[1] * tang_vect[1]

# calculate velocities after collision
new_vel1_norm = (vel1_norm * (object1.mass - object2.mass) 
    + 2 * object2.mass * vel2_norm) / (object1.mass + object2.mass)
new_vel2_norm = (vel2_norm * (object2.mass - object1.mass) 
    + 2 * object1.mass * vel1_norm) / (object1.mass + object2.mass)
# no need to calculate new_vel_tang, since it does not change

# Now update the object's velocity
object1.vel = [norm_vect[0] * new_vel1_norm + tang_vect[0] * vel1_tang, 
               norm_vect[1] * new_vel1_norm + tang_vect[1] * vel1_tang]
object2.vel = [norm_vect[0] * new_vel2_norm + tang_vect[0] * vel2_tang, 
               norm_vect[1] * new_vel2_norm + tang_vect[1] * vel2_tang]