J'ai essayé d'exécuter "Tutorial 2" du site Honke PyODE-sama.
-- Cliquez ici pour d'autres articles sur la mise en œuvre de tut ↓ ・ "Tutoriel 1" (Chute d'objet, dessin Matplotlib ajouté) ・ "Tutoriel 3" (Contact multicorps, OpenGL)
--
Le sujet principal est "Tutoriel 2" Le contenu original est -Construire un pendule en reliant ** 3 objets ** avec 2 charnières. ・ Réglez la vitesse / le couple angulaire sur une charnière -La visualisation est ** dessin 2D par Pygame **.
Le réglage de la vitesse angulaire est commenté ici. J'ai également changé la taille et la coloration de l'écran pour produire une vidéo GIF.
・ Win10 ・ Python 3.8.0 64 bits ・ Pyo de 0.15.2 ・ Pygame 1.9.6 ・ Oreiller 7
Dans mon environnement, le code du site PyODE a été exécuté tel quel.
Extrait du message d'erreur pygame
pygame.draw.circle(srf, rgb, coord( xyz ), 20, 0)
TypeError: integer argument expected, got float
Action: Dans la routine appelée coord () au début du code J'ai inclus chacune des deux valeurs retournées dans int ().
Traiter les erreurs de pygame
def coord(x,y):
"Convert world coordinates to pixel coordinates."
return int(320+170*x), int(400-170*y)
Lors de l'exécution, la table vidéo 2D de Pygame s'affiche. Ici, le fichier enregistré au format GIF est publié.
Il n'y a que 3 objets ODE. La ligne est juste dessinée. Les objets noirs sont fixés dans l'espace. (Cet objet n'a pas à l'être.) Des modifications ont été apportées aux paramètres de liaison, aux paramètres de dessin, etc.
Il reste des pièces inutiles Puisqu'il s'agit d'un petit cordon, je vais le mettre sur le tout.
Python3
# pyODE example 2: Connecting bodies with joints
## Modified: Window-sizing, jointing-condition, and others.
import pygame
from pygame.locals import *
import ode
W = 640
H = 640
CX = 320
CY = 320
S = 80.
def coord(xyz):
(x,y,z) = xyz
"Convert world coordinates to pixel coordinates."
return int( CX +S*x ), int( CY -S*y)
from PIL import Image, ImageDraw
def storeImage( srfc, images ):
if NI_MAX <= len(images):
return
s = srfc
buf = s.get_buffer()
im = Image.frombytes( "RGBA", s.get_size(), buf.raw )
B,G,R,A = im.split()
img = Image.merge("RGBA",(R,G,B,A))
images.append(img)
def gif(images):
print(' @ gif(), ')
savepath = 'tutorial_2.gif'
image0 = images[0]
image_end = images[-1]
for i in range( 5 ):
images.insert(0,image0)
for i in range( 5 ):
images.append(image_end)
images[0].save( savepath, save_all=True, append_images=images[1:], optimize=not False, duration=100, loop=0 )
print(' Exported : [%s]'%savepath)
NI_MAX = 10000
images=[]
# Initialize pygame
pygame.init()
# Open a display
srf = pygame.display.set_mode( (W,H) )
#
# Create a world object
world = ode.World()
world.setGravity((0,-9.81,0))
#
# Create two bodies
body0 = ode.Body(world)
M = ode.Mass()
M.setSphere(2500, 0.05)
body0.setMass(M)
body0.setPosition( (0,0,0) )
body1 = ode.Body(world)
M = ode.Mass()
M.setSphere(2500, 0.05)
body1.setMass(M)
body1.setPosition( (1,1,0) )
body2 = ode.Body(world)
M = ode.Mass()
M.setSphere(2500, 0.05)
body2.setMass(M)
body2.setPosition( (0,2,0) )
bodys = [body0,body1,body2]
# Connect body0 with the static environment
if True:
j0 = ode.BallJoint(world)
j0.attach(body1, ode.environment)
j0.setAnchor( body0.getPosition() )
if False:
j0 = ode.HingeJoint(world)
j0.attach(body1, ode.environment)
j0.setAnchor( body0.getPosition() )
j0.setAxis( (0,0,1) )
#j0.setParam(ode.ParamVel, 3)
#j0.setParam(ode.ParamFMax, 22)
# Connect body1 with body0
j01 = ode.BallJoint(world)
j01.attach(body0, body1)
j01.setAnchor( body0.getPosition() )
# Connect body2 with body1
j12 = ode.BallJoint(world)
j12.attach(body1, body2)
j12.setAnchor( body1.getPosition() )
joints = [j0, j01, j12]
RGBs = { body0:(63, 63, 63), body1:(127, 63, 63), body2:(63, 127, 63) }
####################################################
# Simulation loop...
fps = 50
dt = 1.0/fps
loopFlag = True
clk = pygame.time.Clock()
ti = -1
while loopFlag:
ti += 1
events = pygame.event.get()
for e in events:
if e.type==QUIT:
loopFlag=False
if e.type==KEYDOWN:
gif( images )
loopFlag=False
# Clear the screen
srf.fill((255,255,255))
for joint in joints:
if joint is j0:
continue
rgb = (127,127,127)
SIMPLE=False
if SIMPLE:
p0 = coord( joint.getBody(0).getPosition() )
p1 = coord( joint.getBody(1).getPosition() )
else: #### joint.attach(body, ode.environment)Correspondance avec la position d'ancrage dans le cas de, et codage couleur de la ligne
b_move = None
b0 = joint.getBody(0)
if b0:
if b0.getPosition() != joint.getAnchor():
b_move = b0
if None is b0:
p0 = coord( joint.getAnchor() )
if None is p0:
p0 = coord( body0.getPosition() )
else:
p0 = coord( b0.getPosition() )
b1 = joint.getBody(1)
if b1:
if b1.getPosition() != joint.getAnchor():
b_move = b1
if None is b1:
p1 = coord( joint.getAnchor() )
if None is p1:
p1 = coord( body0.getPosition() )
else:
p1 = coord( b1.getPosition() )
rgb = RGBs[b_move]
lw = 5
pygame.draw.line( srf, rgb, p0,p1, lw)
for body in bodys:
xyz = body.getPosition()
rgb = RGBs[body]
pygame.draw.circle(srf, rgb, coord( xyz ), 20, 0)
pygame.display.flip()
if ti % 4 == 0:
storeImage(srf,images)
# Next simulation step
world.step(dt)
# Try to keep the specified framerate
clk.tick(fps)
#if not loopFlag:
# gif( images )
Recommended Posts