C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

三次元ベクトル演算

CATIA V5用の自作ライブラリっぽいものを
こちらで公開していますが、
GitHub - kantoku-code/KCL: CATIA Library for personal CATVBA (CATIA macro)
不覚にも三次元ベクトル演算類が入ってません・・・。
前々から入れたいとは思っていたのですが。

使うかな?と思い、ボチボチ作っていたのですが、
ちょっと使わなそうなので、こちらに記載しておきます。

'vba
Option Explicit

Private Const EQUAL_TOLERANCE = 0.00001


Sub CATMain()

    Dim res

    res = is_parallel( _
        Array(0, 0, 1), _
        Array(0, 0, -1) _
    )
    Debug.Print res

    res = is_equal( _
        Array(0, 0, 1), _
        Array(0, 0, 1.000001) _
    )
    Debug.Print res

End Sub


Private Function is_equal( _
    ByVal v1 As Variant, _
    ByVal v2 As Variant) _
    As Boolean

    Dim i As Long
    For i = 0 To 2
        If Not (Abs(v1(i) - v2(i)) < EQUAL_TOLERANCE) Then
            is_equal = False
            Exit Function
        End If
    Next

    is_equal = True

End Function


Private Function is_parallel( _
    ByVal v1 As Variant, _
    ByVal v2 As Variant) _
    As Boolean

    Dim n1 As Variant, n2 As Variant
    n1 = normalize(v1)
    n2 = normalize(v2)

    Dim res As Double
    res = dot( _
        normalize(v1), _
        normalize(v2) _
    )

    If Abs(1 - Abs(res)) < EQUAL_TOLERANCE Then
        is_parallel = True
    Else
        is_parallel = False
    End If

End Function


Private Function normalize( _
    ByVal v As Variant) _
    As Variant

    Dim l As Double
    l = get_length( _
        vec_zero(), _
        v _
    )

    If l < EQUAL_TOLERANCE Then
        normalize = vec_zero()
        Exit Function
    End If

    Dim nml(2) As Double, i&
    For i = 0 To UBound(nml)
        nml(i) = v(i) / l
    Next

    normalize = nml

End Function


Private Function dot( _
    ByVal v1 As Variant, _
    ByVal v2 As Variant) _
    As Double

    dot = v1(0) * v2(0) + v1(1) * v2(1) + v1(2) * v2(2)
    
End Function


Private Function cross( _
    ByVal v1 As Variant, _
    ByVal v2 As Variant) _
    As Variant

    Dim vec(2) As Double
    vec(0) = v1(1) * v2(2) - v1(2) * v2(1)
    vec(1) = v1(2) * v2(0) - v1(0) * v2(2)
    vec(2) = v1(0) * v2(1) - v1(1) * v2(0)

    cross = vec

End Function


Private Function get_length( _
    ByVal p1 As Variant, _
    ByVal p2 As Variant) _
    As Double

    get_length = Math.Sqr(get_length_square(p1, p2))
End Function


Private Function get_length_square( _
    ByVal p1 As Variant, _
    ByVal p2 As Variant) _
    As Double

    get_length_square = _
        (p2(0) - p1(0)) * (p2(0) - p1(0)) + _
        (p2(1) - p1(1)) * (p2(1) - p1(1)) + _
        (p2(2) - p1(2)) * (p2(2) - p1(2))

End Function


Private Function vec_zero() _
    As Variant

    vec_zero = Array(0#, 0#, 0#)

End Function

長さ3の配列を三次元ベクトルに見立てています。ので危険です。

大まかにこちらの物を書き直して、ちょっと追加しただけです。
曲線と戦ってみる9 - C#ATIA