spacepaste

  1.  
  2. #!/usr/bin/env python
  3. import pygame
  4. import ode
  5. default_density = 2500
  6. default_radius = 0.5
  7. white = (255, 255, 255)
  8. blue = (0, 0, 255)
  9. class Pendulum(object):
  10. def __init__(self, ball, joint):
  11. self.ball = ball
  12. self.joint = joint
  13. class Block(object):
  14. def __init__(self, block, anchors, joints, i_joints):
  15. self.block = block
  16. self.anchors = anchors
  17. self.joints = joints
  18. self.i_joints = i_joints
  19. def coord((x, y, z)):
  20. return int(100 + x*20), int(300 - y*20)
  21. def init_scene():
  22. # Position and density information
  23. pendulum_density = default_density
  24. pendulum_balls = [(0, 8, 0), (3, 5, 0), ( 7, 4, 0), (12, 3, 0)]
  25. pendulum_joints = [(5, 8, 0), (7, 8, 0), (10, 8, 0), (12, 8, 0)]
  26. base_density = default_density
  27. base_supports = [(5, 12, 0), (12, 12, 0)]
  28. base_joints = [(5, 8, 0), (12, 8, 0)]
  29. # Create world
  30. world = ode.World()
  31. world.setGravity((0, -9.81, 0))
  32. # Create base
  33. b_body = ode.Body(world)
  34. b_mass = ode.Mass()
  35. b_mass.setBox(base_density, 13, 2, 2)
  36. b_body.setMass(b_mass)
  37. b_body.setPosition((8.5, 8.5, 0))
  38. # Create supports
  39. b_anchors = []
  40. b_joints = []
  41. i_joints = []
  42. for s_pos, j_pos in zip(base_supports, base_joints):
  43. print "anchor at", s_pos
  44. # create the support ball
  45. s_body = ode.Body(world)
  46. s_mass = ode.Mass()
  47. s_mass.setSphere(default_density, default_radius)
  48. s_body.setMass(s_mass)
  49. s_body.setPosition(s_pos)
  50. # Create immovable joint
  51. i_joint = ode.BallJoint(world)
  52. i_joint.attach(s_body, ode.environment)
  53. i_joint.setAnchor(s_pos)
  54. print "connected", s_pos, "to environment."
  55. # Create flexible joint
  56. m_joint = ode.BallJoint(world)
  57. m_joint.attach(s_body, b_body)
  58. m_joint.setAnchor(j_pos)
  59. print "connected", s_pos, "to", j_pos
  60. b_anchors.append(s_body)
  61. b_joints.append(m_joint)
  62. i_joints.append(i_joint)
  63. base = Block(b_body, b_anchors, b_joints, i_joints)
  64. # Create pendulums
  65. p_list = []
  66. for p_pos, j_pos in zip(pendulum_balls, pendulum_joints):
  67. p_body = ode.Body(world)
  68. p_mass = ode.Mass()
  69. p_mass.setSphere(default_density, default_radius)
  70. p_body.setMass(p_mass)
  71. p_body.setPosition(p_pos)
  72. # Create & connect joint
  73. joint = ode.BallJoint(world)
  74. joint.attach(p_body, b_body)
  75. joint.setAnchor(j_pos)
  76. print "connected {0} to {1}".format(p_pos, j_pos)
  77. # Instantiate container class
  78. p_list.append(Pendulum(p_body, joint))
  79. # return base, p_list
  80. return world, base, p_list
  81. def init_graphics():
  82. pygame.init()
  83. screen = pygame.display.set_mode((600, 600))
  84. return screen
  85. def main(screen, world, base, p_list):
  86. clock = pygame.time.Clock()
  87. fps = 60
  88. dt = 1.0/fps
  89. while not pygame.event.get(pygame.QUIT):
  90. pygame.event.get([pygame.KEYDOWN, pygame.MOUSEMOTION])
  91. # update world
  92. world.step(dt)
  93. # render world
  94. screen.fill(white)
  95. for p in p_list:
  96. pygame.draw.circle(screen, blue, coord(p.ball.getPosition()), 10)
  97. pygame.draw.line(screen, blue, coord(p.joint.getAnchor()), coord(p.ball.getPosition()), 1)
  98. for p in p_list:
  99. pygame.draw.circle(screen, blue, coord(p.joint.getAnchor()), 10)
  100. pygame.draw.line(screen, blue, coord(p_list[0].joint.getAnchor()), coord(p_list[-1].joint.getAnchor()), 20)
  101. for a, j in zip(base.anchors, base.joints):
  102. pygame.draw.circle(screen, blue, coord(a.getPosition()), 10)
  103. pygame.draw.line(screen, blue, coord(a.getPosition()), coord(j.getAnchor()), 1)
  104. pygame.display.flip()
  105. # tick pygame's clock
  106. clock.tick(fps)
  107. if __name__=="__main__":
  108. screen = init_graphics()
  109. world, base, p_list = init_scene()
  110. main(screen, world, base, p_list)
  111.