C#ATIA

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

曲線と戦ってみる7

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


一本の曲線を近似化するだけなので、あまりスピードには
こだわるつもりは無かったのですが、コードが荒れない程度であれば
高速化したいので、テスト用コードを作成。

こちらのType1のコードを見ると、y4yamaさんも曲線上の点自体が
欲しかったのではなく、点の座標値が欲しかった様で、点を
削除するコードがコメント化されて残っています。
曲線と戦ってみる1 - C#ATIA


僕自身も座標値のみが欲しいので、曲線上の点自体は削除する
部分まで含めたテストコードにし、時間を測定出来るようにしました。

'vba 曲線上の座標値取得テスト
Private Const mPntCount = 100&          '曲線上のポイント数
Private Const mIndexMax = mPntCount - 1 '配列用のインデックス最大値

Sub CATMain()
    '曲線選択
    Dim Msg$: Msg = "曲線を選択して下さい : ESCキー 終了"
    Dim SelElem As SelectedElement
    Set SelElem = KCL.SelectElement(Msg, Array("HybridShape"))
    If KCL.IsNothing(SelElem) Then Exit Sub
    Dim CurveRef As Reference: Set CurveRef = SelElem.Reference
        
    '各種設定
    Dim Doc As PartDocument: Set Doc = KCL.GetParent_Of_T(CurveRef, "PartDocument")
    
    'TestAかBかCをコメント化
    Dim Dmy As Variant, i&
    Debug.Print "*** " + CStr(mPntCount) + "個 ***"
    For i = 1 To 5
        KCL.SW_Start
        Dmy = TestA(Doc.Part, CurveRef)
        'Dmy = TestB(Doc.Part, CurveRef)
        'Dmy = TestC(Doc.Part, CurveRef)
        Debug.Print CStr(i) + "回目 : " + CStr(KCL.SW_GetTime) + "秒"
    Next
    '終了
    MsgBox "end"
End Sub


'曲線上の毎回点を作成し座標を取得
Private Function TestA(ByVal Pt As Part, ByVal CurveRef As Reference) As Variant
    Dim Fact As HybridShapeFactory: Set Fact = Pt.HybridShapeFactory
    Dim Poss() As Variant: ReDim Poss(mIndexMax)
    Dim i&, Ratio#, Pnt As Variant, P(2) As Variant
    
    For i = 0 To mIndexMax
        Ratio = i / mIndexMax
        Set Pnt = Fact.AddNewPointOnCurveFromPercent(CurveRef, Ratio, False)
        Call Pt.UpdateObject(Pnt)
        Call Pnt.GetCoordinates(P)
        Poss(i) = P
        Call Fact.DeleteObjectForDatum(Pnt)
    Next
    
    TestA = Poss
End Function

'曲線上の1点を作成しUpdateで座標を取得
Private Function TestB(ByVal Pt As Part, ByVal CurveRef As Reference) As Variant
    Dim Fact As HybridShapeFactory: Set Fact = Pt.HybridShapeFactory
    Dim Pnt As Variant
    Set Pnt = Fact.AddNewPointOnCurveFromPercent(CurveRef, 0#, False)
    Dim Ratio As RealParam
    Set Ratio = Pnt.Ratio
    
    Dim i&, P(2) As Variant
    Dim Poss() As Variant: ReDim Poss(mIndexMax)
    For i = 0 To mIndexMax
        Ratio.Value = i / mIndexMax
        Call Pt.UpdateObject(Pnt)
        Call Pnt.GetCoordinates(P)
        Poss(i) = P
    Next
    Call Fact.DeleteObjectForDatum(Pnt)
    
    TestB = Poss
End Function

'曲線上の1点を作成しUpdateで座標を取得 除算減らした
Private Function TestC(ByVal Pt As Part, ByVal CurveRef As Reference) As Variant
    Dim Fact As HybridShapeFactory: Set Fact = Pt.HybridShapeFactory
    Dim Pnt As Variant
    Set Pnt = Fact.AddNewPointOnCurveFromPercent(CurveRef, 0#, False)
    Dim Ratio As RealParam
    Set Ratio = Pnt.Ratio
    Dim Unit#: Unit = 1 / mIndexMax
    
    Dim i&, P(2) As Variant
    Dim Poss() As Variant: ReDim Poss(mIndexMax)
    For i = 0 To mIndexMax
        Ratio.Value = Unit * i
        Call Pt.UpdateObject(Pnt)
        Call Pnt.GetCoordinates(P)
        Poss(i) = P
    Next
    Call Fact.DeleteObjectForDatum(Pnt)
    
    TestC = Poss
End Function

こちらのKCLが必要です。(Ver0.05に変更しています)
http://kantoku.hatenablog.com/entry/2016/06/21/111410

TestA~Cに変更し、mPntCount定数を変更して時間を測定しました。
各テストの違いは
・TestA-1点毎に点を作成し、座標値取得後に点を削除
・TestB-1点だけ点を作成し、比率を変更しながら座標値を取得
・TestC-基本的にTestBと同じ。四則演算では除算がコスト高なので減らした

100個の結果はこちら。

TestA
*** 100個 ***
1回目 : 0.375秒
2回目 : 0.343秒
3回目 : 0.361秒
4回目 : 0.343秒
5回目 : 0.344秒

TestB
*** 100個 ***
1回目 : 0.125秒
2回目 : 0.125秒
3回目 : 0.125秒
4回目 : 0.125秒
5回目 : 0.125秒

TestC
*** 100個 ***
1回目 : 0.14秒
2回目 : 0.125秒
3回目 : 0.125秒
4回目 : 0.125秒
5回目 : 0.125秒

TestB・Cは大差無いです。1回目が遅いのは代入一回分の時間でしょう。



1000個の結果はこちら。

TestA
*** 1000個 ***
1回目 : 3.541秒
2回目 : 3.51秒
3回目 : 3.541秒
4回目 : 3.59秒
5回目 : 3.545秒

TestB
*** 1000個 ***
1回目 : 1.201秒
2回目 : 1.185秒
3回目 : 1.204秒
4回目 : 1.186秒
5回目 : 1.201秒

TestC
*** 1000個 ***
1回目 : 1.248秒
2回目 : 1.188秒
3回目 : 1.185秒
4回目 : 1.186秒
5回目 : 1.185秒

こちらでもTestB・Cは大差無いです。


10000個の結果はこちら。

TestA
*** 10000個 ***
1回目 : 35.569秒
2回目 : 36.226秒
3回目 : 35.886秒
4回目 : 35.311秒
5回目 : 34.765秒

TestB
*** 10000個 ***
1回目 : 12.186秒
2回目 : 11.78秒
3回目 : 12.065秒
4回目 : 12.124秒
5回目 : 12.841秒

TestC
*** 10000個 ***
1回目 : 12.09秒
2回目 : 11.75秒
3回目 : 11.783秒
4回目 : 11.686秒
5回目 : 11.735秒

この程度では除算の差はあまり出ないんですね。
もうこれ以上の数では、TestAは試したくないです・・・。