Mostrando postagens com marcador triângulo. Mostrar todas as postagens
Mostrando postagens com marcador triângulo. Mostrar todas as postagens

domingo, 11 de março de 2018

Project Euler 18

No problema 18 do Project Euler, a proposta é encontrar o caminho com a maior soma partindo-se do topo de um triângulo de números. Só são permitidos caminhos que passem pelos números adjacentes da camada (ou linha) seguinte do triângulo. Assim, a proposta é essa, de todos os caminhos possíveis encontrar aquele cuja soma seja a maior.



Na implementação, escolheu-se a abordagem bottom-up, aplicando a seguinte ideia.
Observe esse triângulo de exemplo, formado pelas primeiras 4 linhas do triângulo proposto.
Soma-se os adjacentes da camada inferior (bottom) com o número da camada de cima (up) e, dessa forma, os valores dos números da camada de cima são substituídos pelo maior valor dessas somas. Por exemplo, da camada inferior (bottom) temos os números 18 e 35, adjacentes do número 17 da camada de cima (up). A maior soma é dos números 35+17, assim o valor 52 é o que será armazenado. Ao final, a camada de cima (up) será atualizada e ficará com os seguintes valores.

Repetindo-se esse algoritmo, a segunda linha ficaria como abaixo, sendo o resultado final, ao ser efetuada a soma com a primeira linha, o valor 304.

Aplicando-se ao triângulo inteiro proposto, a implementação ficou assim:
$tri = @((75),(95,64),(17,47,82),(18,35,87,10),(20,04,82,47,65),(19,01,23,75,03,34),(88,02,77,73,07,63,67),(99,65,04,28,06,16,70,92),(41,41,26,56,83,40,80,70,33),(41,48,72,33,47,32,37,16,94,29),(53,71,44,65,25,43,91,52,97,51,14),(70,11,33,28,77,73,17,78,39,68,17,57),(91,71,52,38,17,14,91,43,58,50,27,29,48),(63,66,04,68,89,53,67,30,73,16,69,87,40,31),(04,62,98,27,23,09,70,98,73,93,38,53,60,04,23))
$bottom = @()
$up = @()
$max = 0

For ($li=(($tri.Length)-1); $li -gt 0; $li--) {
    $bottom = $tri[$li]
    $up = $tri[($li-1)]
    For ($i=1; $i -lt (($tri[$li].Length)-1); $i++) {
        If (($bottom[$i]+$up[$i]) -gt ($bottom[$i+1]+$up[$i])) {
            $up[$i] = ($bottom[$i]+$up[$i])
        }
        Else {
            $up[$i] = ($bottom[$i+1]+$up[$i])
        }
    }
}

If (($bottom[0]+$up[0]) -gt ($bottom[1]+$up[0])) {
     $max = ($bottom[0]+$up[0])
}
Else {
     $max = ($bottom[1]+$up[0])
}

Write-Host "Project Euler 18. Valor Máximo:"$max

Project Euler 18. Valor Máximo: 1074

sábado, 17 de fevereiro de 2018

Project Euler 15

Em Project Euler, o problema 15 propõe encontrar o número de caminhos possíveis em uma grade 20x20. Como exemplo, uma figura representando as rotas em uma grade 2x2 é exibida:



Observando a grade 2x2, para chegarmos ao destino (2,2), temos em cada ponto a possibilidade de ir para a direita (D) ou para baixo (B), ou seja, há 2 possíveis caminhos, que são percorridos para a direita um X número de vezes e, para baixo, um Y número de vezes. Todas as rotas terão X+Y passos.
O problema pode ser resolvido de diversas maneiras, mas acredito que todas relacionadas com Binomial Coefficient. Dentro desse contexto, escolhemos a implementação através do Triângulo de Pascal, onde cada número é obtido da soma dos números anteriores que estão à esquerda e acima. Observa-se uma analogia ao problema, pois montando uma grade preenchida com os números do Triângulo de Pascal, a coordenada final sempre indicará o número de caminhos possíveis, como ilustra a figura abaixo.

Cada número alocado em uma coordenada da grade é igual a soma dos números das coordenadas imediatamente à esquerda e acima. Assim, o 6 é a soma 3+3. O 20, a soma 10+10. O 70, a soma 35+35. O 6 representa o número de caminhos possíveis em uma grade 2x2, pois está na coordenada (2,2). O 20 representa o número de caminhos possíveis em uma grade 3x3, pois está na coordenada (3,3). O 70 representa o número de caminhos possíveis em uma grade 4x4, pois está na coordenada (4,4).

