Public Type POINT
x As Double
y As Double
End Type
Private Const N = 5&
'GaussJordan ガウス−ジョルダン法で連立方程式を解く
'詳しくはそのサンプルをご覧下さい
Private Function GaussJordan(value() As Double, _
count As Long) As Boolean
Dim a As Double
Dim i As Long, j As Long
Dim k As Long
Dim temp As Double
For i = 0& To count - 1&
a = value(i, i)
If Abs(a) < 1E-20 Then GaussJordan = False: Exit Function
For k = i To count
value(k, i) = value(k, i) / a
Next k
For j = 0& To count - 1&
If j <> i Then
temp = value(i, j)
For k = i To count
value(k, j) = value(k, j) - _
temp * value(k, i)
Next k
End If
Next j
Next i
GaussJordan = True
End Function
'与えられた点をすべて通る曲線を N 次数のスプライン的に描く
'N は奇数である必要あり、N = 3,5,7 ぐらいが適当です。
'Nが大きいほどより滑らかに描けます。
'果たしてこういう物がスプラインと言うのだろうか・・・
'pos() 点
'pCount 点の数
'sPic 描画先ピクチャボックス
'sx,ex 描画開始,終了位置
Public Function DrawCarveLine2(pos() As POINT, _
ByVal pCount As Long, _
ByVal sPic As Object, _
ByVal sx As Long, _
ByVal ex As Long)
Dim gj() As Double '連立方程式を解くための行列の値
Dim i As Long, j As Long, k As Long 'カウンタ
Dim y As Double '補間された値
Dim tempx As Long, tempy As Long '直線の始点保管
Dim hsx As Long, hex As Long '曲線を描く区間の始点と終点
ReDim gj(N + 1 - 1 + 1, N + 1 - 1) '[点の数]の正方行列
'座標スケールの定義
sPic.Scale (0, sPic.Height)-(sPic.Width, 0)
For k = N \ 2& To pCount - N \ 2& - 1& - 1&
'点のx,y値を連立方程式を解くための行列値にする
For j = 0& To N + 1& - 1&
For i = 0& To N + 1& - 1&
gj(i, j) = pos(j - N \ 2& + k).x ^ (N + 1& - 1& - i)
Next i
gj(N + 1, j) = pos(j - N \ 2& + k).y
Next j
'連立方程式を解く
If GaussJordan(gj, N + 1) = False Then Exit Function
tempx = 0&: tempy = 0&
hsx = pos(k).x
hex = pos(k + 1).x
If k = N \ 2& Then hsx = sx
If k = pCount - N \ 2& - 1& - 1& Then hex = ex
'連立方程式の解を使用して補間値を求め曲線を描く
For j = hsx To hex
y = 0#
For i = 0& To N + 1& - 1&
y = y + CDbl(j ^ (N + 1& - 1& - i)) * gj(N + 1, i)
Next i
If j <> hsx Then sPic.Line (tempx, tempy)-(j, CLng(y))
tempx = j: tempy = y
Next j
Next k
End Function
|