科学と家事とプログラミング (python を中心に)

python 温度計測 湿度計測 DS18B20 USB9097

図形を使った解法は、見ためも安心なのです(改)

コンピューターグラフィックスのアイデアが、ピタッとと当てはまる問題というのがあります。 教科書に出てきそうな Bang-Bang 制御の切り替え線の判定も、そんな問題の一つです。 図形の論理演算(and/or)を使って、制御の ON/OFF を判定する例を紹介します。

Bang-Bang 制御

Bang-Bang 制御は、位置  x と速度  \dot{x} に応じて、 一定量の制御を加えるかどうかを判定します。 いろんなパターンがありますが、たとえばこんな感じ(位相面)。

f:id:sken20k:20180525173650j:plain:w200

水色の領域では下向きに、緑色の領域では上向きに制御を加えます(速度を変化させる)。 折れ線になっているので、判定はちょっと面倒ですね。

よくある解法

よくある解法は、直線の交点を求めて x との大小関係で比較直線を選ぶというものでしょう。 そのままロジックを組むと、たくさんの交点を求めるのも面倒だし、 判定も if else がいくつも連なって、ややこしくなりそうです。

図形を使った解法

図形を使った解法はこうです。 比較的単純な領域を定義して、それらの論理和としてもとの領域を表現します。

f:id:sken20k:20180525173956j:plain:w400

制御を加える領域は、上の3つの領域の和になっています。 仕様(図計)を、プログラムに直せば、こんな感じになります。

def judge(x, y):
    y1, y2, y3, y4, y5 = f1(x), f2(x), f3(x),  f4(x), f5(x)
    if (y > y1 and y > y2) or (y>y3 and y>y4) or (y > y5):
        output = -1
   else:
        output = 0
    return output

仕様(図形を使った表現)と実装の対応が良いのも魅力です。 レビューをしっかりすれば、ほぼ間違えることはないのだけれど、 この手のロジックを検証する場合は、作った関数を使って、元の切り替え線(判定領域)を 作図してみるのが確実です(位相面を2次元でサンプリングする)。

おまけ

3次元CG のモデリング(画像生成)では、基本的な形状の組みあわせによって 複雑な形状を表現することがあります。 例えば、レンズの形は、球と球の and 領域として定義できます。 上の、Bang-Bang 制御の判定ロジックは、そこからアイデアをいただきました。 むかし CGや図形処理で遊んでいましたが、そういう経験が結構役立つ場面は多い気がします。 図形処理は、応用範囲が広いということですかね。