gpt4 book ai didi

python - 我找不到 python 中的这个圆反弹计算有什么问题

转载 作者:太空狗 更新时间:2023-10-30 01:28:42 25 4
gpt4 key购买 nike

我有一个程序可以让圆圈相互反弹。我按照此处的说明旋转矢量并根据碰撞角度缩放大小:http://www.vobarian.com/collisions/2dcollisions2.pdf

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

norm_vect = [(object2.pos[0] - object1.pos[0]), (object2.pos[1] - object1.pos[1])]
unit = sqrt((norm_vect[0]**2) + (norm_vect[1]**2))
unit_vect = [float(norm_vect[0]) / unit, float(norm_vect[1]) /unit]
tan_vect = [-unit_vect[1], unit_vect[0]]
vel1 = object1.vel
vel2 = object2.vel
vel1_norm = vel1[0] * unit_vect[0] + vel1[1] * unit_vect[1]
vel1_tan = vel1[0] * tan_vect[0] + vel1[1] * tan_vect[1]
vel2_norm = vel2[0] * unit_vect[0] + vel2[1] * unit_vect[1]
vel2_tan = vel2[0] * tan_vect[0] + vel2[1] * tan_vect[1]
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)
new_norm_vect1 = [new_vel1_norm * float(unit_vect[0]), new_vel1_norm * float(unit_vect[1])]
new_norm_vect2 = [new_vel2_norm * float(unit_vect[0]), new_vel2_norm * float(unit_vect[1])]
new_tan_vect1 = [new_vel1_norm * float(tan_vect[0]), new_vel1_norm * float(tan_vect[1])]
new_tan_vect2 = [new_vel2_norm * float(tan_vect[0]), new_vel2_norm * float(tan_vect[1])]

# Now update the object's velocity
object1.vel = [new_norm_vect1[0] + new_tan_vect1[0], + new_norm_vect1[1] + new_tan_vect1[1]]
object2.vel = [new_norm_vect2[0] + new_tan_vect2[0], + new_norm_vect2[1] + new_tan_vect2[1]]

问题是它有时有效,但有时无效。谁能告诉我为什么?似乎如果球以正确的角度碰撞,那么它们的导出轨迹就会交换或发生其他事情。我在 codeskulptor 浏览器中写了这个:http://www.codeskulptor.org/#user39_8q0Xdp3Y4s_2.py

谁能指出我哪里做错了?

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

    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_norm_vect1,法向量在碰撞过程中不会改变。

一些其他的小备注:

  • 为什么在代码中使用float()?这通常不需要。如果这样做的原因是为了获得正确的除法结果,您应该在代码顶部添加一个 from __future__ import division,因为您似乎使用的是 Python2。参见 this old question了解更多信息。

  • 你所说的norm_vect其实就是非归一化的法向量,你所说的unit_vect其实就是归一化的法向量。我会同时调用 norm_vect,以使法线和切线之间的区别更加清楚。单位向量是长度为 1 的任何向量,因此将其用于法线向量有点误导。

  • 如果您打算进行更多此类模拟,您应该考虑学习 numpy。这允许您编写矢量化计算,而不是手写出所有 xy 的方程式。例如。 norm_vect = pos2 - pos1; norm_vect/= np.linalg.norm(norm_vect)object1.vel = norm_vect * new_vel1_norm + tang_vect * vel1_tang

我会写你的代码片段应该或多或少像这样(未经测试的代码):

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]

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

关于python - 我找不到 python 中的这个圆反弹计算有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29136677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com