Box2Dで機械式時計
※wonderflを利用していますが正しく表示されない場合は当サーバ上のswfで表示する
概要
最初はぜんまいが巻かれていない状態です。
左上のボタンをクリックすると最初の数秒間リューズにトルクを加え、ぜんまいが巻かれ、時計が動き始めます。
途中から、30秒間で秒針(四番車)が何度回転するかを計測します。
やや細かい説明
まあ時計と言っても時針もなく、単にテンプ、アンクル、ガンギ車あたりの動きをBox2Dで再現してみた、というswfであります。
動きが微妙なところもありますが、、、(^^;
機械式時計の構造はこのサイトを参考にしました → Horology - 機械式時計の仕組み,知識,解説,研究 - | 機械式時計を楽しむサイト「TOKEI ZANMAI -時計三昧-」
各部品の位置やサイズ等はネット上で見つけた画像をベースに、適当に決めています。
もうちょっと細かい説明
swfは50FPSで設定しています。
ですからBox2Dでも1/50秒ごとに計算をしています。
部品ごとにもう少し細かい説明をしますね。
リューズ

右の写真で言うと、右側にあってゼンマイを巻くのに回転させるところがリューズ。
時刻合わせにも使いますが、本swfではそこまで表現しておりません。
当然、Box2Dでモデル化するためにリューズの回転軸が画面に垂直になっています。
コード上では、最初の250ステップほどリューズにトルクを加えています。
ちなみに、写真の機械式時計(TISSOT)は私のもので、毎朝ゼンマイを巻いております。ええ、こういうのが好きなんです、はい。
丸穴車
リューズの回転は丸穴車に伝わります。
リューズと丸穴車にはギアジョイントを設定しています。
角穴車
丸穴車の回転は角穴車に伝わります。
このあたりは右のページを見ればよくわかると思います → 時計のしくみ-ゼンマイの巻き上げと動力- | Horology | TOKEI ZANMAI-時計三昧-
実際にはコハゼというゼンマイから受けるトルクにより角穴車が逆回転しないような機構があるのですが、コード上では、単に"トルクを受けない"ということにしています。
香箱
角穴車と香箱はゼンマイを介してつながっていますので、角穴車が回転すると、それにより香箱も回転しようとします。
コード上では、この時に香箱が受けるトルクは
トルク[N・m] = ねじりばね定数[N・m/rad]×角度[rad]
と考え、角穴車と香箱車の角度差で決まるようにしています。
var theKoubakoAngle:Number = koubako.body.GetAngle();
var torque:Number = (theKakuanaAngle - theKoubakoAngle) * 3000;
ねじりばね定数が3000となっていますが、値は適当です。
二番車
香箱の回転は二番車の内側に伝わります。
このあたりはこのページが詳しいです → 時計のしくみ-動力の伝達- | Horology | TOKEI ZANMAI-時計三昧-
二番車、三番車、四番車とも内側に小さい歯車、外側に大きい歯車があって一体になっています(こういう歯車は何て言うんでしょうかね?)。
このように一体化した二つの大小の歯車を表現するのに、Box2Dでは、二つの歯車をディスタンスジョイントでつないでいます。
一つのbodyとするとギアジョイント(例えば二番車の外側と三番車の内側)の設定ができないための、苦肉の策であります(もっとスマートな方法はないものか、、、?)。
ちなみに、この二番車は1時間で1周します。つまり分針ですね。
三番車
二番車と四番車の仲介役ですね。
四番車
四番車は1分で1周します。つまり秒針です。
この四番車の外側の歯はガンギ車というギアにつながっています。
ガンギ車
ガンギ車は四番車の外側と噛み合う小さい歯車と、外周に15個の円を持つ物体として構成しています。
このガンギ車の回転する速度はアンクルによってコントロールされます。
このあたりの構成はここが詳しいです → 時計のしくみ-調速機と脱進機- | Horology | TOKEI ZANMAI-時計三昧-
アンクル

アンクルはガンギ車の回転を制御するツメとテンプと接触する部分の4つの部品としてモデル化しています。
右図のように、アンクルの支点(回転する中心)を十字で示しています。
テンプ
テンプは規則正しく往復で(って表現は変かな?)回転する部品ですので、ばねと質量ということでモデル化しています。
物体は外側に二つの円(別にどんな形状でもいいのですが、見た目に動いてるな!とわかるようにしたつもりであります)、内側にも二つの円をもっており、内側はアンクルと接触します。
テンプは回転ジョイントで固定され、ばねによるトルクを受けます。前述の
トルク[N・m] = ねじりばね定数[N・m/rad]×角度[rad]
の式に従い、コード上では毎ステップごとに
var tempuAngle:Number = tempu.body.GetAngle();//テンプの回転角
torque = tempuAngle* tempu._kr;//回転角とばね定数でトルクを決める
tempu.body.ApplyTorque(-torque);//トルクを与える
としています。
時計ですからテンプは規則正しく動いてくれなくては困るのですが、テンプの振動の周期はそのばね定数と質量(厳密には慣性モーメント)で決まります。
今回の時計では、テンプは2.5Hzで動く必要があることから、そのようにばね定数を求めています。
作成:2010年3月23日公開