| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #!/usr/bin/env python
- # http://pyode.sourceforge.net/tutorials/tutorial2.html
- # pyODE example 2: Connecting bodies with joints
- # modified by Gideon Klompje (removed literals and using
- # 'ode.Mass.setSphereTotal' instead of 'ode.Mass.setSphere')
- import ode
- import pygame
- from pygame.locals import QUIT, KEYDOWN
- # Constants
- WINDOW_RESOLUTION = (640, 480)
- DRAW_SCALE = WINDOW_RESOLUTION[0] / 5
- """Factor to multiply physical coordinates by to obtain screen size in pixels"""
- DRAW_OFFSET = (WINDOW_RESOLUTION[0] / 2, 50)
- """Screen coordinates (in pixels) that map to the physical origin (0, 0, 0)"""
- BACKGROUND_COLOR = (255, 255, 255)
- GRAVITY = (0, -9.81, 0)
- SPHERE1_POSITION = (1, 0, 0)
- SPHERE1_MASS = 1
- SPHERE1_RADIUS = 0.15
- SPHERE1_COLOR = (55, 0, 200)
- SPHERE2_POSITION = (2, 0, 0)
- SPHERE2_MASS = 1
- SPHERE2_RADIUS = 0.15
- SPHERE2_COLOR = (55, 0, 200)
- JOINT1_ANCHOR = (0, 0, 0)
- JOINT1_COLOR = (200, 0, 55)
- JOINT1_WIDTH = 2
- """Width of the line (in pixels) representing the joint"""
- JOINT2_ANCHOR = SPHERE1_POSITION
- JOINT2_COLOR = (200, 0, 55)
- JOINT2_WIDTH = 2
- """Width of the line (in pixels) representing the joint"""
- TIME_STEP = 0.04
- # Utility functions
- def coord(x, y, integer=False):
- """
- Convert world coordinates to pixel coordinates. Setting 'integer' to
- True will return integer coordinates.
- """
- xs = (DRAW_OFFSET[0] + DRAW_SCALE*x)
- ys = (DRAW_OFFSET[1] - DRAW_SCALE*y)
- if integer:
- return int(round(xs)), int(round(ys))
- else:
- return xs, ys
- # Initialize pygame
- pygame.init()
- # Open a display
- screen = pygame.display.set_mode(WINDOW_RESOLUTION)
- # Create a world object
- world = ode.World()
- world.setGravity(GRAVITY)
- # Create two bodies
- body1 = ode.Body(world)
- M = ode.Mass()
- M.setSphereTotal(SPHERE1_MASS, SPHERE1_RADIUS)
- body1.setMass(M)
- body1.setPosition(SPHERE1_POSITION)
- body2 = ode.Body(world)
- M = ode.Mass()
- M.setSphereTotal(SPHERE2_MASS, SPHERE2_RADIUS)
- body2.setMass(M)
- body2.setPosition(SPHERE2_POSITION)
- # Connect body1 with the static environment
- j1 = ode.BallJoint(world)
- j1.attach(body1, ode.environment)
- j1.setAnchor(JOINT1_ANCHOR)
- # Connect body2 with body1
- j2 = ode.BallJoint(world)
- j2.attach(body1, body2)
- j2.setAnchor(JOINT2_ANCHOR)
- # Simulation loop...
- if __name__ == "__main__":
- fps = 1.0 / TIME_STEP
- clk = pygame.time.Clock()
- sph1_rad = int(DRAW_SCALE * SPHERE1_RADIUS)
- sph2_rad = int(DRAW_SCALE * SPHERE2_RADIUS)
- loopFlag = True
- while loopFlag:
- for e in pygame.event.get():
- if e.type==QUIT:
- loopFlag=False
- if e.type==KEYDOWN:
- loopFlag=False
- # Clear the screen
- screen.fill(BACKGROUND_COLOR)
- # Draw the two bodies and the lines representing the joints
- x1, y1, z1 = body1.getPosition()
- x2, y2, z2 = body2.getPosition()
- xj1, yj1, zj1 = j1.getAnchor()
- xj2, yj2, zj2 = j2.getAnchor()
- pygame.draw.line(screen, JOINT1_COLOR, coord(xj1, yj1), coord(x1, y1), JOINT1_WIDTH)
- pygame.draw.line(screen, JOINT2_COLOR, coord(xj2, yj2), coord(x2, y2), JOINT2_WIDTH)
- pygame.draw.circle(screen, SPHERE1_COLOR, coord(x1, y1, integer=True), sph1_rad, 0)
- pygame.draw.circle(screen, SPHERE2_COLOR, coord(x2, y2, integer=True), sph2_rad, 0)
- pygame.display.flip()
- # Next simulation step
- world.step(TIME_STEP)
- # Try to keep the specified framerate
- clk.tick(fps)
|