Dessa forma, bastaria criar um programa que criasse a grade 20x20 correspondente, preenchendo o valor de cada coordenada. O valor da coordenada (20,20) será a resposta do problema.
$tam = 20
$tam_matriz = $tam + 1 
## Matriz deve ser somada de 1 para o triangulo de Pascal
$path = New-Object 'object[,]' $tam_matriz,$tam_matriz

For ([int]$x=0; $x -lt $tam_matriz; $x++) {
    For ([int]$y=0; $y -lt $tam_matriz; $y++) {
        If ($x -eq 0) { $path[0,$y] = 1 }
        If ($y -eq 0) { $path[$x,0] = 1 }
        If (($x -gt 0) -and ($y -gt 0)) {
            $path[$x,$y] = $path[($x-1),$y] + $path[$x,($y-1)]
        }
    }
}
Clear-Host
Write-Host "O número de caminhos possíveis, obtido pelo triângulo de Pascal"
Write-Host "para uma matriz 20x20, foi:" $path[($tam),($tam)

O número de caminhos possíveis, obtido pelo triângulo de Pascal
para uma matriz 20x20, foi: 137846528820

sábado, 28 de outubro de 2017

Desenhando com Pixels - parte 2

Na parte 1 de Desenhando com Pixels, criou-se funções para o desenho de pontos, retas, triângulos e quadrados. Ainda, naquele código usou-se o artifício de carregar um bitmap de fundo.

Agora, vamos acrescentar novas funções, como o desenho de círculos, bem como o desenho de figuras geométricas com preenchimento. Para o desenho dessa característica, usaremos o que foi aprendido no post sobre recursividade, ou seja, o preenchimento de uma figura pode ser obtido através de chamadas recursivas à própria função de desenho.

Na plotagem, criamos um novo atributo "espessura", possibilitando a geração de pontos maiores e, como todas as demais figuras são baseadas em pontos, a consequente geração de retas, quadrados, triângulos e círculos mais espessos.

Outra melhoria foi a alteração no modo de compor o fundo de desenho, sem a necessidade da carga de um bitmap gerado externamente, seja de um arquivo ou de uma string base64. Agora, o fundo foi implementado assim:
$img = New-Object System.Drawing.Bitmap($form.Width, $form.Height)
$form.BackgroundImage = $img
$form.BackgroundImageLayout = "None"


A implementação completa é demonstrada abaixo:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
##########################################################
Function plot([Int32]$x, [Int32] $y, [String] $cor, [Int32] $espessura) {
    for ([Int32]$ey=0;$ey -le $espessura;$ey++) {
        for ([Int32]$ex=0;$ex -le $espessura;$ex++) {
             $img.SetPixel($x+$ex, $y+$ey, $cor)
        }
    }
}
##########################################################
Function retaBresenham ([Int32]$x1, [Int32]$y1, [Int32]$x2, [Int32]$y2, [String]$cor, [Int32]$espessura) {
    [Int32] $dx = $x2 - $x1
    [Int32] $dy = $y2 - $y1
    [Int32] $stepx, $stepy

    if ($dy -lt 0) { 
        $dy = -$dy 
        $stepy = -1
    }
    else { $stepy = 1 }

    if ($dx -lt 0) { 
        $dx = -$dx 
        $stepx = -1
    }
    else { $stepx = 1 }

    $dy = $dy -shl 1
    $dx = $dx -shl 1

    plot $x1 $y1 $cor $espessura

    if ($dx -gt $dy) {
        [Int32] $fraction = $dy - ($dx -shr 1)
        while ($x1 -ne $x2) {
            if ($fraction -ge 0) {
                $y1 += $stepy
                $fraction -= $dx
            }
            $x1 += $stepx
            $fraction += $dy
            plot $x1 $y1 $cor $espessura
        }
    }
    else {
        [Int32] $fraction = $dx - ($dy -shr 1)
        while ($y1 -ne $y2) {
            if ($fraction -ge 0) {
                $x1 += $stepx
                $fraction -= $dy
            }
            $y1 += $stepy
            $fraction += $dx
            plot $x1 $y1 $cor $espessura
        }
    }
    
}

##########################################################
Function triangulo([Int32]$x1, [Int32]$y1, [Int32]$h, [String]$cor, [Int32]$espessura) {
    [Int32] $lado = ([math]::Sqrt(4*$h*$h/3))
    retaBresenham $x1 $y1 ($x1-($lado/2)) ($y1+$h) $cor $espessura
    retaBresenham $x1 $y1 ($x1+($lado/2)) ($y1+$h) $cor $espessura
    retaBresenham ($x1-($lado/2)) ($y1+$h) ($x1+($lado/2)) ($y1+$h) $cor $espessura
}

##########################################################
Function trianguloSolido([Int32]$x1, [Int32]$y1, [Int32]$h, [String]$cor) {
    ## Caso Base - Triângulo mínimo alcançado
    if ($h -lt 3) {
        triangulo $x1 $y1 $h $cor 2 
        return 
    }
    triangulo $x1 $y1 $h $cor 2
    return trianguloSolido $x1 ($y1+3) ($h-6) $cor
}

##########################################################
Function quadrado([Int32]$x1, [Int32]$y1, [Int32]$tam, [String]$cor, [Int32]$espessura) {
    retaBresenham $x1 $y1 ($x1+$tam) $y1 $cor $espessura
    retaBresenham $x1 $y1 $x1 ($y1+$tam) $cor $espessura
    retaBresenham $x1 ($y1+$tam) ($x1+$tam) ($y1+$tam) $cor $espessura
    retaBresenham ($x1+$tam) $y1 ($x1+$tam) ($y1+$tam) $cor $espessura
}

##########################################################
Function quadradoSolido([Int32]$x1, [Int32]$y1, [Int32]$tam, [String]$cor) {
    ## Caso Base - Quadrado mínimo alcançado
    if ($tam -lt 5) {
        quadrado $x1 $y1 $tam $cor 5
        return 
    }
    quadrado $x1 $y1 $tam $cor 5
    return quadradoSolido ($x1+5) ($y1+5) ($tam-10) $cor
}

##########################################################
Function circuloSolido([Int32]$xC, [Int32]$yC, [Int32]$r, [String]$cor) {
    ## Caso Base - Quadrado mínimo alcançado
    if ($r -lt 5) {
        plot $xC $yC $cor 5
        return
    }
    circulo $xC $yC $r $cor 5
    return circuloSolido $xC $yC ($r-5) $cor
}

##########################################################
Function circulo([Int32]$xC, [Int32]$yC, [Int32]$r, [String]$cor, [Int32]$espessura) {
    [Int32] $x = 0
    [Int32] $y = $r
    [Int32] $u = 1
    [Int32] $v = 2*$r-1
    [Int32] $E = 0

    while ($x -lt $y) {
        plot ($xC + $x) ($yC + $y) $cor $espessura ## NNE
        plot ($xC + $y) ($yC - $x) $cor $espessura ## ESE
        plot ($xC - $x) ($yC - $y) $cor $espessura ## SSW
        plot ($xC - $y) ($yC + $x) $cor $espessura ## WNW
        $x++
        $E += $u
        $u += 2
        if ($v -lt (2*$E)) {
            $y--
            $E -= $v
            $v -= 2
        }
        if ($x -gt $y) { return }
        plot ($xC + $y) ($yC + $x) $cor $espessura ## ENE
        plot ($xC + $x) ($yC - $y) $cor $espessura ## SSE
        plot ($xC - $y) ($yC - $x) $cor $espessura ## WSW
        plot ($xC - $x) ($yC + $y) $cor $espessura ## NNW
    }
}


Function bmpRefresh([System.Drawing.Bitmap]$img){
    $formGraphics.DrawImage($img,0,0,$img.Width,$img.Height)    
}

##########################################################
[Windows.Forms.Application]::EnableVisualStyles()
$form = New-Object Windows.Forms.Form
$form.Width = 600;
$form.Height = 480;
$img = New-Object System.Drawing.Bitmap($form.Width, $form.Height)
$form.BackgroundImage = $img
$form.BackgroundImageLayout = "None"
$formGraphics = $form.CreateGraphics()

$form.Add_Shown({

        ### Pontos
        for ([Int32]$x=30;$x -lt 55;$x+=5) {
            plot $x 50 'Red' 0
            plot $x 60 'Red' 1
            plot $x 70 'Red' 2
        }
        bmpRefresh($img)

        ### Reta
        retaBresenham 50 0 535 440 'Orange' 2
        retaBresenham 0 0 585 440 'Blue' 1
        bmpRefresh($img)

        ### Triângulo
        triangulo 100 100 100 'Green' 3
        triangulo 100 120 70 'Gray' 2
        bmpRefresh($img)

        ### Triângulo Sólido
        trianguloSolido 100 220 100 'Red'
        bmpRefresh($img)

        ### Quadrado
        quadrado 370 70 100 'Red' 5
        quadrado 390 90 60 'Black' 3
        quadrado 410 110 20 'blue' 2
        bmpRefresh($img)

        ### Quadrado Sólido
        quadradoSolido 250 70 100 'Green'
        bmpRefresh($img)

        ### Círculo
        circulo 200 380 40 'Black' 2
        bmpRefresh($img)

        circuloSolido 340 370 60 'Blue'
        bmpRefresh($img)
        
})

$form.ShowDialog()

O resultado:

quarta-feira, 25 de outubro de 2017

Desenhando com Pixels

Vamos usar o powershell para realizar algumas experiências com computação gráfica, tendo como premissa que um pixel (um ponto) pode ser considerado base para o desenho de outras estruturas como retas, triângulos, quadrados, etc.

Como nosso objetivo aqui é a implementação dessas estruturas básicas, vamos ignorar que o powershell já possui métodos implementados para desenhar retas, polígonos, etc.

  • Um pixel possui uma coordenada (x,y).
  • Uma reta será um conjunto de pontos; traçada através da implementação do algoritmo de Bresenham.
  • Implementaremos triângulos isósceles a partir de um ponto e a altura do triângulo fornecidos.
  • Quadrados serão implementados a partir de um ponto e o tamanho do lado fornecidos.

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

##########################################################
Function plot([Int32]$x, [Int32] $y, [String] $cor) {
    $img.SetPixel($x, $y, $cor) 
}

##########################################################
Function retaBresenham ([Int32]$x1, [Int32]$y1, [Int32]$x2, [Int32]$y2, [String] $cor) {
    [Int32] $dx = $x2 - $x1
    [Int32] $dy = $y2 - $y1
    [Int32] $stepx, $stepy

    if ($dy -lt 0) { 
        $dy = -$dy 
        $stepy = -1
    }
    else { $stepy = 1 }

    if ($dx -lt 0) { 
        $dx = -$dx 
        $stepx = -1
    }
    else { $stepx = 1 }

    $dy = $dy -shl 1
    $dx = $dx -shl 1

    plot $x1 $y1 $cor

    if ($dx -gt $dy) {
        [Int32] $fraction = $dy - ($dx -shr 1)
        while ($x1 -ne $x2) {
            if ($fraction -ge 0) {
                $y1 += $stepy
                $fraction -= $dx
            }
            $x1 += $stepx
            $fraction += $dy
            plot $x1 $y1 $cor
        }
    }
    else {
        [Int32] $fraction = $dx - ($dy -shr 1)
        while ($y1 -ne $y2) {
            if ($fraction -ge 0) {
                $x1 += $stepx
                $fraction -= $dy
            }
            $y1 += $stepy
            $fraction += $dx
            plot $x1 $y1 $cor
        }
    }
    
}

##########################################################
Function triangulo([Int32]$x1, [Int32]$y1, [Int32]$h, [String]$cor) {
    [Int32] $lado = ([math]::Sqrt(4*$h*$h/3))
    retaBresenham $x1 $y1 ($x1-($lado/2)) ($y1+$h) $cor
    retaBresenham $x1 $y1 ($x1+($lado/2)) ($y1+$h) $cor
    retaBresenham ($x1-($lado/2)) ($y1+$h) ($x1+($lado/2)) ($y1+$h) $cor
}

##########################################################
Function quadrado([Int32]$x1, [Int32]$y1, [Int32]$tam, [String]$cor) {
    retaBresenham $x1 $y1 ($x1+$tam) $y1 $cor
    retaBresenham $x1 $y1 $x1 ($y1+$tam) $cor
    retaBresenham $x1 ($y1+$tam) ($x1+$tam) ($y1+$tam) $cor
    retaBresenham ($x1+$tam) $y1 ($x1+$tam) ($y1+$tam) $cor
}

##########################################################
$B64 = "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAHgAlgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z"
$imgBytes = [Convert]::FromBase64String($B64)
$imgStream = New-Object IO.MemoryStream($imgBytes, 0, $imgBytes.Length)
$img = [System.Drawing.Image]::FromStream($imgStream)
[Windows.Forms.Application]::EnableVisualStyles()
$form = New-Object Windows.Forms.Form
$form.Width = $img.Size.Width;
$form.Height = $img.Size.Height;
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Width =  $img.Size.Width;
$pictureBox.Height =  $img.Size.Height;

### Pontos
for ([Int32]$x=30;$x -lt 55;$x+=5) {
    plot $x 50 'Red'
    plot $x 60 'Red'
    plot $x 70 'Red'
}
### Reta
retaBresenham 0 0 585 440 'Blue'
retaBresenham 50 0 535 440 'Orange'
### Triângulo
triangulo 100 100 100 'Green'
triangulo 100 120 70 'Gray'
### Quadrado
quadrado 250 70 100 'Red'
quadrado 270 90 60 'Black'

$pictureBox.Image = $img;
$form.controls.add($pictureBox)
$form.Add_Shown( { $form.Activate() } )
$form.ShowDialog()

Neste exemplo, estamos criando alguns pontos, 2 retas, 2 triângulos e 2 quadrados.