具有相同初始条件的混沌摆

2024-06-28 14:28:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我的第一篇关于堆栈溢出的帖子,请忍受我。 我用pymunk物理库在pymunk物理库中建立了一个混沌双摆模型,而pymunk物理库又使用了花栗鼠C库。钟摆处于混沌状态,对初始条件表现出极大的敏感性。然而,我已经意识到,即使我在完全相同的初始条件下运行模拟(不管怎样改变零代码),这两个模拟的分歧还是相当快的。

我的代码中有一些东西在每次运行时都有可能产生不同的结果。因为模拟是混乱的,任何一个微小的错误,如果不是我运行之间的常数,都会导致很大的变化。

是什么引起的?我不确定这是否是花栗鼠、pymunk,甚至python或我的OS/PC中的一个小缺陷造成的

编辑:

这是我的代码:

import pyglet
import pymunk
import pymunk.pyglet_util


def add_pendulum(space):
    static_body = pymunk.Body()
    static_body.position = 400, 400
    mass = 10
    inertia = pymunk.moment_for_box(mass, 5, 100)

    body1 = pymunk.Body(mass, inertia)
    body1.position = 350, 400
    l1 = pymunk.Poly(body1, [(50, 0), (-50, 0), (-50, 5), (50, 5)])
    l1.friction = 0.1
    l1.collision_type = 2
    pivot_joint = pymunk.PivotJoint(static_body, body1, (400, 400))
    space.add(body1, l1, pivot_joint)

    mass = 10
    inertia = pymunk.moment_for_box(mass, 5, 100)
    body2 = pymunk.Body(mass, inertia)
    body2.position = 250, 400
    l2 = pymunk.Poly(body2, [(50, 0), (-50, 0), (-50, 5), (50, 5)])
    l2.friction = 0.1
    l2.collision_type = 2
    pivot_joint2 = pymunk.PivotJoint(body1, body2, (300, 402.5))

    space.add(body2, l2, pivot_joint2)

    # A hack to disable all collisions
    nocollisions = lambda space, arbiter: False
    space.add_collision_handler(2, 2, nocollisions, nocollisions, nocollisions, nocollisions)



window = pyglet.window.Window(800, 600)
space = pymunk.Space()
add_pendulum(space)
space.gravity = (0, -10)



test = [()] # A temporary hack to hide the tuple in a mutable object

def on_draw(dt): #For graphing the moving pendulum
    points = test[0]
    space.step(dt)
    pyglet.gl.glClearColor(0, 0, 0, 1)
    window.clear()
    pymunk.pyglet_util.draw(space)
    points += (int(tuple(space.shapes[1].get_vertices()[1])[0]), int(tuple(space.shapes[1].get_vertices()[1])[1]))
    pyglet.gl.glClearColor(200, 200, 200, 1)
    pyglet.graphics.draw(len(points)/2, pyglet.gl.GL_POINTS,
                         ('v2i', points)
                         )
    test[0] = points


pyglet.clock.schedule_interval(on_draw, 1/1000.0)
pyglet.app.run()

Tags: addl1物理spacemasspointspygletpivot
1条回答
网友
1楼 · 发布于 2024-06-28 14:28:16

关于从pyglet.clock.schedule_interval调用的on_draw(dt)函数,pyglet docs状态:

The dt parameter gives the number of seconds (due to latency, load and timer inprecision, this might be slightly more or less than the requested interval).

  • 强调我的。在

每次运行程序时,它都会用稍微不同的dt参数调用on_draw。继续调用space.step(dt),每次调用都会略有不同。考虑到你的程序对不断变化的环境有多敏感,我认为这是罪魁祸首。在

不确定这是否有用,但是here 是另一个关于固定或可变时间步数和物理(嗯,游戏引擎)的问题。在

相关问题 更多 >