Module Module1

    Const PICWIDTH As Integer = 40
    Const PICHEIGHT As Integer = 40

    Sub fillPic(ByVal pic As Char(,), ByVal penColor As Char)
        For y As Integer = 0 To pic.GetUpperBound(0)
            For x As Integer = 0 To pic.GetUpperBound(0)
                pic(x, y) = penColor
            Next
        Next
    End Sub
    Sub displayPic(ByVal pic As Char(,))
        For y As Integer = 0 To pic.GetUpperBound(0)
            For x As Integer = 0 To pic.GetUpperBound(1)
                Console.Write(pic(x, y))
            Next
            Console.WriteLine()
        Next
        Console.ReadLine()
    End Sub
    Sub drawLine(ByVal pic As Char(,), ByVal penColor As Char, ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer)
        Dim x, y As Integer

        If x1 = x2 Then         ' Vertical Line
            ' We need to have a special case for a vertical line.
            ' 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.

            For y = y1 To y2
                pic(x1, y) = penColor
            Next

        ElseIf y1 = y2 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 = x1 To x2
                pic(x, y1) = penColor
            Next

        Else                    ' diagonal line

            ' Calculate the slope
            Dim m As Double = (y2 - y1) / (x2 - x1)

            ' For every x value on the line calculate the appropriate
            ' y value and display it on the line
            For x = x1 To x2
                ' The following comes from reorganizing the
                ' "point-slope" equation for a line, y-y1=m(x-x1), 
                ' where x1,y1 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 - x2) + y2)
                pic(x, y) = penColor
            Next

            ' For every y value on the line calculate the appropriate
            ' x value and display it on the line.
            For y = y1 To y2
                x = Math.Round((y - y2 + m * x2) / m)
                pic(x, y) = penColor
            Next
        End If

    End Sub

    ' Copy a portion of a picture and return a new picture with just that portion
    Function copy(ByVal pic As Char(,), ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) As Char(,)
        Dim newPic As Char(,) = New Char(height, width) {}

        For row As Integer = y To height
            For col As Integer = x To width
                newPic(row, col) = pic(y + row, x + col)
            Next
        Next
        Return newPic
    End Function

    ' Paste a copy of pic2 onto pic1 at a specific location
    Sub paste(ByVal pic1 As Char(,), ByVal pic2 As Char(,), ByVal x As Integer, ByVal y As Integer)

        For pic2row As Integer = 0 To pic2.GetUpperBound(0)
            For pic2col As Integer = 0 To pic2.GetUpperBound(1)
                pic1(pic2col + x, pic2row + y) = pic2(pic2col, pic2row)
            Next
        Next
    End Sub
    Sub Main()
        Dim pics As Char()(,) = New Char(10)(,) {}

        pics(0) = New Char(PICHEIGHT, PICWIDTH) {}

        fillPic(pics(0), ".")
        drawLine(pics(0), "1", 0, 0, PICWIDTH, 0)
        drawLine(pics(0), "2", 0, 0, PICWIDTH, 10)
        drawLine(pics(0), "3", 0, 0, PICWIDTH, 25)
        drawLine(pics(0), "4", 0, 0, PICWIDTH, PICHEIGHT)
        drawLine(pics(0), "5", 0, 0, 25, PICHEIGHT)
        drawLine(pics(0), "6", 0, 0, 10, PICHEIGHT)
        drawLine(pics(0), "7", 0, 0, 0, PICHEIGHT)

        displayPic(pics(0))

        pics(1) = New Char(10, 10) {}
        fillPic(pics(1), "*")

        displayPic(pics(1))

        pics(2) = copy(pics(0), 0, 0, 10, 10)
        displayPic(pics(2))

        pics(3) = New Char(40, 40) {}
        fillPic(pics(3), ".")
        'paste(pics(3), pics(1), 0, 0)
        'paste(pics(3), pics(2), 10, 0)
        'paste(pics(3), pics(2), 0, 10)
        'paste(pics(3), pics(1), 10, 10)


        paste(pics(3), pics(1), 5, 5)
        paste(pics(3), pics(2), 25, 5)
        paste(pics(3), pics(2), 5, 25)
        paste(pics(3), pics(1), 25, 25)


        displayPic(pics(3))
    End Sub

End Module