こちらの続きです。
曲線と戦ってみる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は試したくないです・・・。