ホーム ] 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 / グラフィックス系

G0103 曲線の接線・法線

最終更新:2006/11/12 新規

●解説 

 自由曲線の始点から辿ってある距離の点における、接線角度(方向)と法線角度(方向)を求める。方向の意味は、ベクトルとしての角度のこと。この例では、進行方向の左側に法線を立てるとしている。

 上図で、接線の角度はB,法線の角度はAとなる。Graphics上は、水平左が0度となり、時計周りが正の方向(角度)となる。

●原理 

 求める点については、G0102 曲線長を測るを参照方。

 法線角度は接線角度を求めれば、B + 270度あるいは、B - 90度とすれば良い。 

●方法 

接線角度は以下のように求める。 

  1. 求める点を見つける。(G0102 曲線長を測るを参照)

  2. その点が、

  • 元々の曲線上の点である:その点の前後の二点による傾きとする

  • 補間された点である:補間に使用した二点による傾きとする

角度はtan-1を使用する。しかし、この関数の周期はπ(180度)であるが、求める角度は360度周期なので、方向により角度の調整を行う必要がある。傾きを計算する二点をPa(前点)、Pb(後点)とすれば、 

dx = Pb(X) - Pa(X)
      dy = Pb(Y) - Pa(Y)
      B = tan-1(dy/dx) 

ここで、

dx >= 0 なら、
       
 そのまま
      dx < 0 なら
       
 B = B + π

とする。 

●実例 

関数の形での例。

Poは曲線のPoint配列、cl()は既に作成された距離テーブル。
距離Lを指定すると、対応する点X、Yとその点の法線角度A(度)を返す。 

Public Sub GetCurveParam(ByVal po() As PointF, ByVal cl() As Single, ByVal L As Single, ByRef X As Single, ByRef Y As Single, ByRef A As Single)

        Dim i, k As Integer
        Dim c As Integer = po.Length
        Dim pa As New PointF(0.0F, 0.0F)
        Dim pb As New PointF(0.0F, 0.0F)
        pb = po(c - 1)
        pa = po(c - 2)
        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
                If i < c - 1 Then
                    pa = po(i - 1)
                    pb = po(i + 1)
                Else
                    pa = po(i - 1)
                    pb = po(i)
                End If
                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
                pa = po(i - 1)
                pb = po(i)
                Exit For
            End If
        Next
        Dim dy, dx As Single
        dy = pb.Y - pa.Y : dx = pb.X - pa.X
        If dx >= 0 Then
            A = Atan(dy / dx)
        Else
            A = Atan(dy / dx) + PI
        End If
        A = A * 180.0F / PI + 270.0F
    End Sub