C#ATIA

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

ボディの体積をダンプする4

こちらの続きです。
ボディの体積をダンプする3 - C#ATIA

ソート関数等って恐らくVBA自体には無いですよね・・・。
ExcelのRangeであればメソッドがあるようですが、純粋なVBAには無さそう。

アルゴリズムの勉強と言う意味では、ソートを自作するのも
少しだけ意味が有りそうな気もしますが、昨今のプログラミング言語
場合は、標準で実装されていると思いますし、そこに時間を
使うのも無意味な気もするのですが・・・。


時間の確保が難しく、先人の知恵をお借りしました。

こちらは配列内の数値をソートしてダンプします。
挿入ソートはこちらからお借りして、少々変更しました。
1次元配列の並べ替え(バブルソート,挿入ソート,クイックソート)|VBAサンプル集

'vba

Option Explicit

Sub CATMain()

    Dim ary As Variant
    ary = Array(5, 10, 2, 1, 15)
    
    dump_array ary, "** ソート前 **"
    
    'ソート実行
    insertion_sort ary
    
    dump_array ary, "** ソート後 **"
    
End Sub


'https://excel-ubara.com/excelvba5/EXCELVBA228.html
Private Sub insertion_sort( _
    ByRef argAry As Variant)

    Dim low As Long
    low = LBound(argAry)
    
    Dim upp As Long
    upp = UBound(argAry)

    Dim i As Long, j As Long
    Dim vSwap As Variant
    For i = low + 1 To upp
        vSwap = argAry(i)
        For j = i - 1 To low Step -1
            If argAry(j) > vSwap Then
                argAry(j + 1) = argAry(j)
            Else
                Exit For
            End If
        Next
        argAry(j + 1) = vSwap
    Next
End Sub


Private Sub dump_array( _
    ByVal ary As Variant, _
    Optional ByVal title As String = "")

    If Len(title) > 0 Then
        dump title
    End If
    
    Dim low As Long
    low = LBound(ary)
    
    Dim upp As Long
    upp = UBound(ary)

    Dim i As Long
    For i = low To upp
        dump Str(ary(i))
    Next
End Sub


Private Sub dump( _
    ByVal msg As String)
    
    Debug.Print msg
End Sub

元々の挿入ソートが破壊的だったため、そのままにしましたが
個人的にはあまり好きじゃないですね。

実行結果はこんな感じです。

** ソート前 **
 5
 10
 2
 1
 15
** ソート後 **
 1
 2
 5
 10
 15

問題はタイトルに"ボディの体積"って書いてるくせに、ちっとも体積じゃない
って事です。

当然、ボディの配列をinsertion_sort関数に渡しても、体積でソートしてくれません。
(恐らくエラーになると思う)
insertion_sort関数内で体積を取得する処理を追記して、体積同士で比較するように
すれば体積でソート出来るでしょう。

しかし、前回Fusion360で試したように、体積ではなく表面積でソートしたい場合、
insertion_sort_by_area関数を用意する必要が出てきます。
これが、重心位置と原点の距離とか複数のマテリアルが使用されているボディ群から
重量で、等になった場合、その都度ソート関数を用意するのは面倒ですよね?

こういった場合、VBAではどうやるのが正攻法なのかな?
(その都度、ソート関数作るのが正攻法のような気はしていますが)