我见过Peter Colling Ridge的精彩教程
http://www.petercollingridge.co.uk/pygame-physics-simulation/
我正在扩展PyParticles脚本
该代码在网站上可用(免费),我正在使用PyParticles4.py
本教程中使用的类
粒子类
圆形2d物体,具有半径,质量,速度,位置
春季班
弹簧绑定2个物体(粒子)并使用胡克定律(F = -kx)来确定它们之间的相互作用
环境类
粒子相互作用的环境
我想知道我是否可以使用2个粒子并制作一个"Rod"类(如教程中的Spring类),它具有特定的长度并且不允许粒子比那个(指定的)长度更接近。
也,
向每个粒子施加一个力(当需要时),这样如果一个被拉向左边,另一个被拉向另一个粒子,但实际上......
就像使用钢棒将2种不同类型的球(从中心)连接起来一样,但是在2-d ..
而且我不想使用第三方模块
提前致谢..
编辑/ UPDATE:
试图应用约束定理(失败)
这是代码:
class Rod:
def __init__(self, p1, p2, length=50):
self.p1 = p1
self.p2 = p2
self.length = length
def update(self):
'Updates The Rod and Particles'
# Temp store of co-ords of Particles involved
x1 = self.p1.x
x2 = self.p2.x
###### Same for Y #######
y1 = self.p1.y
y2 = self.p2.y
# Calculation of d1,d2,d3 and final values (x2,y2)
# from currently known values(x1,y1)...
# From Constraint algorithm(see @HristoIliev's comment)
dx1 = x2 - x1
dy1 = y2 - y1
# the d1, d2, d3
d1 = math.hypot(dx1,dy1)
d2 = abs(d1)
d3 = (d2-self.length)/d2
x1 = x1 + 0.5*d1*d3
x2 = x2 - 0.5*d1*d3
y1 = y1 + 0.5*d1*d3
y2 = y1 - 0.5*d1*d3
# Reassign next positions
self.p1.x = x1
self.p2.x = x2
###### Same for Y #######
self.p1.y = y1
self.p2.y = y2
你为什么不用一个非常强大的弹簧?
没有对象只是随机移动,它们没有按照我想要的方式运行,Python引发错误"OverflowError:Python int太大而无法转换为C long"
诸如杆之类的硬接头是完整约束。这些通常通过特殊约束算法或通过将它们建模为无限刚性弹簧来处理,并明确地找到必须应用于无约束系统的校正形式(参见此处的示例)。
@HristoIliev什么是x1,x2?你能解释最后2个方程式,我知道我必须将它们应用于x和y组件。
显然,x1和x2是第一和第二粒子的坐标。这些方程是针对1-d系统编写的,并且特定于Verlet积分器。你引用的框架使用不同的集成方案,因此方程将有不同的形式(老实说,我不知道它会是什么)。
@HristoIliev什么是t + delta(t)?
下一个时间步。
@HristoIliev不,我试过一个测试代码,它没有用。使用约束算法,它没有真实地模拟,并且碰撞使粒子表现异常......这是python的实现
为什么不用pymunk?
@BartlomiejLewandowski实际上我想在PyParticles模块之上创建自己的物理引擎。
您可以从javascript中的类似实现中获得灵感:github.com/kennethkufluk/js-mindmap这里有一个演示:kenneth.kufluk.com/google/js-mindmap
有些事情对我来说不合适。首先,在计算d1,d2和d3后,是否直接重新分配y2?其次,构造函数在任意位置取两个点并施加距离约束(固定长度)。这看起来很过分。更新方法是否意味着最初使它们符合长度限制?因为它没有。实际上,如果y2分配应该是y2 = y2 - ...而不是y2 = y1 - ...,则在调用之前和之后差异x2-x1和y2-y1是相同的。我不认为那就是你想要的。
@RickGoldstein对不起,一个错字,仍然没有变化,但是这就是它似乎是......而且,仔细阅读,我在这里看到这一行|这不能保证以与碰撞物理一致的方式这样做这就是我想要的,如果你认为我在实施中犯了错误,请至少指出我应该做的事情。
@Thava他们和spring相似(不一样),看python代码或者这个
2D中的杆具有3个自由度(2个速度/位置+ 1个旋转/角度频率)。
我将表示中心的位置,该位置通过常规方式的力进行修改,并使用旋转(为简单起见,围绕系统中心)变量计算粒子的位置。
通过力来修改旋转
ang_accel = F * r * sin (angle(F,r)) / (2*M * r^2)
哪里
ang_accel是角加速度
F是作用在特定球上的力,因此有2个扭矩*加起来,因为有两个力加起来(矢量方向)以更新中心的位置。
r是长度的一半
angle(F,r)是力矢量和半径矢量之间的角度(从中心到受力的粒子),
以便
F * r * sin (angle(F,r))是围绕中心的扭矩,和
2*M * r^2是围绕中心的两点系统的惯性矩。
有错字吗? ang_accel和dang_accel ??
是的,错字。 正如我所说,我会这样做,而不是基于粒子。 你有3个自由度,这种方法对于消除2个自由粒子系统所具有的四个中的一个是最自然的。
颗粒的质量是不一样的。
您可以通过改变惯性矩来调整角度加速度公式以考虑质量变化。
实际上,en.wikipedia.org / wiki / List_of_moments_of_inertia
@ m.brindley Thx的帮助。