Public Class Line

    Private p1Value, p2Value As Point
    Private color As Char

    Public Sub New(ByVal p1 As Point, ByVal p2 As Point, ByVal c As Char)
        color = c
        p1Value = p1
        p2Value = p2
    End Sub

    Public Sub draw(ByVal c As Canvas)

        ' The points for the line are stored in leftPoint and rightPoint. We
        ' guaranteed in the constructor (i.e. SUB NEW) that the leftPoint will be to the 
        ' left (i.e. lower value for x) of the right point (i.e. higher value for x).
        ' We will also need to know later which point is physically higher when drawn
        ' on the screen (i.e. lower value for y) and which is physically lower (i.e. 
        ' higher value for y). We use the following variables for that:
        Dim leftPoint, rightPoint As Point
        If p1Value.x < p2Value.x Then
            leftPoint = p1Value
            rightPoint = p2Value
        Else
            leftPoint = p2Value
            rightPoint = p1Value
        End If

        Dim higherPoint, lowerPoint As Point
        If p1Value.y < p2Value.y Then
            higherPoint = p1Value
            lowerPoint = p2Value
        Else
            higherPoint = p2Value
            lowerPoint = p1Value
        End If

        ' We need to have special cases for a vertical and horizontal lines.
        ' The reason we need to treat a vertical line differently
        ' is that the slope of a vertical line is undefined since you
        ' would have to divide by zero when calculating the slope.
        ' In mathematics (and in computer programming) it is 
        ' an ERROR to divide by zero.
        '
        ' We need a special case for horizontal lines for similar reasons (see code below)

        If higherPoint.x = lowerPoint.x Then         ' Vertical Line

            For y As Integer = higherPoint.y To lowerPoint.y
                c.info(higherPoint.x, y) = color
            Next

        ElseIf leftPoint.y = rightPoint.y Then     'Horizontal Line
            ' The following is a special case for a horizontal line.
            '
            ' In a strict mathematical sense we don't need to treat
            ' horizontal lines as a special case. However, our algorithm
            ' below will cause a division by zero error for horizontal 
            ' lines too.
            For x As Integer = leftPoint.x To rightPoint.x
                c.info(x, leftPoint.y) = color
            Next

        Else                    ' diagonal line

            ' Calculate the slope
            Dim m As Double = (p2Value.y - p1Value.y) / (p2Value.x - p1Value.x)
            Dim x, y As Integer

            ' For every x value on the line calculate the appropriate
            ' y value and display it on the line
            For x = p1Value.x To p2Value.x
                ' The following comes from reorganizing the
                ' "point-slope" equation for a line, y-p1.y=m(x-p1.x), 
                ' where p1.x,p1.y is a SPECIFIC point, x is a "free variable" - 
                ' i.e. x can take on any value and y is the value that
                ' is calculated from the specific value for x that 
                ' is chosen
                y = Math.Round(m * (x - p2Value.x) + p2Value.y)
                c.info(x, y) = color
            Next

            ' For every y value on the line calculate the appropriate
            ' x value and display it on the line.
            For y = p1Value.y To p2Value.y
                x = Math.Round((y - p2Value.y + m * p2Value.x) / m)
                c.info(x, y) = color
            Next
        End If
    End Sub

End Class