C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA

曲線と戦ってみる3

こちらの続きです。
曲線と戦ってみる2 - C#ATIA


Type1・2・3で共通に利用されているrad_3Pkeisan関数に、
"数学的な部分の一部が、理解出来ていない" 部分が存在しています。
出来れば知りたいところ・・・。

結果的には、3点を通過する円弧(=3点を頂点とする三角形の外接円)
の中心座標と半径を取得する関数と言うことは理解しています。

'vba
Function rad_3Pkeisan() As Double
    Dim V1(2) As Double, V2(2) As Double
    Dim n3(2) As Double, n2(2) As Double, kp(2) As Double
    Dim mid1(2) As Double, mid2(2) As Double, i As Integer
    
    For i = 0 To 2
        V1(i) = icd2(i) - icd1(i)
        V2(i) = icd3(i) - icd2(i)
        mid1(i) = (icd2(i) + icd1(i)) / 2#
        mid2(i) = (icd2(i) + icd3(i)) / 2#
    Next
    ・・・

icd1,icd2,icd3は標準モジュールのメンバ変数で、gen_cir関数で設定された
通過する3点の座標値が入っています。(今後この3点をP1,P2,P3と表現します)
For文内の、V1配列にはP1-P2のベクトル、V2配列にはP2-P3のベクトルを代入し
mid1はP1-P2の中間位置、mid2はP2-P3の中間位置が代入されています。
f:id:kandennti:20160620122341p:plain



'vba
    ・・・
    Call Unit_Vec(V1)
    Call Unit_Vec(V2)
    Call gaiseki(V1, V2, n3) '①
    Call gaiseki(V2, n3, n2) '②
    Call Unit_Vec(n2)
    ・・・

V1とV2を単位ベクトル化し、①部分でこの2ベクトルの外積(n3)を得ます。
これは、P1~P3を通る平面の向きのベクトルの取得ですね。

②部分ではV2と平面のベクトルの外積(n2)を得ています。
この部分は、V2に直行するベクトルの取得です。
f:id:kandennti:20160620122355p:plain
本来位置は無関係なのですが、便宜上 mid2 を通過するように
書きました。このラインは、オイラー線と呼ばれるのですね。

オイラー線 - Wikipedia

最後に n2 も単位ベクトル化しています。


'vba
    ・・・
    Dim nv  As Double, na As Double, D As Double, t As Double
    nv = V1(0) * n2(0) + V1(1) * n2(1) + V1(2) * n2(2) '③
    If 0.000000000001 > Math.Abs(nv) Then
        rad_3Pkeisan = -1
    ・・・

③部分での演算は、関数化されていないのですが、内積です。
V1とn2の内積(nv)を得た後、If文で結果を評価しています。
これはP1~P3の3点が、一直線上の並んで居るか?をチェックしています。
(かなりギリギリでチェックされていますね)


'vba
    ・・・
    Else
        D = V1(0) * mid1(0) + V1(1) * mid1(1) + V1(2) * mid1(2) '④
        na = V1(0) * mid2(0) + V1(1) * mid2(1) + V1(2) * mid2(2) '⑤
        t = (D - na) / nv '⑥
        
        For i = 0 To 2
            kp(i) = mid2(i) + t * n2(i) '⑦
            centre(i) = kp(i) '⑧
        Next
        rad_3Pkeisan = cal_leng(icd1(0) - kp(0), icd1(1) - kp(1), icd1(2) - kp(2)) '⑨
    End If
End Function

理解できていないのがこの部分です。 ④⑤の内積と先程の③の内積を利用し
⑥部分で演算しているのですが、この演算が何なのか?が、わかっていないんです。
但し⑦の演算から、求めた t はV2から外心までの距離だと言う事は
わかります。
f:id:kandennti:20160620122406p:plain
⑧で外心(centre - 標準モジュールのメンバ変数)、⑨で半径を求めて
返しています。

関数は、何を渡して何が戻ってくるかさえ理解していれば、内部的に
どんな処理をしているのかまでは知らなくても、利用できるので
構わないと言えば構わないのですが・・・。