2017年9月30日土曜日

ボールの自由落下 pyodeの雛形コード


自分のしたことをネット上に公開すると、自分でもあとからなんだっけ
と思った時検索して、自分の過去の資料にいきつけるのでよい。

はじめは、ヒットするとはずかしがったが......
pyodeをやっている人は少ないようだ。

vpython ボールの落下をpyodeで描く    
https://blogs.yahoo.co.jp/hhhappyyyymoto/42321848.html
もあるが、
雛形コードとしてはこちらのほうがいい。

# coding: UTF-8
#ボールの自由落下による 地面とのバウンドから停止まで

import ode
from visual import *

class Field:
   
    #scene = display(forward=visual.norm((-2.0,-1.0,-1.0)))
   
    #物理世界を作成
    world=ode.World()
    world.setGravity((0, -9.81, 0))
    #自由落下させたいなら worldのコメントアウトのほうを生かし
    # 最後の方の ball.body.addForce((0,-1000,0)) を殺す
    #world.setGravity((0, 0, 0))
    #地平面を作成?
    space=ode.Space()

    #衝突関係
    jointgroup=ode.JointGroup()
    ode_floor=ode.GeomPlane(space,(0,1,0),0)
    #()なかの引数 上の例ではy軸方向に重力が発生
    #多分 spaceの最後の引数が y軸の座標を示す
    ode_floor.setCategoryBits(1)
    ode_floor.setCollideBits(3)
    ode_floor.viz=box(
        pos=(0,-0.03,0),
        width=10,length=10,height=0.06,color=(0.5,0.5,1.0))

    target_fps=30
    #target_fps=30だから1秒間に30回の処理をする
    dt=1.0/target_fps

    def near_callback(self,args,geom1,geom2):
        for c in ode.collide(geom1,geom2):
            #接触ジョイント (Contact joint) 
            #mu    摩擦係数 (摩擦方向1) mu2    摩擦係数 (摩擦方向2)
            #bounce    反発係数
            c.setBounce(0.97)
            c.setMu(50)
            c.setMu2(50)
            j=ode.ContactJoint(self.world,self.jointgroup,c)
            j.attach(geom1.getBody(),geom2.getBody())

    def tick(self):
        ball.update()
        time.sleep(0.03)
        self.space.collide((),self.near_callback)
        #self.dtの間隔で世界を動かしていく
        self.world.step(self.dt)
        self.jointgroup.empty()
        return True

class Ball:
    def __init__(self,field):
        self.body=ode.Body(field.world)
        M=ode.Mass()
        M.setSphere(1, 1)
        self.body.setMass(M)
        self.geom=ode.GeomSphere(
                space=field.space,
                radius=0.3
                )
        #このradiusが実際のバウンドを決める
        #多分 sphereの座標が0で radiusが0.3だから
        #posが0.3ぐらいのバウンド点になる
        self.geom.setCategoryBits(1)
        self.geom.setCollideBits(3)
        #上は Boxのジオメトリを作成
        self.geom.setBody(self.body)
        # 剛体にジオメトリをセット
        self.vball=sphere(
            radius=0.3,
            color=color.red)

    def update(self):
        pos=self.geom.getPosition()
        #boxのジオメトリの位置を得る
        self.vball.pos=pos
        print pos

field = Field()
ball=Ball(field)
ball.body.setPosition((0,2,0))
#ball.body.addForce((0,-1000,0))

while True:
    field.tick()

#最後の数行 main()にまとめて    
#if __name__ == '__main__':
#    main() 
# などとしたいけれど 変数にglobalをいくつも
#いれないと だめなようだ。

0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ページ

Featured Posts