t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Python Processing ベクトルの回転を使ったアニメーション(LEGO ライントレースボット研究の副産物)

今回は偶然の産物としてバネ状の軌跡を描くようなアニメーションが出来たのでご紹介。
もともとはLEGO Mindstorm EV3のライントレースボットで左右タイヤの回転比率によってカーブの軌跡がどう変わるかをProcessingでシミュレーションしたかったのだが、そちらはまだ上手くいっていない。

成果物


コード

あんまり綺麗なコードとは言えない。
ProcessingのPythonモードにしたことでsetupとdrawでvelocityなどのオブジェクト変数が共通と見做されなくなったので、とりあえず双方でGlobal宣言するくらいしか方法が思いつかずこうなった。Python知識をもっと磨けば解決すると思われる。

import math
radius = 100
circumference = 2 * radius * math.pi
b = 10
theta = b / circumference * 360

def setup():
    global velocity
    global location
    global acceleration
    size(800, 600)
    frameRate(30)
    location = PVector(0.0, 0.0)
    velocity = PVector(-5.0, -2.0)
    acceleration = PVector(-1.0, -1.0)
    fill(0)
    rect(0, 0, width, height)

def draw():
    #こちらのglobalは必要ないらしい。im_y_oさんありがとうございます。
    #global velocity
    #global location
    #global acceleration
    fill(0, 2)
    rect(0, 0, width, height)
    fill(255)
    noStroke()
    velocity.rotate(-radians(theta))
    location.add(acceleration)
    location.add(velocity)
    translate(width, height)
    ellipse(location.x, location.y, 20, 20)

経緯

話はまったくの別件から始まる。

先日LEGO Mindstorm EV3でライントレースボットを作ったが、動かす前にバッテリー切れで検証できていなかった。
thom.hateblo.jp

今日はちょっと後輪に手を加えてカーブに追随しやすくしてみた。

実際に動かしてみたのがこちら(割とうるさいので音量注意)
youtu.be

トレースは出来ているけど、カーブで曲がり切れておらず大回りした結果最後はラインへの新入角が大きくなりすぎてコースアウト。
カーブ処理は内輪が36度回転する間に外輪が360度、つまり1対10の比率としている。

この比率は適当に決めたものだが、実機だと変数(摩擦とか)が多くて比率と描かれるカーブの関係性がいまひとつ理解しづらいので、シミュレーションしてみようということを思いついた。

そこでVisual Programmingといえば、Processing!

いやぁ、学んだことってこう繋がるんだなぁと感激しながらちょっと考えてみた。

しかしすぐにこの問題の難しさに気づく。
内輪が1進む間に外輪が。。しかし車軸で繋がっているのでまっすぐは進めず角度が付く、そこで内輪・外輪ともに進行方向が変わるので。。。あれ?どうなるんだ?とか。

内輪の移動距離を微小な単位に落とし込むと外輪の移動距離が求まりその結果として角度θが求まるのでは。。あれ?もしかして微分ってここで使うものなの?あでも微細化しすぎるとコンピューターの最小座標単位である1ピクセルを下回るしなぁ。。あ、それで積分なのか?。。でもそもそも微積分よく分かってないので適用範囲なのかどうか不明。。とか。

でも厳密には外輪の移動って直線ではなくて円周上だよなぁ、だったら車軸距離を半径とした円周距離の比率に360度を掛けると角度θが求まるか。。でも求めた後、進行方向変わったあとってどうやって座標に落とし込むんだ。。とか。

まぁ、ごちゃごちゃとメモしながらひとしきり考えみたんだけど。。

うん、わからん!

そんで、とりあえず動かしながら考えてみようとなった。

そしたら新発見、なんとProcessingのPVectorクラスには、rotateという命令があることを知る。
もともと悩んでたのは、回転したらベクトルの向きが変わるけどベクトルって座標系だから回転をくわえた座標を三角関数でもとめ。。うわどうやるんだこれ!?だったので、なんだ、rotateあるなら簡単にできるやん!となった訳だ。

そして!

できなかった!!!

代わりにできたのが。。冒頭に戻る。

もうちょい考えないとダメみたいだ。

以上

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。