Public Class VectorViewer

    Private Const ONEDIVSQRT3 As Double = 0.57735026918962573

    Public Property Xmax() As Single
        Get
            Return xMaxValue
        End Get
        Set(ByVal value As Single)
            xMaxValue = value
        End Set
    End Property
    Private xMaxValue As Single

    Public Property Xmin() As Single
        Get
            Return xMinValue
        End Get
        Set(ByVal value As Single)
            xMinValue = value
        End Set
    End Property
    Private xMinValue As Single

    Public Property Ymax() As Single
        Get
            Return yMaxValue
        End Get
        Set(ByVal value As Single)
            yMaxValue = value
        End Set
    End Property
    Private yMaxValue As Single

    Public Property Ymin() As Single
        Get
            Return yMinValue
        End Get
        Set(ByVal value As Single)
            yMinValue = value
        End Set
    End Property
    Private yMinValue As Single

    Public Vectors() As Vector
    
    Public Alpha As Single

    Public Class Vector
        Public Property X1() As Single
            Get
                Return x1Value
            End Get
            Set(ByVal value As Single)
                x1Value = value
            End Set
        End Property
        Private x1Value As Single

        Public Property X2() As Single
            Get
                Return x2Value
            End Get
            Set(ByVal value As Single)
                x2Value = value
            End Set
        End Property
        Private x2Value As Single

        Public Property Y1() As Single
            Get
                Return y1Value
            End Get
            Set(ByVal value As Single)
                y1Value = value
            End Set
        End Property
        Private y1Value As Single

        Public Property Y2() As Single
            Get
                Return y2Value
            End Get
            Set(ByVal value As Single)
                y2Value = value
            End Set
        End Property
        Private y2Value As Single

        Public Property Pen() As Pen
            Get
                Return penValue
            End Get
            Set(ByVal value As Pen)
                penValue = value
            End Set
        End Property
        Private penValue As Pen

        Public Sub New(ByVal x1, ByVal y1, ByVal x2, ByVal y2, ByVal pen)
            x1Value = x1
            y1Value = y1
            x2Value = x2
            y2Value = y2
            penValue = pen
        End Sub
    End Class

    Private vectorPen As New Pen(Color.Blue, 1)
    Private axisPenEnabled As New Pen(Color.Black, 1)
    Private axisPenDisabled As New Pen(Color.LightGray, 1)

    Private drawFont As New Font("Arial", 12)
    Private drawBrushEnabled As New SolidBrush(Color.Black)
    Private drawBrushDisabled As New SolidBrush(Color.LightGray)

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        Dim axispen As Pen
        Dim drawbrush As Brush
        If Me.Enabled Then
            axispen = axisPenEnabled
            drawbrush = drawBrushEnabled
        Else
            axispen = axisPenDisabled
            drawbrush = drawBrushDisabled
        End If

        Dim scaleX As Single = Me.Width / (Xmax - Xmin)
        Dim scaleY As Single = Me.Height / (Ymax - Ymin)

        ' Draw horizontal axis
        e.Graphics.DrawLine(axisPen, 0, CSng(Me.Height / 2), Me.Width, CSng(Me.Height / 2))

        ' Draw vertical axis
        e.Graphics.DrawLine(axisPen, CSng(Me.Width / 2), 0, CSng(Me.Width / 2), Me.Height)

        ' Draw text
        e.Graphics.DrawString(Xmin, drawFont, drawBrush, 0, Me.Height / 2)
        e.Graphics.DrawString(Xmax, drawFont, drawBrush, Me.Width - 20, Me.Height / 2)
        e.Graphics.DrawString(Ymin, drawFont, drawBrush, Me.Width / 2 + 5, Me.Height - 15)
        e.Graphics.DrawString(Ymax, drawFont, drawBrush, Me.Width / 2 + 5, 0)

        If Not Me.Enabled Then Exit Sub

        Dim _x1, _y1, _x2, _y2 As Integer

        If Vectors IsNot Nothing Then
            For i As Integer = 0 To Vectors.Length - 1
                _x1 = (Vectors(i).X1 - Xmin) * scaleX
                _y1 = Me.Height - (Vectors(i).Y1 - Ymin) * scaleY   'Y-direction is reversed
                _x2 = (Vectors(i).X2 - Xmin) * scaleX
                _y2 = Me.Height - (Vectors(i).Y2 - Ymin) * scaleY   'Y-direction is reversed
                e.Graphics.DrawLine(Vectors(i).Pen, _x1, _y1, _x2, _y2)
            Next
        End If

        _x1 = -Xmin * scaleX
        _y1 = Me.Height + Ymin * scaleY   'Y-direction is reversed
        _x2 = (Xmax * Math.Cos(Alpha) - Xmin) * scaleX
        _y2 = Me.Height - (Ymax * Math.Sin(Alpha) - Ymin) * scaleY
        e.Graphics.DrawLine(Pens.Green, _x1, _y1, _x2, _y2)

        'e.Graphics.DrawString(Fix(Rad2Deg(Alpha)), drawFont, drawBrush, Me.Width / 2, Me.Height / 2)
    End Sub
End Class


