Um exemplo pouco explorado de aplicação utilizando os programas de GD é a introdução dos conceitos de algoritmo. Isso ocorre porque poucos são os programas de GD que dispõe de recursos para agrupar passos de construção na forma de uma função geométrica (que chamaremos de ``script'').
Informalmente, podemos dizer que um algoritmo é uma seqüência finita de passos que aplicada a um conjunto de dados de entrada produz um conjunto de dados de saída (ou resposta). Além disso, a menos de uma classe particular de algoritmos, um algoritmo deve ser determinístico, ou seja, sempre que for aplicado sobre um mesmo conjunto de entradas, deve produzir o mesmo conjunto de saídas. Observe que, se o conjunto de entrada for vazio, a saída do algoritmo será sempre a mesma.
Uma característica importante de um algoritmo é que ele resolve uma classe de problemas e
não uma instância. Por exemplo, um algoritmo de ordenação para números inteiros (digamos com
),
ordena qualquer conjunto com até
inteiros, em qualquer configuração
(isto é, qualquer que seja a permutação, dentre as
possíveis). A aplicação do algoritmo
sobre um particular conjunto de inteiros, constitui a resolução de uma instância do problema.
Esta observação permite entendermos melhor a diferença entre a GD, que é do tipo 1-N e a geometria estática, tipo 1-1: uma solução geométrica implementada em GD, na prática constitui um algoritmo, enquanto a correspondente solução estática equivale a uma aplicação do algoritmo geométrico sobre um conjunto fixado de dados (estáticos e, portanto, único).
A caracterização de soluções geométricas como algoritmos, pode ser melhor percebida utilizando-se a GD, pois ao finalizar uma construção e testá-la com outras configurações (de entrada), fica claro que a mesma pode ser aplicada a qualquer outro conjunto de entradas (dentre os possíveis). Por outro lado, como observa (), as soluções obtidas pela geometria da régua e compasso são estáticas e particulares, pois não podem ser alteradas e nenhuma delas garante o significado genérico de sua definição (o desenho de um círculo, por exemplo, possui um centro e raio, ambos fixos, mas o conceito de círculo não depende de valores arbitrários).
Para introduzir o conceito de algoritmo geométrico, vamos examinar o exemplo ,
sobre a construção da mediatriz de dois pontos dados, A e B. Na tabela
,
apresentamos um esquema dos passos para obter a mediatriz
de
e
.
Mediatriz(![]() ![]() |
![]() ![]() ![]() |
![]() ![]() ![]() |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() |
Resposta ![]() |
Note que os passos descritos podem ser aplicados a quaisquer pares de pontos (não coincidentes)
constituindo assim um algoritmo. Os comandos ,
e
podem ser
entendidos como primitivas (funções) geométricas:
é a circunferência centrada
em
e passando pelo ponto
;
é um dos pontos de interseção entre os
objetos
e
(podem existir dois, neste caso definidos por "norte",
se
, ou "sul", se
); e
é a reta que contém os pontos
e
(se
, a reta não será única).
Deste modo, é natural esperar que programas de GD permitam que construções geométricas sejam
armazenadas explicitamente na forma de funções, como o fazem o iGeom, GSP e
Cabri. Estas funções geométricas, por agruparem seqüências de comandos, recebem o nome de scripts
(como nas versões atuais do iGeom e do GSP) ou macros (como no Cabri). Uma vez
armazenada uma função, pode-se: (a) marcar os objetos de entrada (na ordem correta)
e depois selecionar a função desejada (como no iGeom e GSP); ou (b) selecionar a função e depois
marcar os objetos de entrada (Cabri). Como discutiremos posteriormente na seção ,
a primeira forma pode ser dita do tipo ``seleção+ação'' enquanto a segunda é do tipo ``ação+seleção''.
A possibilidade de armazenar algoritmos geométricos como funções é bastante útil do ponto de vista didático, pois permite que o aluno armazene em funções as construções que utiliza mais freqüentemente e com isso possa concentrar sua energia nas tarefas novas. Os programas já citados (iGeom, Cabri e GSP) permitem até que uma função, já armazenada, seja invocada durante a geração de uma nova função e com isso aproveitamos funções prontas para construir outras mais complexas.
Exemplo nos quais os usos das funções geométricas são muito úteis são aqueles com processo
de repetição, nos quais é necessário aplicar várias vezes a mesma seqüência de passos,
como no exemplo , apresentado por ().
Para simular geometricamente este exemplo (Figura ),
definimos uma função dist_metade que obtém a próxima posição da
tartaruga em relação a sua posição atual e a posição de aquiles (tabela
).
Utilizando a função dist_metade, podemos simular esta hipotética corrida a partir de eventos
discretos, definindo duas sequências,
uma de tempo
e uma de posição
.
Sendo
o instante de largada e
a posição inicial da tartaruga, podemos definir
as sequências, para
, da seguinte forma:
Deste modo, a construção apresentada na Figura
serve para gerar os pontos
, como esquematizado na tabela
.
Zenão argumentava que a metade de um número positivo (distância) é um número positivo e, deste modo, sendo o tempo e o espaço contínuos, Aquiles jamais alcançaria a tartaruga3. Como observado em (), o aparente paradoxo divulgado por Zenão ilustra a dificuldade que os matemáticos tinham, antes do surgimento do Cálculo Diferencial e Integral, com o conceito infinito e infinitésimo.
Note que o algoritmo geométrico apresentado na tabela possui um bloco de repetição (ou
laço4),
comum nas linguagens de programação usuais (como C, Pascal ou Java).
O passo geral do algoritmo da tabela
é:
Assim, para efetuar a simulação utilizando dist_metade é necessário aplicá-la
seguidas vezes. Entretanto, se na própria definição deste algoritmo incorporarmos uma
chamada recorrente, a própria recorrência controla as múltiplas aplicações.
Portanto, é natural imaginar que tal recurso também possa ser incorporado aos scripts na GD.
A partir do script dist_metade podemos produzir um novo script, de nome aquiles,
anotando a repetição através de uma recorrência
(ou recursão). Usando a função dist_metade, o
script aquiles é definido da seguinte forma:
1. |
![]() |
de acordo com a construção da tabela ![]() |
2. |
![]() |
recorrência, aplicada aos pontos ![]() ![]() |
A recorrência é caracterizada pela instrução na linha 2. Entretanto existe um problema com o
pseudo-código da construção que é não indicar uma condição de parada.
Nas linguagem de programação
usuais, como C ou Pascal, utilizam-se um condicional para invocar a recorrência (e portanto, a recorrência
é interrompida quando certa condição não é satisfeita). Em nosso caso, fazemos
o controle definindo a priori o número de chamadas recorrentes.
O número de vezes (conhecido como profundidade) que a recorrência será aplicada,
,
é definido na chamada da função pelo usuário. Por exemplo, a Figura
mostra o uso
do script aquiles com profundidade dois (poderia-se produzir
uma construção mais ``limpa'' examinando-se os objetos intermediários).
![]() |
Seiji Isotani 2006-10-04