Regressemos às nossas pirâmides. Recordo aqui o programa para desenhar uma pirâmide de quadrados.
import turtle
def pir_quadrados(n,posx, posy,lado):
for i in range(1,n+1):
# desenha linha i
# posiciona
turtle.penup()
turtle.setx(posx+(n-i)*lado/2)
turtle.pendown()
# desenha
for j in range(1,i+1):
quadrado(turtle.xcor(),turtle.ycor(), lado)
turtle.setx(turtle.xcor()+lado)
# muda de linha
turtle.penup()
turtle.goto(posx,turtle.ycor()-lado)
turtle.pendown()
turtle.hideturtle()
def quadrado(posx, posy,lado):
turtle.showturtle()
# posicioan
turtle.penup()
turtle.goto(posx, posy)
turtle.pendown()
# desenha
for i in range(4):
turtle.forward(lado)
turtle.left(90)
turtle.hideturtle()
Quando executado para um pirâmide de tamanho 4, com 20 pixeis de lado obtemos:
Admitamos que o problema agora é semelhante com a diferença da pirâmide dever aparecer... invertida.
Como fazer? olhando para o código acima percebemos que ele está feito para que na linha 1 seja desenhado 1 quadrado, na linha 2, 2 quadrados e, de um modo geral, na linha i sejam desenhados i quadrados. Este procedimento é controlado pelos dois ciclos for. O mais externo identifica a linha i e o mais interno garante que são desenhados i quadrados. Mas agora o que pretendemos é que na linha 1 sejam desenhados n, na 2 (n-1), ..., e na n apenas 1. Se não queremos mexer muito no código basta o ciclo exterior comece por identificar a linha n, depois a (n-1) , etc. Com esta única alteração o problema fica resolvido!
def pir_quadrados_inv(n,posx, posy,lado):
for i in range(n,0,-1): # <-- só alterámos aqui!!
# desenha linha i
# posiciona
turtle.penup()
turtle.setx(posx+ (n-i)*lado/2)
turtle.pendown()
# desenha
for j in range(1,i+1):
quadrado(turtle.xcor(),turtle.ycor(), lado)
turtle.setx(turtle.xcor()+lado)
# muda de linha
turtle.penup()
turtle.goto(posx,turtle.ycor()-lado)
turtle.pendown()
turtle.hideturtle()
Fantástico não é? Mas suponhamos que alguém tem algo contra quadrados e prefere triângulos?? Bem, temos que ser capazes de desenhar triângulos, certo? Vamos a isso.
def triangulo(posx, posy, lado):
turtle.showturtle()
# posicioan
turtle.penup()
turtle.goto(posx, posy)
turtle.pendown()
# desenha
for i in range(3):
turtle.forward(lado)
turtle.left(120)
turtle.hideturtle()
E agora? Será que substituir o uso da definição quadrado pela definição de triângulo resolve a questão?
def pir_triangulos_inv(n,posx, posy,lado):
for i in range(n,0,-1):
# desenha linha i
# posiciona
turtle.penup()
turtle.setx(posx+ (n-i)*lado/2)
turtle.pendown()
# desenha
for j in range(1,i+1):
triangulo(turtle.xcor(),turtle.ycor(), lado) # <-- única mudança!!
turtle.setx(turtle.xcor()+lado)
# muda de linha
turtle.penup()
turtle.goto(posx,turtle.ycor()-lado)
turtle.pendown()
turtle.hideturtle()
Então e não é que resolve?
Mas porque funciona? É facil de perceber que a estrutura global é a mesma. Por outro lado, o posicionamento de cada triângulo obedece à mesma regra do caso dos quadrados. Entusiasmados, passamos a hexágonos:
def pir_hexagonos_inv(n,posx, posy,lado):
for i in range(n,0,-1):
# desenha linha i
# posiciona
turtle.penup()
turtle.setx(posx+ (n-i)*lado/2)
turtle.pendown()
# desenha
for j in range(1,i+1):
hexagono(turtle.xcor(),turtle.ycor(), lado) # <-- única mudança!
turtle.setx(turtle.xcor()+lado)
# muda de linha
turtle.penup()
turtle.goto(posx,turtle.ycor()-lado)
turtle.pendown()
turtle.hideturtle()
Quando executamos o código, a surpresa. Não funciona:
A razão está no modo como vamos avançando os hexágonos em cada linha e na forma como baixamos de linha. Então quais os valores certos? olhemos para a figura:
Ela diz-nos que dentro de cada linha temos que avançar x do valor do lado mais duas vezes o valor de B. Quando mudamos de linha temos que alterar y de um valor igual a A. Mas o que são A e B? Um pouco de geometria diz-nos que A = 2* coseno(30) e B = coseno(60). Feitas as contas, chegamos a A= 1.732* lado e B = 0.5 * lado. Daí a nossa solução final:
def pir_hexagonos(n,posx, posy,lado):
for i in range(n,0,-1):
# desenha linha i
# posiciona
turtle.penup()
turtle.setx(posx+(n-i)*lado)
turtle.pendown()
# desenha
for j in range(1,i+1):
hexagono(turtle.xcor(),turtle.ycor(), lado)
turtle.penup()
turtle.setx(turtle.xcor()+2*lado) # <-- Novidade!
turtle.pendown()
# muda de linha
turtle.penup()
turtle.goto(posx,turtle.ycor()-1.732*lado) # <-- Novidade!
turtle.pendown()
turtle.hideturtle()
Ver para crer:
Moral da história. Existem padrões de programação. Para uma dada classe de problemas semelhantes as soluções também elas são semelhantes. De qualquer modo temos que ter cuidado com generalizações apressadas e identificar bem o que faz a essência de uma solução. Neste caso o modo como se posiciona a tartaruga para uma linha e dentro de uma dada linha.
Agora, pode tentar com ... pentágonos??
Sem comentários:
Enviar um comentário