こちらの続きです。
曲線と戦ってみる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の中間位置が代入されています。
'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に直行するベクトルの取得です。
本来位置は無関係なのですが、便宜上 mid2 を通過するように
書きました。このラインは、オイラー線と呼ばれるのですね。
最後に 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から外心までの距離だと言う事は
わかります。
⑧で外心(centre - 標準モジュールのメンバ変数)、⑨で半径を求めて
返しています。
関数は、何を渡して何が戻ってくるかさえ理解していれば、内部的に
どんな処理をしているのかまでは知らなくても、利用できるので
構わないと言えば構わないのですが・・・。