ssCAROのブログ

色んなとこで見つけたプログラムのメモ置き場っぽい

波線を描画したい(VB.net)

波線を描画したくなった。
作成はVisual Basic 2017で行った。

DrawLineを使って描いても良かったんだけど、もう少し効率の良い方法はないかと探してみて色々試した結果、DrawCurveを使うことにした。

等間隔で中央、上、中央、下、中央…という感じでy位置を変化させてPointに格納しDrawCurveで曲線を描画させた。

横線のみです。

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
    Dim g As Graphics = Graphics.FromImage(canvas)
    
    DrawWavyLine(g, Pens.Blue, 0, 200, 200)
    
    PictureBox1.Image = canvas
End Sub

'横の波線を描画
Public Sub DrawWavyLine(ByRef g As Graphics, ByRef pen As Pen, ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single)
    '--------------------
    '波線の設定
    '--------------------
    '波線の曲線(0.0 = 直線 ~ 1.0 = 曲線)
    Dim tension As Single = 1.0F
    '波線の幅
    Dim waveWidth As Single = 5.0F
    '波線の高さ
    Dim waveHeight As Single = 5.0F
    '--------------------
    Dim points As New List(Of PointF)
    Dim x As Single = 0F
    Dim y As Single = 0F
    Dim f As Integer = 0

    While x < (x2 - x1)
        Select Case f
            Case 0, 2
                y = 0F
            Case 1
                y = -waveHeight
            Case 3
                y = waveHeight
        End Select
        f = If(f < 3, f + 1, 0)

        points.Add(New PointF(x, y1 + y))

        x += waveWidth / 2.0F
    End While

    g.DrawCurve(pen, points.ToArray(), tension)
End Sub

f:id:ssCARO:20200701103403p:plain

斜めの波線の途中未完成!!

  • 横線を引き、そこに等間隔で縦線を引く
  • その横線を傾けたときの角度を求める
  • 縦線の上、中央、下の位置に対して角度を適応した位置を求める
  • 中央、上、中央、下、中央…の位置をPointに格納してDrawCurveに投げると…なんか上手くいかない!
Public Sub DrawWavyLine2(ByRef g As Graphics, ByRef pen As Pen, ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single)
    '--------------------
    '波線の設定
    '--------------------
    '波線の曲線(0.0 = 直線 ~ 1.0 = 曲線)
    Dim tension As Single = 0.0F
    '波線の幅
    Dim waveWidth As Single = 10.0F
    '波線の高さ
    Dim waveHeight As Single = 10.0F
    '--------------------
    Dim points As New List(Of PointF)
    Dim x As Single = 0F
    Dim y As Single = 0F
    Dim f As Integer = 0

    Dim wx1 As Single = 0F
    Dim wy1 As Single = 0F
    Dim wx2 As Single = 0F
    Dim wy2 As Single = 0F
    Dim wx3 As Single = 0F
    Dim wy3 As Single = 0F

    '2点間の角度
    Dim radian As Double = Math.Atan2(y2 - y1, x2 - x1)
    Dim cos As Double = Math.Cos(radian)
    Dim sin As Double = Math.Sin(radian)

    While (x1 + x) < x2
        '角度から座標を求める
        wx1 = x * cos - -waveHeight * sin
        wy1 = x * sin + -waveHeight * cos

        wx3 = x * cos - 0F * sin
        wy3 = x * sin + 0F * cos

        wx2 = x * cos - waveHeight * sin
        wy2 = x * sin + waveHeight * cos

        Select Case f
            Case 0, 2
                y = wy3
            Case 1
                y = wy1
            Case 3
                y = wy2
        End Select
        f = If(f < 3, f + 1, 0)

        points.Add(New PointF(x1 + x, y1 + y))

        x += waveWidth / 2.0F
    End While

    g.DrawCurve(pen, points.ToArray(), tension)
End Sub

参考URL
開発メモ:円周上の点
2点間の距離と角度と座標の求め方