はじめてのVB
以前からずっと使っている(かのB. DeMarco*1の手になるらしい)CCDカメラ制御&画像解析プログラムの一部をPCI用にちょっと修正した.これがなんとVisual Basic 6.0で書かれている.勘弁してくれ! (CCDカメラに付属のメーカー謹製制御ソフトをCOM経由で動かしているので,自分の好きな言語で再実装... とはやり難い)
Visual Basic 6.0にはArcCosがないらしい.ググってそれっぽいコードを拾ってきたが,定義域がどうなってるかは完全スルー:
There is no ArcSin and ArcCos functions in Visual Basic, but there is ArcTan function, and you can use it to calculate both ArcSin and ArcCos.
ということで以下のコードをコピペ:
Function ArcCos(X As Double) As Double ArcCos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1) End Function
しかしプログラムを実行してみるとエラー → 強制終了を連発.VB 6.0のエラーはスタック・トレースを吐かないのだが,どうやらこのArcCos
に渡る引数(CCD信号の強度の比みたいなもの)がSqr
かAtn
(ArcTan)の定義域に違反しているらしい.そこで禁術 On Error ...
を使ってみた.
Function ArcCos(X As Double) As Double On Error GoTo ErrorHandler ArcCos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1) ErrorHandler: ArcCos = 0 End Function
すると結果の画像が0で塗りつぶされてしまった.どうやら上のように書くとエラーが出ないときも ArcCos = 0
が実行されてしまうようだ.そこで次のように修正したらOKだった:
Function ArcCos(X As Double) As Double On Error GoTo ErrorHandler ArcCos = 0 ArcCos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1) ErrorHandler: End Function
関数の返り値を表す ArcCos
にまず0を代入し,そこに欲しい値を代入する行で,右辺の計算途中にエラーが出たら0から書き換わらないままに関数が終了する.
ちなみに 2 * Atn(1)
のようにArcTanを経由して円周率を表現するのは,円周率が定数として用意されてないシステムでは常套手段である.まぁ日本人は円周率をよく暗記しているので手で3.14159265くらいまで書けば十分だろうけど.
*1:http://www.physics.uiuc.edu/People/DeMarco/ Brian L. DeMarco, Department of Physics at the University of Illinois at Urbana-Champaign