ホーム ] TIPS ウィンドウズ系 ] TIPS グラフィックス系 ] TIPS メルチメディア系 ] TIPS 理数系 ] TIPS 総覧 ]

上へ
G0001 色名一覧
G0002 アルファブレンド
G0003 カラーマップを作る
G0101 曲線の数値化
G0102 曲線長を測る
G0103 曲線の接線・法線
G0104 曲線のスムージング
G0201 図形の回転
G0202 領域の認識
G0301 文字の線形変換
G0302 文字の自由変形
G0303 文字の極座標変換
G0304 曲線に沿った文字列
G0305 飾文字-中抜き
G0306 飾文字-縁取り
G0307 飾文字-ドロップダウンシャドウ
G0501 画像の線形変換
G0502 画像の透明化
G0503 画像の任意形状切出し
G0504 画像の回転
G0505 画像の高速処理化

VB.NET2005 TIPS / グラフィックス系

G0102 曲線長を測る

最終更新:2006/11/12 再掲

●解説 

 任意の自由曲線(XやYが単調増加である制限はない)の線長を計測する。また、線長を変数として対応する座標を求められるようにする。これができると、曲線を等間隔に区切ったり、またその点での接線、法線が求められるような曲線の追跡ができる。 

●原理 

 曲線はPoint配列なので、隣接するPointの距離を求めることに他ならない。また配列は既にスプライン補間された曲線を十分に反映して折線近似していると仮定する。G0101 曲線の数値化参照。

上図で、二点間の微小距離ΔLは、 

ΔL = Sqrt(ΔX2 + ΔY2)
        = Sqrt((Xi - Xi-1) 2 + (Yi-Yi-1) 2

で求められる。これを元に、始点から辿って指定の距離にある点Pの座標を見つける関数にする。

 

●方法 

曲線のPoint配列に対応した距離テーブルを作成する。
任意の距離の点を求めるため線形一次補間を行う。

 距離Lと距離テーブル比較(始点は飛ばす)し、

  • 同じ:点が求まった

  • Lが小さい:この点と前の点で補間し、X,Yを求める

  • Lが大きい:次の点に移る

●実例 

距離テーブルは最初に一回だけ作成するのが良いので、独立した関数にした例。

Poは曲線のPoint配列、cl()は距離テーブル 

   Public Sub MeasureCurveLength(ByVal po() As PointF, ByRef cl() As Single)
        Dim i As Integer
        Dim dL As Double
        Dim c As Integer = po.Length
        ReDim cl(c - 1)
        cl(0) = 0.0F
        For i = 1 To c - 1
            dL = Sqrt((po(i).X - po(i - 1).X) ^ 2 + (po(i).Y - po(i - 1).Y) ^ 2)
            cl(i) = cl(i - 1) + dL
        Next
    End Sub
 

以下は、距離Lに対応する点を見つけるコード例

Poは曲線のPoint配列、cl()は距離テーブル 

        Dim i As Integer
        Dim c As Integer = po.Length
        X = po(c - 1).X
        Y = po(c - 1).Y               
見つからなかった時の返す座標値(終点)
        For i = 1 To c - 1
            If L = cl(i) Then
                X = po(i).X
                Y = po(i).Y
                Exit For
            ElseIf L < cl(i) Then                              '線形一次補間する
                Dim r As Single = (L - cl(i - 1)) / (cl(i) - cl(i - 1))
                X = (po(i).X - po(i - 1).X) * r + po(i - 1).X
                Y = (po(i).Y - po(i - 1).Y) * r + po(i - 1).Y
                Exit For
            End If
        Next