Você está na página 1de 78

PostScript

Ilustrando e aprendendo matemática

versão 1.1

Frederico José Andries Lopes


Sumário
Introdução ............................................................................................................... 4
Capítulo 1................................................................................................................. 6
Os fundamentos da linguagem...........................................................................6
1.1 O sistema de coordenadas ..........................................................................6
1.2 A unidade de medida ....................................................................................7
1.3 Notação pós-fixa e operações aritméticas....................................................8
1.4 A pilha ........................................................................................................... 9
1.5 Exercícios.................................................................................................... 11
Capítulo 2 .............................................................................................................. 13
Linhas retas (I).................................................................................................. 13
2.1 Segmentos de reta .....................................................................................13
2.2 Pontos......................................................................................................... 18
2.3 Nomeando trechos de código: o comando def............................................19
2.4 Exercícios.................................................................................................... 20
Capítulo 3 .............................................................................................................. 22
Linhas retas (II)................................................................................................. 22
3.1 Estilos de linhas ......................................................................................... 22
3.1.1 setgray ............................................................................................... 22
3.1.2 setlinewidth ........................................................................................ 24
3.1.3 setdash ............................................................................................... 26
3.2 Os comandos gsave e grestore ..................................................................27
3.3 Exercícios.................................................................................................... 29
Capítulo 4............................................................................................................... 31
Circunferências, arcos de circunferência, elipses e curvas de Bézier...............31
4.1 Circunferências e arcos de circunferências.................................................31
4.1.1 arc....................................................................................................... 31
4.1.2 arcn..................................................................................................... 34

1
4.2 Elipses......................................................................................................... 35
4.3 Efeitos de sombra.......................................................................................36
4.4 Curvas de Bézier......................................................................................... 37
4.5 Exercícios.................................................................................................... 39
Capítulo 5............................................................................................................... 40
Transformações ............................................................................................... 40
5.1 O ponto corrente ........................................................................................ 40
5.2 Translação .................................................................................................. 41
5.3 Rotação ...................................................................................................... 42
5.4 Ampliação e redução...................................................................................46
5.5 Reflexão...................................................................................................... 47
5.6 Exercícios.................................................................................................... 48
Capítulo 6............................................................................................................... 49
Elementos de programação..............................................................................49
6.1 O comando de repetição repeat .................................................................49
6.2 Procedimentos............................................................................................ 53
6.3 Arrays (vetores)........................................................................................... 54
6.4 Exercícios.................................................................................................... 57
Capítulo 7............................................................................................................... 58
Fontes............................................................................................................... 58
7.1 Fontes PostScript........................................................................................ 58
7.2 Principais comandos...................................................................................58
7.3 Outros comandos........................................................................................ 61
7.4 Exercícios.................................................................................................... 62
Capítulo 8............................................................................................................... 63
Acabamentos, cores e clipping.........................................................................63
8.1 Acabamentos............................................................................................... 63
8.2 Cores........................................................................................................... 65
8.3 Clipping....................................................................................................... 66
8.4 Exercícios.................................................................................................... 68
Bibliografia ............................................................................................................. 69
Apêndices .............................................................................................................. 71
A - Preparando o ambiente ..............................................................................71
B - Trabalhando com PostScript .......................................................................73
Trabalhando interativamente .......................................................................73
C – Fontes PostScript.......................................................................................74
D - Criando um arquivo EPS.............................................................................76

3
Introdução
Para explicar conteúdos de matemática, professores frequentemente fazem uso
de ilustrações. Seja desenhada no quadro negro ou na forma de slides, uma boa
figura permite a representação e a interpretação dos elementos de uma ideia que
se apresenta à compreensão do aluno. Como elementos essenciais na geometria
ou como metáforas em outras áreas, ilustrações de conceitos matemáticos são
vistas, desde a antiguidade, como um dos melhores auxílios que uma pessoa
pode ter durante seu esforço de aprendizado.
Desde o nascimento da era do computador pessoal, no idos dos anos de
1970, matemáticos e cientistas da computação têm se dedicado à criação de mei-
os computacionais que facilitem a criação de figuras. E cada vez mais, computa-
dores têm-nos permitido produzir material ilustrativo de excelente qualidade para
uma gama crescente de assuntos e públicos, ampliando e fortalecendo o campo
da educação em praticamente todas as áreas.
Destacando-se no campo da informação visual e no desenvolvimento de
tecnologias voltadas a esse fim, a empresa americana Adobe Systems Incorpora-
ted criou, na década de 1980, a linguagem de programação PostScript, especifica-
mente voltada para a visualização de informações. Desde então, a Adobe Systems
– a mesma empresa que posteriormente criou o formato PDF – vem desenvolven-
do a linguagem, que se encontra atualmente em sua terceira versão, e fornecendo
ao público gratuitamente excelentes manuais para seu aprendizado (Adobe Sys-
tems, 1985, 1988, 1999).
A linguagem PostScript fornece uma gama de comandos específicos para
o desenho de letras e figuras, incluindo comandos de traçado e formas de repre-
sentação de imagens. É uma linguagem de programação completa, interpretada,
simples e fácil de aprender. Alguns poderiam dizer, como de fato dizem (Adobe
Systems, 1985), que a PostScript pode ser abordada inicialmente como uma varia-
ção da linguagem LOGO, à qual foram acrescentados novos e avançados recur-
sos. Um programa de edição de texto simples e um interpretador gratuito são mais
do que suficientes para operarmos com a linguagem em sua plenitude.
Foi com as obras de Bill Casselman (Casselman, 2000 e 2005) que a
PostScript foi redescoberta como a linguagem fundamental da ilustração matemá-
tica, a despeito das alternativas usuais advindas da comunidade de usuários do
sistema de tipografia LaTeX, como os pacotes de macros PStricks e PGF/TikZ, ou
as linguagens MetaFont e MetaPost. Ainda que programas comerciais geradores
de gráficos matemáticos, como o Maple, o Mathematica e o MatLab sejam capa-
zes de produzir belíssimas ilustrações, apenas a PostScript permite o controle fino
do processo de desenho, produzindo resultados impossíveis de serem atingidos
satisfatoriamente por qualquer outro programa.
O que nos interessa aqui, neste livro, é mostrar uma resposta satisfatória à
pergunta: por que usar PostScript no ensino de matemática? Como nos informa
Casselman no prefácio de seu livro Mathematical Illustrations: A Manual of Geo-
metry and PostScript (2005), uma boa ilustração matemática sempre requer mate-
mática no processo de desenho. Esse aspecto da criação e da programação de
ilustrações captou nossa atenção desde nossos primeiros contatos com a lingua-
gem. A necessidade de usar matemática para ilustrar matemática faz da PostScript
uma excelente ferramenta para não só explicar, mas também descobrir matemáti-
ca.
Aprender PostScript é uma atividade estimulante, facilmente integrada
com diversas outras metodologias de ensino de matemática. Por exemplo, a habili-
dade de desenhar algoritmicamente nos permite criar figuras que esclarecem os
argumentos de textos matemáticos. Tentar criar ilustrações para obras centrais da
matemática clássica, como os Elementos, de Euclides, ou os Principia, de Newton,
obriga o estudante a compreender a argumentação do autor, criando um envolvi-
mento ativo e criativo no processo de aprendizagem.
O campo de uso da PostScript é bastante amplo. Pelo menos quatro clas-
ses de profissionais podem ser beneficiadas pelo aprendizado da linguagem:
• cientistas de várias áreas que precisam criar uma grande quantidade
de ilustrações, e que gostaria de ter uma outra alternativa computacio-
nal além dos programas convencionais;
• professores em qualquer nível de aprendizado que desejam tornar a
matemática mais compreensível e interessante a seus alunos;
• estudantes que desejam ver como a matemática, mesmo elementar,
pode ser aplicada a problemas reais interessantes, e
• artistas e designers gráficos interessados em arte algorítmica ou mes-
mo carentes de novos instrumentos para suas produções gráficas.
Em vista do que foi dito, este livro pretende promover o estudo das geo-
metrias através da criação de ilustrações. E não só as geometrias euclidiana e
analítica planas podem sair beneficiadas, mas também as geometrias projetiva e a
hiperbólica, uma vez que a linguagem PostScript é flexível o bastante para incor-
porar módulos, desenvolvidos por terceiros, que permitem a manipulação de ima-
gens mais avançadas.

5
Capítulo 1
Os fundamentos da linguagem
Antes de iniciarmos a criação de gráficos, vamos primeiro explorar alguns concei-
tos fundamentais da linguagem PostScript, como o sistema de coordenadas, a uni-
dade medida e os principais operadores de que ela se serve para realizar dese-
nhos e construções geométricas. Todos os capítulos seguintes dependem de uma
boa compreensão dos conceitos aqui apresentados.
Também essencial ao aprendizado é o bom funcionamento dos programas
utilizados para a geração de gráficos. Certifique-se de ter lido e compreendido o
Apêndice A para poder trabalhar com eficiência na programação com PostScript.

1.1 O sistema de coordenadas


Para localizar e desenhar ponto em uma folha de papel, a PostScript faz
uso do que chamamos de sistema de coordenadas.
Imaginemos uma folha de papel com eixos localizados em sua extremida-
de inferior esquerda. Esses eixos correm da esquerda para a direita e de baixo
para cima, como nos mostra a figura seguinte:
figura 1.1

Os desenhos são feitos com esse sistema de coordenadas em mente, em


uma folha de papel imaginária. O canto inferior esquerdo, chamado de origem, tem
coordenadas (0, 0). A partir dessa referência inicial, podemos encontrar a localiza-
ção de qualquer objeto na página.
Por exemplo, se um ponto tem coordenadas (100, 200), isso significa que
ele se localiza na folha de papel imaginária a 100 pontos à direita da origem, e 200
pontos acima da origem. É como no jogo de batalha naval ou na notação da posi-
ção das peças em um tabuleiro de xadrez.

1.2 A unidade de medida


Na seção anterior falamos de coordenadas de um ponto. Mas o que vem a
ser um ponto na linguagem PostScript?
Em PostScript, um ponto é uma unidade de medida, chamada de ponto
PostScript. Em uma polegada (2,54 cm) há exatamente 72 pontos PostScript. Isso
nos diz que um ponto equivale à medida de aproximadamente 0,35278 mm. As-
sim, podemos afirmar que uma folha de papel A4, de dimensões 210 mm x 297
mm, mede, aproximadamente, 595 pontos na horizontal e 842 pontos na vertical.
Para efeitos práticos, vamos imaginar um ponto PostScript como um pe-
queno retângulo localizado na posição dada pela coordenadas. Certamente esse
não é o conceito matemático de ponto, mas essa é a melhor representação do que
efetivamente acontece na tela de um computador digital. Um ponto PostScript,

7
além de uma unidade de medida, será visto como um elemento gráfico distinto,
possuindo comprimento e largura, ainda que diminutos. Apesar de imaginarmos
pontos PostScript como pequenos retângulos empilhados uns sobre os outros,
não devemos confundi-los com os pixels da tela do computador.
A unidade de medida ponto PostScript será posteriormente substituída pe-
las unidades de medida usuais como o milímetro e o centímetro. Por ora, lembre-
se apenas de que uma polegada, equivalente a aproximadamente 2,5 cm, contém
72 pontos PostScript.

1.3 Notação pós-fixa e operações aritméticas


A PostScript usa a chamada notação pós-fixa (ou pós-fixada) para expres-
sar comandos. Com essa notação, uma operação aritmética simples como

7 + 5

passa a ser escrita como

7 5 +

ou seja, o número 7, um espaço em branco, o número 5, um espaço em branco, e


o sinal de +. Observe que o símbolo da operação a ser realizada sobre os dados
vem depois dos dados (daí o nome pós-fixa).
Em verdade, a operação acima é escrita, em PostScript, como

7 5 add

em que o operador add substitui o tradicional sinal +.


Em PostScript existem vários operadores aritméticos. A lista abaixo, que
usaremos como referência, mostra alguns deles. Usamos o símbolo → para indi-
car o resultado da operação:
• add adiciona dois números: 5 6 add → 11
• sub subtrai dois números: 8 5 sub → 3
• mul multiplica dois números: 4 6 mul → 24
• div divide dois números: 18 3 div → 6
• neg inverte o sinal de um número: 3 neg → -3
-5 neg → 5
Todos os operadores agem imediatamente sobre os números encontrados
logo à esquerda, substituindo-os pelo resultado da operação. Como são armaze-
nados esses dados?

1.4 A pilha
O uso da notação pós-fixa é uma consequência da maneira como os dados em
PostScript são armazenados na memória do computador, em uma estrutura co-
nhecida como pilha.
Os dados em PostScript vão para a memória do computador como se fos-
sem empilhados uns sobre os outros, como em uma pilha de pratos. Quando pre-
cisamos de um prato, costumamos tirar primeiro o prato de cima, para depois tirar
o de baixo. Ou seja, o último prato a ser empilhado é o primeiro a ser desempilha -
do. Essa maneira simples de estruturar os dados na memória do computador é
chamada de estrutura LIFO, do inglês last in, first out (último a entrar, primeiro a
sair).
Precisamos entender bem como essa estrutura funciona. No lugar de uma
pilha de pratos, imaginemos uma fila de livros que vão sendo colocados na estante
um após o outro, da esquerda para a direita:

| | | | | ... etc.

Em PostScript, vamos usar essa metáfora para entender o código que es-
crevemos. Primeiro colocamos os dados um após o outro na pilha (ou estante)

7 5

e depois dizemos o que fazer com eles:

7 5 add

O operador add diz que devemos adicionar os dados e deixar o resultado


(12) na pilha.
Se desejamos subtrair dados, a ordem é também a da esquerda para a di-
reita, como fazemos normalmente. Se escrevemos

12 5 sub

expressão em que sub denota o operador de subtração, teremos na pilha o resul-


tado 7.

9
Operações aritméticas mais complexas devem ser cuidadosamente anali-
sadas, para que a entrada de dados na pilha seja feita com correção. Por exem -
8
plo, a operação deve ser notada como
7−3

8 7 3 sub div

pois dá entrada na pilha, da esquerda para a direita, na seguinte sequência:

8
8 7
8 7 3
8 7 3 sub
8 4
8 4 div
2

Observe que os operadores sub e div, assim que entram na pilha, operam
imediatamente sobre os dois dados mais próximos à esquerda, deixando o resulta-
do na pilha antes da entrada dos dados e operadores seguintes.
Pode ser necessário realizar uma troca de elementos na pilha, eliminar um
deles, duplicar um outro, e assim por diante, em operações aritméticas. Sera ne -
cessário, portanto, alterar a ordem dos dados na pilha, através de operadores cria-
dos exclusivamente para esse fim. A lista abaixo mostra alguns dos mais usados
operadores:

• clear remove todos os elementos da pilha: 3 5 9 clear → (vazio)


• dup duplica o elemento superior da pilha: 3 5 9 dup → 3 5 9 9
• pop remove o elemento no topo da pilha: 3 5 9 pop → 3 5
• exch troca a posição dos dois elementos do topo da pilha:
3 5 9 exch → 3 9 5

Os operadores de pilha nos dão mais flexibilidade nas operações aritméti-


cas. Por exemplo, os dois códigos seguintes são equivalentes (deixam o mesmo
resultado na pilha):

14 2 5 add div
2 5 add 14 exch div

14
Qualquer uma das duas linhas de código acima realiza a operação .
25
A segunda, porém, segue um pouco mais a lógica que utilizamos no dia a dia, rea-
lizando primeiro a soma no denominador e depois a divisão. Vejamos um esquema
passo a passo dessa operação:

2
2 5
2 5 add
7
7 14
7 14 exch
14 7
14 7 div
2

Em palavras, primeiro alimentamos a pilha com 2 e 5 e fizemos a opera-


ção de adição, deixando 7 na pilha. Alimentamos a pilha com 14, mas não pode-
7 14
mos realizar a operação de divisão, que daria , e não , como desejamos.
14 7
Por isso, alimentamos a pilha com o operador exch, que inverte a posição dos
dois números mais recentemente introduzidos na pilha. Agora podemos realizar a
operação, ficando com o resultado correto 2.
Percebemos, no entanto, que a notação da primeira linha é mais econômi-
ca e mais simples, mas exige um conhecimento mais seguro de como são realiza-
das as operações em pilha. Para entender melhor esses recursos, realize os exer -
cícios no fim de cada capítulo, começando desde já sua história pessoal com essa
magnífica linguagem.

1.5 Exercícios
1. Escreva as operações abaixo em PostScript:
6
a) 7−
2
6
b) −7
2

11
5 2
c) −
2 5
5−2
d)
2−5

2. Calcule mentalmente o resultado das operações abaixo:


a) 2 3 add 5 div
b) 6 1 5 add sub
c) 3 5 div 2 5 div add
d) 3 4 5 add mul
e) 3 4 mul 5 add

3. Escreva os valores que ficam na pilha depois da operações:


a) 2 dup 6 dup
b) 3 8 exch dup
c) 3 9 exch pop
d) 4 7 pop 5 exch
e) 1 2 3 pop exch

4. Calcule mentalmente o resultado das operações abaixo:


a) 1 2 dup div add
b) 3 6 2 sub exch sub
c) 2 7 5 3 pop sub mul
d) 4 5 exch sub 3 dup mul add
e) 3 6 9 12 exch sub sub div
Capítulo 2
Linhas retas (I)
Linhas retas são os componentes mais frequentes em ilustrações matemáticas, e
os primeiros que aprendemos quando estudamos PostScript, antes mesmo de
aprendermos a desenhar um simples ponto. Neste capítulo vamos aprender como
lidar com esse elemento simples e extremamente versátil, nas diversas formas em
que se apresenta.
Vamos também estudar o comando def, que nos possibilitará nomear tre-
chos de código, evitando sua repetição e aumentando a legibilidade de nossos
programas.

2.1 Segmentos de reta


Segmentos de reta são tradicionalmente o primeiro elemento que domina-
mos quando aprendemos PostScript. Comecemos aprendendo a desenhar um
segmento horizontal de 100 pontos de comprimento em nosso espaço gráfico.
Todo desenho, em PostScript, deve ser preferencialmente iniciado com o
comando

newpath

Após esse comando, podemos imaginar que uma mão passou a segurar
um lápis. Vamos imaginar também que a ponta desse lápis não escreve com grafi-
te ou tinta, mas é feita de aço ou de outro material que marca a folha, deixando
nela um leve sulco.
Agora vamos desenhar um segmento de reta horizontal de 100 pontos a
partir das coordenadas (300, 500). Primeiro, devemos mover a ponta do lápis até
lá usando o comando moveto:

13
300 500 moveto

O comando moveto desloca a ponta do lápis para as coordenadas (300,


500).
Com o lápis em posição, marquemos no papel uma linha horizontal de ta-
manho 100 pontos para a direita com o comando lineto, ou seja, do ponto de co-
ordenadas (300, 500) até o ponto de coordenadas (400, 500):

400 500 lineto

Em verdade, o segmento ainda não foi traçado. Apenas um sulco foi feito
sobre a folha, uma marca que será posteriormente preenchida com tinta. A ponta
do lápis está agora sobre o ponto (400, 500), esperando o próximo comando.
O comando stroke preenche com tinta as marcações feitas. Após os qua-
tro comandos

newpath
300 500 moveto
400 500 lineto
stroke

devemos ver a seguinte imagem na folha:

figura 2.1-a

Após passar tinta sobre as marcas criadas, o comando stroke retira o lá-
pis do papel e "esquece" as indicações dadas. É preciso um outro newpath para
realizar um novo desenho. Uma folha pode conter vários desenhos, cada um en -
volvido por um par de comandos newpath e stroke.
Suponha agora que, antes de finalizar o desenho, você queira traçar mais
um segmento, paralelo ao primeiro, mas 20 pontos acima.
Lembre-se que, após o comando 400 500 lineto, a ponta do lápis imaginá-
rio está exatamente sobre essas coordenadas, ou seja, sobre o ponto de coorde-
nadas (400, 500). É necessário mover a ponta do lápis 100 pontos para trás (sub-
traindo 100 da coordenada 400) e 20 pontos para cima (somando 20 à coordena-
da 500):

300 520 moveto


Agora a ponta do lápis está localizada 20 pontos acima do início do seg-
mento original. Agora trace o novo segmento:

400 520 lineto

Acrescente essas duas linhas ao seu programa original, antes do coman-


do stroke. Seu programa agora é:

newpath
300 500 moveto
400 500 lineto
300 520 moveto % move novamente o lápis
400 520 lineto % marca um novo segmento
stroke

O símbolo % é utilizado em programas PostScript para indicar o início de


um comentário. Tudo o que vem depois dele, até o final da linha em que aparece,
é ignorado quando o programa é interpretado.
Você poderia substituir o comando 300 520 moveto por um outro:

-100 20 rmoveto

O comando rmoveto executa um movimento relativo ao ponto em que o


lápis se encontra. Como precisávamos subtrair 100 da coordenada 400, e somar
20 à coordenada 500, podemos informar isso ao comando rmoveto que ele faz as
contas por nós. Substitua a linha no seu programa e visualize o resultado, que
deve ser:

figura 2.1-b

Suponha agora que, em vez de traçar uma paralela, você queira traçar um
segmento de reta para cima, como o tamanho de 100 pontos. Você tem duas alter-
nativas: escrever, logo após 400 500 lineto, uma das linhas

400 600 lineto

ou

15
0 100 rlineto

Na primeira opção, você faz as contas e informa ao comando lineto até


onde a ponta do lápis deve ir. Na segunda, você informa apenas o acréscimo que
quer dar às coordenadas correntes.
Seu programa agora, para o segmento original acrescentado com o seg-
mento perpendicular, fica:

newpath
300 500 moveto
400 500 lineto
0 100 rlineto % marca um segmento vertical
stroke

gerando a figura

figura 2.1-c

Se você quer desenhar um quadrado, bastam quatro comandos rlineto a


partir do primeiro moveto:

newpath
300 500 moveto
100 0 rlineto % inicia a marcação de 4 segmentos
0 100 rlineto
-100 0 rlineto
0 -100 rlineto
stroke
figura 2.1-d

Faça agora uma experiência. No programa GSview, amplie o desenho, cli-


cando no ícone que tem o desenho de uma lupa, apertando em seguida a tecla R,
e observe o vértice inferior esquerdo do quadrado, o início do desenho. Não pare -
ce que os segmentos estão bem conectados; há uma pequena falha bem no canto
(compare com os outros vértices do quadrado). Vamos corrigir esse problema com
o comando closepath:

newpath
300 500 moveto
100 0 rlineto
0 100 rlineto
-100 0 rlineto
closepath % fecha o caminho traçado
stroke

O comando closepath elimina o problema descrito na seção anterior, o da


falha na união dos segmentos (amplie a nova figura e repare). Sempre que desejar
usar formas fechadas, utilize o comando closepath para melhores resultados visu-
ais.
Se você deseja desenhar figuras preenchidas, use o comando fill no lugar
do comando stroke:

newpath
300 500 moveto
100 0 rlineto
0 100 rlineto
-100 0 rlineto
closepath
fill % preenche o caminho traçado

17
figura 2.1-e

Em verdade, o comando fill substitui não só o comando stroke, mas tam-


bém o comando closepath. Apague o comando closepath no programa acima, e
verifique o resultado.
O comando stroke pode ser usado várias vezes no desenho, um stroke
após cada novo elemento do desenho. Essa técnica deve ser utilizada sempre que
aparecerem elementos indesejados no desenho.

2.2 Pontos
Em PostScript, um ponto é visto como um segmento de reta de tamanho
1, em qualquer direção. Se desejamos colocar um ponto nas coordenadas (100,
100), começamos dizendo ao interpretador que desejamos realizar um desenho,
movemos o lápis até as coordenadas (100, 100), marcamos sobre a folha um seg-
mento de dimensão 1, e preenchemos com tinta:

newpath
100 100 moveto
1 0 rlineto % marca um segmento de tamanho 1
stroke

A direção da esquerda para a direita foi escolhida apenas por comodidade.


Poderíamos traçar um segmento de tamanho 1 em qualquer direção.
Em geral, um ponto com essas dimensões é dificilmente visível na tela do
computador ou no papel impresso. Essa dificuldade é superada substituindo-o,
graficamente, por um pequeno círculo cheio ou vazio, que aprenderemos a dese-
nhar no capítulo 4.
2.3 Nomeando trechos de código: o comando def
O ponto PostScript não é uma medida que costumamos usar em nosso dia
a dia. Seria bem melhor se pudéssemos usar em nossos desenhos as medidas
usuais de centímetro (cm) e milímetro (mm), o que faremos com o comando def.
O comando def é de importância fundamental quando desejamos dar um
nome a determinados conjuntos de comandos. Aqui, vamos usá-lo para definir
uma nova unidade. Comecemos definindo o centímetro.
Suponhamos que queremos escrever um programa que desenha um qua-
drado, de lado igual a 5 cm, da seguinte maneira:

newpath
10 cm 15 cm moveto
5 cm 0 cm rlineto
0 cm 5 cm rlineto
-5 cm 0 cm rlineto
closepath
stroke

Como fazer isso? Como mover a ponta do lápis 10 cm para direita e 15 cm


para cima, e daí começar o quadrado, usando a medida dos lados em centíme-
tros? Primeiro, vamos entender como converter essas medidas — 5 cm, 10 cm e
outras — no número de pontos PostScript correspondentes.
Sabemos que uma polegada tem 72 pontos PostScript, e que uma polega-
da mede exatamente 2,54 cm. Para encontrarmos a medida em polegadas de 5
cm, basta dividir 5 por 2,54, o que nos dá aproximadamente 1,97 polegadas. Ou
seja, 5 cm equivalem a aproximadamente 1,97 polegadas. Quantos pontos PostS-
cript há em 1,97 polegadas? Basta multiplicarmos 1,97 por 72, obtendo aproxima-
damente 141,84 pontos PostScript.
Em resumo, fizemos (5 / 2,54) x 72. Em PostScript, fica

5 2.54 div 72 mul

Se agora queremos saber quantos pontos há em 10 cm, a conta será

10 2.54 div 72 mul

Observe que o conjunto de instruções 2.54 div 72 mul é o mesmo nos


dois casos, e será o mesmo com qualquer outra medida em centímetros. Aqui é
que entra o comando def.

19
O comando def atribui um nome a um conjunto de instruções. Sua sintaxe
é bem simples:

/cm {2.54 div 72 mul} def % definição de cm

que é equivalente a

/cm {28.35 mul} def % definição simplificada

pois dividir por 2,54 e multiplicar por 72 é o mesmo que multiplicar por 72/2,54 =
28,34646, ou ainda, aproximadamente por 28,35. Isso significa que quando quere -
mos um segmento de 3 cm, precisamos multiplicar 3 por 28,35 para encontrarmos
o valor em pontos. Como podemos perceber, há aproximadamente 28,35 pontos
PostScript em 1 cm.
Atribuímos ao nome cm o conjunto de instruções 28.35 mul. Observe que
há uma barra / antes do nome e chaves ao redor do conjunto de instruções. Com
isso, em vez de escrevermos

10 28.35 mul 15 28.35 mul moveto

escrevemos apenas

10 cm 15 cm moveto

o que aumenta enormemente a legibilidade de nossos programas.


Para ganharmos essa flexibilidade, basta acrescentarmos a linha /cm
{28.35 mul} def antes do comando newpath, ou seja, como a primeira linha de
nosso programa.

2.4 Exercícios
Os exercícios seguintes foram planejados de maneira a exigirem do programador
conhecimentos específicos de matemática. A ajuda de bons livros de geometria
euclideana plana e de geometria analítica talvez sejam indispensáveis. O aprendi-
zado de matemática, lembremos, é um dos objetivos deste livro.

1. Desenhe dois segmentos que sejam:


a) concorrentes
b) concorrentes e que se dividam mutuamente na razão 2:1
c) concorrentes e que façam um ângulo de 30 o entre si

2. Desenhe um triângulo:
a) equilátero
b) retângulo com a hipotenusa paralela à base da “folha de papel”
c) com lados na proporção 3:5:7

3. Desenhe um quadrilátero com lados não congruentes e não paralelos. Desenhe


o quadrilátero formado pelos segmentos que unem os pontos médios de cada
lado.

4. Faça uma ilustração para o teorema de Tales: “Se duas retas são transversais
de um feixe de retas paralelas, então a razão entre dois segmentos quaisquer de
uma delas é igual à razão entre os respectivos segmentos correspondentes da ou-
tra.”

5. Desenhe duas setas paralelas, como na figura abaixo:

Desenhe agora os eixos coordenados da figura 1.1.

21
Capítulo 3
Linhas retas (II)
Neste capítulo aprenderemos como alterar o estilo de uma linha, em função de
uma melhor apresentação gráfica das ilustrações.
Vamos estudar também os comandos gsave e grestore, dando os primei-
ros passos para a simplificação de nossos programas.

3.1 Estilos de linhas


Em muitos desenhos, precisamos de mais de um estilo de linhas para
mostrar que certos elementos são mais importantes do que outros, ou que alguns
elementos são linhas de construção, provisórias. Esses elementos não devem ser
considerados como parte integrante do desenho final, como quando realizamos
construções com régua e compasso. Geralmente, linhas contínuas e pontilhadas
são usadas juntamente com linhas linhas finas e grossas, e também com linhas
claras e escuras para causar esse efeito. Veremos alguns comandos da PostScript
que tratam desse assunto.

3.1.1 setgray
O comando que especifica se uma linha será mais clara do que outra é o
setgray. Esse comando é usado com um número entre 0 e 1, que específica tons
de cinza, entre o preto (0) e o branco (1).
Retome o programa das paralelas, usando agora rmoveto e rlineto, e
acrescente antes do stroke o comando 0.7 setgray:
newpath
300 500 moveto
100 0 rlineto
-100 20 rmoveto
100 0 rlineto
0.7 setgray % estabelece uma tonalidade de cinza
stroke

figura 3.1.1-a

Executando o programa sem 0.7 setgray, você verá duas paralelas pretas;
com 0.7 setgray, as paralelas tomaram a tonalidade cinza claro. O comando 0.7
setgray veio antes de stroke apenas para nos lembrarmos que é o comando
stroke que realiza o desenho, e que a ele informamos que a tonalidade deveria
ser 0.7.
Se você deseja que um segmento seja claro e o outro escuro, por enquan-
to você deve fazer dois desenhos:

newpath
300 500 moveto
100 0 rlineto
stroke

newpath
300 520 moveto
100 0 rlineto
0.7 setgray
stroke

figura 3.1.1-b

Se não definimos o valor de setgray, a PostScript assume que ele é 0


(preto). Não precisamos desse comando se não são necessárias tonalidades dife-
rentes em nosso desenho.
Mas adiante, veremos como evitar a escrita de dois desenhos com os co-
mandos gsave e grestore.

23
3.1.2 setlinewidth
Também a espessura das linhas pode ser alterada. Se desejamos que
nossas linhas tenham a espessura de 10 pontos PostScript, simplesmente escre-
vemos

10 setlinewidth

logo antes de stroke:

newpath
300 500 moveto
100 0 rlineto
10 setlinewidth % estabelece a espessura da linha
stroke

figura 3.1.2-a

É preciso ter em mente que as marcações feitas na folha pelo comando


rlineto não têm a espessura de 10 pontos. É o comando 10 setlinewidth que fun-
ciona como um pincel de 10 pontos de largura a ser passado sobre as marcações
invisíveis. Essas marcações podem ser imaginadas como a "alma" das linhas, lo-
calizadas bem no centro delas:

figura 3.1.2-b

Na figura 3.1.2-b acima, desenhamos uma linha em branco no meio da li-


nha preta apenas para representar a marcação invisível sobre a qual a PostScript
desenha com os comandos fill e stroke. Esse conceito, o de tinta sobre a marca-
ção, deve ser mantido em mente o tempo todo, pois uma linha com 10 pontos de
largura significa 5 pontos de largura para cada lado, alterando as dimensões reais
do desenho. Por exemplo, o quadrado da figura 2.1.4, se traçado com uma linha
de 10 pontos de espessura, terá a medida de seus lados aumentada em 10 pon-
tos:
figura 3.1.2-c

Observe agora outra característica da linguagem PostScript. Copie o segu-


inte programa e visualize no GSview:

newpath
300 500 moveto
100 0 rlineto
10 setlinewidth
stroke

newpath
300 520 moveto
100 0 rlineto
0.7 setgray
stroke

figura 3.1.2-d

Apenas lendo o programa, percebemos que a primeira parte traça um seg-


mento de reta de espessura 10 pontos, e a segunda parte traça um segmento de
reta mais claro que o primeiro. No entanto, quando visualizamos o resultado, a se-
gunda linha também aparece com a espessura de 10 pontos! O que aconteceu, se
não escrevemos 10 setlinewidth também na segunda parte (e, portanto, a PostS-
cript deveria assumir que a espessura é 1 setlinewidth)?
Dissemos que o comando stroke finaliza um desenho, passando a tinta
sobre as marcações efetuadas, esquecendo-as logo depois. Mas esse comando

25
não esquece de detalhes como cor, espessura e estilo de linha. Esses dados con-
tinuam guardados na memória do computador para uso futuro, e são chamados de
estado gráfico do desenho.
Portanto, se você deseja uma linha clara com a espessura de 1 ponto,
será necessário escrever 1 setlinewidth antes de stroke na segunda parte do de-
senho. Faça isso agora e visualize o resultado.

3.1.3 setdash
Quando precisamos de linhas tracejadas ou pontilhadas, usamos o co-
mando setdash. Vamos traçar um quadrado e depois uma de suas diagonais com
uma linha tracejada:

newpath
300 500 moveto
100 0 rlineto
0 100 rlineto
-100 0 rlineto
closepath
stroke

newpath
300 500 moveto
100 100 rlineto
[5 4] 0 setdash % cria um padrão de traços e espaços
stroke

figura 3.1.3

O comando setdash é bastante flexível. Com ele podemos criar diversos


padrões de linhas pontinhadas, tracejadas e mistas, bastando para isso definir o
padrão de pontos pretos e brancos que desejamos. Em nosso caso, determinamos
que seria uma linha tracejada com 5 pontos pretos seguidos de 4 pontos brancos.
Por isso, escrevemos [5 4]. O zero em [5 4] 0 nos diz que esse padrão deve ser
repetido a partir do primeiro ponto do padrão original. Se desejamos começar com
brancos, devemos começar a partir do sexto ponto: [5 4] 6.
O padrão é sempre o de pretos seguidos de brancos. Faça alguns testes:
tente trocar [5 4] por [5 4 1 4] e observe o que acontece. Troque também o núme-
ro que vem logo depois para outros valores.
Como na figura acima, e também nas figuras que mostraram linhas claras
e escuras, precisamos começar dois desenhos. Os comando da seção seguinte,
gsave e grestore nos ajudarão a economizar linhas de código.

3.2 Os comandos gsave e grestore


Os comando gsave e grestore costumam andar juntos. Funcionam como
“parênteses” no meio do código, salvando as configurações do estado gráfico até
o momento, rastaurando-as depois quando necessário.
Lembremo-nos que o estado gráfico de um desenho, como dito na seção
3.1.2, é um conjunto de informações sobre a espessura das linhas, suas cores e
seus estilos. Também faz parte do estado gráfico de um desenho as marcações
feitas até então e o último ponto sobre o qual se apoiou a ponta de nosso lápis
imaginário, ponto esse chamado de ponto corrente. Vejamos na prática como usar
esses comandos.
Suponha que você queira fazer o seguinte desenho:

figura 3.2

Preenchemos um quadrado com a tonalidade de cinza 0.5 setgray e de-


pois o emolduramos com uma borda de 10 pontos de largura. Como você faria

27
isso? Por enquanto, são necessários 2 desenhos, um para o preenchimento e ou-
tro para a moldura:

newpath
300 500 moveto
100 0 rlineto
0 100 rlineto
-100 0 rlineto
0.5 setgray
fill

newpath
300 500 moveto
100 0 rlineto
0 100 rlineto
-100 0 rlineto
closepath
0 setgray
10 setlinewidth
stroke

Esse código produz o resultado desejado, além de simples e de fácil leitu-


ra. No entanto, há muitas linhas repetidas nas duas partes, e seria interessante
que pudéssemos aproveitar na segunda parte o que foi escrito na primeira, ou vi-
ce-versa. Observe como há muita redundância entre as partes.
Vamos mostrar como ficaria esse código usando os comandos gsave e
grestore, passando a explicar seu funcionamento logo depois:

newpath
300 500 moveto
100 0 rlineto
0 100 rlineto
-100 0 rlineto
closepath
gsave % salva o estado gráfico
0.7 setgray
fill
grestore % restaura o estado gráfico
10 setlinewidth
stroke
As seis primeiras linhas são as marcações iniciais do quadrado que dese-
jamos preencher. Nesse momento, a PostScript também assume que a espessura
da tinta sobre essas marcações será, futuramente, de 1 ponto (1 setlinewidth) e
será da cor preta (0 setgray). Até que informemos mais coisas, esse é o atual es-
tado gráfico do desenho.
Quando usamos o comando gsave, pedimos à PostScript que armazene
na memória esse atual estado gráfico: as marcações feitas mais as características
de espessura e cor assumidas. Agora vamos fazer algumas alterações nesse esta-
do gráfico.
Quando escrevemos 0.7 setgray e fill, ordenamos à PostScript que mude
a cor, de preto para um cinza claro, e que preencha as marcações com esse tom
de cinza. O estado gráfico foi claramente alterado.
Logo depois, aparece o comando grestore, que traz de volta todo o esta-
do gráfico anterior ao gsave: todas as marcações feitas, a espessura e a cor da
tinta. É como se depois do closepath pulássemos diretamente para o comando 10
setlinewidth, que informará ao comando stroke que a linha ser pintada tem a es-
pessura de 10 pontos.
Em um primeiro momento, os comando gsave e grestore podem parecer
confusos, mas a experiência com a linguagem os tornará mais claros. Como disse-
mos, a divisão de um desenho em várias partes é uma boa alternativa para criar -
mos códigos mais simples e mais legíveis. Mas haverá momentos em que os co -
mando gsave e grestore, inteligentemente utilizados, serão a única alternativa
para realizarmos desenhos matemáticos complexos.
Como exercício, reescreva os programas das seções 3.1.2 e 3.1.3 com os
comandos gsave e grestore.

3.3 Exercícios
1. Desenhe um triângulo escaleno obtusângulo. Em relação ao maior lado, dese-
nhe, em um tom de cinza:
a) a mediana
b) a mediatriz
c) a altura

2. Desenhe as figuras abaixo com as diagonais pontilhadas:


a) um trapézio isósceles
c) um trapézio retângulo

29
d) um trapézio qualquer

3. Desenhe um pentágono. Desenhe suas diagonais com metade da espessura


dos lados.

4. Usando gsave e grestore, desenhe:


a) três linhas paralelas com tonalidades diferentes de cinza
b) três linhas paralelas com padrões diferentes de linha
c) um triângulo retângulo com preenchimento cinza e lados pretos

5. Ilustre a “regra do paralelogramo” utilizada na soma de dois vetores. Se os veto -


res v e w são v = (a, b) e w = (c, d), então v + w = (a + c, b + d).
Capítulo 4
Circunferências, arcos de circunferência, elipses e cur-
vas de Bézier
Circunferências e arcos de circunferência, são tão importantes nas ilustrações
quanto segmentos de reta. Neste capítulo veremos como desenhá-los, e também
elipses, arcos de elipses e o que são as famosas curvas de Bézier.

4.1 Circunferências e arcos de circunferências


Circunferências e arcos de circunferência são simples de serem desenha-
dos em PostScript. Os dois principais comandos são arc e arcn.

4.1.1 arc
O comando arc desenha arcos que variam de 0 o a 360o, em sentido anti-
horário. Esse comando opera com 5 parâmetros: as coordenadas do centro da cir-
cunferência, o raio da circunferência e os ângulos inicial e final, nessa ordem.
Como exemplo, o comando para desenhar um arco de 90o de uma circun-
ferência de raio igual a 50 pontos com centro no ponto (300, 400) é

300 400 50 0 90 arc

figura 4.1.1-a

31
O comando começou com as coordenadas do centro da circunferência,
(300, 400). Logo depois, informamos o valor do raio, 50, e dissemos que o arco
começaria em 0o e terminaria em 90o. O programa todo é, simplesmente,
newpath
300 400 50 0 90 arc % arco de 90 graus, raio 50
stroke

Se desejamos desenhar uma circunferência, basta informarmos que o ân-


gulo final é 360o:

300 400 50 0 360 arc

figura 4.1.1-b

Podemos traçar uma circunferência tracejada, utilizando o comando set-


dash visto no capítulo anterior:

newpath
300 400 50 0 90 arc
[5 5] 0 setdash
stroke

figura 4.1.1-c
Observe como o primeiro e o último traço formaram um traço maior logo
no início do arco. Podemos ajustar isso alterando o número imediatamente anteri-
or ao comando setdash ou o mudando padrão de brancos e pretos do comando.
Teste alguns valores até conseguir uma figura que lhe seja conveniente.
Se desejamos desenhar um anel, basta traçarmos um arco mais largo,
com o uso do comando setlinewidth. Vamos desenhar um anel circular com uma
linha de 30 pontos de espessura:

newpath
300 400 40 0 360 arc
30 setlinewidth
stroke

figura 4.1.1-d

Observe a pequena fenda à direita. Isso pode ser corrigido com o coman-
do closepath. Acrescente-o logo depois do comando arc, e veja como a fenda
some. Com figuras fechadas, use sempre com o comando closepath, mesmo lhe
pareçendo redundante.
Como o comando lineto, o comando arc é responsável por realizar ape-
nas uma marcação invisível no papel, sobre a qual o comando stroke passará um
pincel com tinta. Se queremos desenhar um anel circular, não devemos simples-
mente aumentar a espessura da linha, como fizemos na figura 4.1.1-d acima, mas
desenhar dois círculos com fill, um com a cor preta e outro com a cor branca.
Vamos desenhar uma coroa circular com raio externo de 2 cm e raio inter-
no de 1 cm. Lembremo-nos de usar o comando def para transformar a medida
"cm" em pontos.

/cm {28.35 mul} def % define a unidade cm

33
newpath
300 400 2 cm 0 360 arc % circunferência externa
fill % preenche a circunf. externa
300 400 1 cm 0 360 arc % circunferência interna
1 setgray % define a cor branca
fill % preenche a circunf. interna

figura 4.1.1-e

4.1.2 arcn
O comando arcn é como o comando arc, mas a contagem do ângulo é fei-
ta em sentido horário. O programa abaixo é o mesmo que gerou a figura 4.1.1-a
com o comando arc substituído pelo comando arcn:
newpath
300 400 50 0 90 arcn
stroke

figura 4.1.2

Observe que a divisão da circunferência em ângulos continua a ser feita


no sentido anti-horário. O comando arcn simplesmente anda na direção contrária
à marcação usual dos ângulos. Tudo o que pode ser feito com o comando arcn
pode ser feito com o comando arc, com os devidos ajustes.

4.2 Elipses
A PostScript é capaz de desenhar elipses através de um truque simples:
primeiro, desenhamos uma circunferência, depois “achatamos” sua altura ou seu
comprimento. Isso é conseguido com o comando scale:

newpath
1 0.3 scale % reduz a “altura” da circ. em 30%
300 400 80 0 360 arc
stroke

figura 4.2.1

O comando scale recebe dois argumentos. Ambos multiplicam o tamanho


natural de um desenho por um valor. Em nosso caso, o primeiro valor, 1, multipli-
cou o comprimento da figura por 1, ou seja, manteve o comprimento inalterado. O
segundo valor, 0.3, multiplicou a altura do desenho por 0,3. Em outras palavras,
fez com que o desenho ficasse com apenas 30% de sua altura original.
Em verdade, o comando scale altera as dimensões de todos os pontos da
página pelo valor informado. Se tivéssemos escrito em nosso programa

0.5 0.5 scale

teríamos reduzido as dimensões de todos os pontos da página para a metade, e


teríamos uma circunferência com a metade do diâmetro original. Discutiremos com
mais detalhes esse comando no próximo capítulo.

35
4.3 Efeitos de sombra
Um dos artifícios usados para se criar a ilusão de tridimensionalidade é a
presença de sombras no desenho. Em PostScript, esse efeito é conseguido por
meio de três desenhos sobrepostos, começando de baixo para cima: primeiro de-
senhamos a sombra, deslocada alguns pontos para a direita e para baixo, depois
desenhamos o interior branco do desenho e, por fim, desenhamos o contorno. Ob-
serve o código abaixo, escrito como três desenhos distintos por questões mera-
mente didáticas:

newpath % a sombra
305 395 50 0 360 arc
fill
stroke

newpath % o interior
300 400 50 0 360 arc
1 setgray
fill
stroke

newpath % o contorno
300 400 50 0 360 arc
0 setgray
stroke

figura 4.3.1

O raio do círculo de interior branco é de 50 pontos, com centro em (300,


400). Sua sombra, afastada para a direita e para baixo em 5 pontos, é um círculo
também de raio 50, mas de centro (305, 395). O desenho é feito de baixo para
cima porque o interior do círculo branco deve “apagar” o interior do círculo preto.
Sabemos como usar inteligentemente os comandos gsave e grestore
para economizar código. Seria possível utilizar esse par de comandos aqui?

4.4 Curvas de Bézier


Curvas de Bézier são importantes nas engenharias e na ciência da com-
putação. Essas curvas receberam esse nome em homenagem ao engenheiro fran-
cês Pierre Étienne Bézier (1910-1999), que as utilizou amplamente no design de
automóveis. Curvas de Bézier são criadas pelo comando curveto.
O comando curveto gera curvas de Bézier formadas por um ponto inicial e
um ponto final, mais pontos intermediários, ditos pontos de controle:

figura 4.4-a
Na curva da figura 4.4.1-a acima, temos os pontos P0 e P3 como pontos
inicial e final, respectivamente, e os pontos P1 e P2 como pontos de controle. Vi-
sualmente, a curva parece ser "atraída" pelos pontos de controle, sem passar por
eles, e se ligar aos pontos inicial e final tangenciando as linhas pontilhadas.
Se invertemos os pontos P1 e P2, a situação se modifica bastante:

figura 4.4-b

37
Agora a curva parte de P0 em direção a P1, é atraída por P2 e depois se
dirige a P3. É difícil prevermos o comportamento de curvas de Bézier, mesmo en-
tendendo suas equações. A maioria das vezes, usamos essas curvas por tentativa
e erro, mas depois de alguma prática acabamos com uma boa noção acerca de
seu funcionamento.
Observe agora o que ocorre quando unimos o ponto inicial ao ponto final:

figura 4.4-c

Vejamos agora como essas figuras foram geradas. O código seguinte


mostra apenas a curva da figura 4.4-a, sem as linhas pontilhadas e o nome dos
pontos.
/cm {28.35 mul} def % define centímetro
/P0 {1 cm 1 cm} def % define ponto P0
/P1 {1 cm 5 cm} def % define ponto P1
/P2 {4 cm 5 cm} def % define ponto P2
/P3 {5 cm 2 cm} def % define ponto P3

newpath
P0 moveto % move lápis até o ponto P0
P1 P2 P3 curveto % P1 e P2 de controle, P3 final
stroke

O programa inicia-se com uma seção de definições. Definimos a unidade


de medida (cm), e depois 4 pontos, P0, P1, P2 e P3.
Logo depois, começamos o desenho com newpath, e indicamos ao lápis
imaginário que se mova até o ponto P0. Logo após, dizemos ao comando curveto
quais são os dois pontos de controle e o ponto final da curva. Com o comando
stroke, a curva é desenhada.
Curvas de Bézier são bastante utilizadas em programas de ilustração veto-
rial. Um excelente programa gratuito é o Inkscape (www.inkscape.org), no qual po-
demos treinar nossa intuição geométrica relativa a curvas de Bézier.
4.5 Exercícios
1. Desenhe:
a) três circunferências concêntricas, com tonalidades diferentes de linha
b) duas circunferências de raios diferentes tangentes externamente
c) duas circunferências de raios diferentes tangentes internamente

2. Desenhe:
a) duas coroas circulares concêntricas
c) meia coroa circular
d) duas meias coroas circulares afastadas uma da outra em 1 mm

3. Desenhe:
a) um setor circular de 60o
b) um segmento circular de 60o
c) uma circunferência e seu diâmetro

4. Desenhe:
a) um triângulo retângulo escaleno inscrito em uma semicircunferência
b) uma circunferência, um ângulo central de 60 o e um ângulo inscrito de 30o
c) uma circunferência e duas cordas concorrentes que não sejam diâmetros

5. Desenhe duas circunferências de tamanhos diferentes e uma reta tangente às


duas

6. Desenhe uma circunferência usando curvas de Bézier. Compare-a com uma cir-
cunferência criada com o comando arc.

7. Desenhe uma espiral qualquer usando curvas de Bézier.

39
Capítulo 5
Transformações
Transformações planas como translações, rotações, homotetias e reflexões são
extremamente importantes do ponto de vista geométrico. Elas nos proporcionam
meios econômicos de realizarmos muitas ilustrações matemáticas. Este capítulo
introduz o uso das principais transformações no âmbito da linguagem PostScript.

5.1 O ponto corrente


Voltemos à metáfora do lápis invisível. Enquanto o lápis caminha fazendo
marcas invisíveis sobre o papel, seguindo as instruções de nosso programa, a
PostScript armazena as coordenadas do último ponto sobre o qual a ponta desse
lápis se apoiou. Esse é o chamado ponto corrente do desenho, cujas coordenadas
são obtidas através do comando currentpoint.
O comando currentpoint coloca na pilha as coordenadas do ponto corren-
te. Se a pilha se encontra, por exemplo, com os números

120 350 200 110

e a ponta do lápis parada sobre o ponto de coordenadas (200, 250), o comando


currentpoint faz com que a PostScript coloque essas coordenadas na pilha:

120 350 200 110 200 250

Esse comando é bastante útil com os comandos translate e rotate, vistos


nas seções seguintes.
5.2 Translação
A operação de translação consiste em mover a origem dos eixos coorde-
nados para uma nova posição, estabelecendo um novo ponto de referência para
as coordenadas dos desenhos. O comando que realiza essa operação é o trans-
late.
Antes de explicar o uso do comando, lembremo-nos que, inicialmente, a
origem do nosso sistema de coordenadas se encontra na extremidade inferior es-
querda da folha de papel:

figura 5.2-a

A seta que aponta da esquerda para a direita nos dá a direção do chama-


do eixo x; a que aponta de baixo para cima nos dá a direção do chamado eixo y. O
ponto (0, 0) é chamado de origem do sistema de coordenadas.
Para mudarmos a origem do sistema para outro ponto, usamos o comando
translate informando as coordenadas da nova origem. Por exemplo, se deseja-
mos transladar todo o sistema para o ponto de coordenadas (200, 250), fazemos

200 250 translate

e as coordenadas do desenho passam a ser referenciadas a partir desse novo


ponto:

41
figura 5.2-b

Com esse novo sistema, um ponto de coordenadas (300, 600), por exem-
plo, passa a ter coordenadas (100, 350), pois a origem do sistema se aproximou
dele 200 pontos na horizontal e 250 pontos na vertical.
Para ser executado, o comando translate usa os dois últimos números da
pilha. Se movermos a ponta de nosso lápis para as coordenadas (400, 500) e logo
depois acionarmos o comando currentpoint, teremos na pilha os números 400 e
500. O comando translate logo em seguida fará com que nosso sistema seja des-
locado para o ponto (400, 500). Assim, escrever

400 500 translate

é equivalente a

400 500 moveto


currentpoint % coloca 400 e 500 na pilha e
translate % translada o sistema para lá

5.3 Rotação
Como a translação, a rotação age sobre o sistema de coordenadas, giran-
do-o em sentido anti-horário. O comando que realiza a rotação é o rotate.
Volte à figura 5.2-a. Nela, a origem dos eixos coordenados está no canto
inferior esquerdo da folha de papel. O comando
45 rotate

gira o sistema em 45o no sentido anti-horário:

figura 5.3-a

Observe bem: se os eixos estão rotacionados em 45 o, a maneira de pen-


sarmos as coordenadas também muda. Por exemplo, o comando 200 0 rlineto, a
partir da origem do sistema, não vai marcar uma linha horizontal de 200 pontos de
comprimento na folha, mas uma de 200 pontos de comprimento na diagonal, ou
seja, no novo sentido do eixo x. Teste o programa abaixo para ver o que queremos
dizer.

newpath
60 rotate
0 0 moveto
200 0 rlineto
stroke

O comando rotate, combinado com translate e currentpoint, são capa-


zes de realizar façanhas nos desenhos. Por exemplo, o pentágono a seguir

43
figura 5.3-b

foi desenhado com o programa

newpath
100 100 moveto % move lápis para (100, 100)
currentpoint translate % translada para (100, 100)
50 0 rlineto % marca uma linha de 50 pontos
72 rotate % rotaciona o sistema em 72o
currentpoint translate % translada para a extremidade
50 0 rlineto
72 rotate
currentpoint translate
50 0 rlineto
72 rotate
currentpoint translate
50 0 rlineto
72 rotate
closepath
2 setlinewidth
stroke

O programa acima não será tão repetitivo quando aprendermos alguns


princípios de programação nos capítulos seguintes. Mas é um ótimo exemplo de
como podemos usar inteligentemente os comandos currentpoint, translate e ro-
tate. Vamos analisá-lo passo a passo.
Após o newpath, deslocamos a ponta de nosso lápis para as coordenadas
(100, 100). De lá evocamos o comando currentpoint, que coloca na pilha os nú-
meros 100 e 100, ou seja, coloca na pilha as coordenadas da ponta do lápis. Logo
depois, transladamos a origem de nosso sistema para esse ponto, com o comando
translate. Temos, nesse momento, a origem de nosso sistema no ponto (100,
100).
Da nova origem do sistema, marcamos uma reta de tamanho 50 pontos
para a direita. Nesse momento, a ponta do lápis está na extremidade mais à direita
desse segmento. Daí, giramos os eixos do sistema em 72 o e o deslocamos para
onde está a ponta do lápis. Estamos agora com a seguinte situação:

figura 5.3-c

Na figura acima vemos um segmento de reta com os novos eixos em uma


extremidade, rotacionados em 72o no sentido anti-horário. Vamos repetir o proces-
so: marcamos um novo segmento de 50 unidades na direção do novo eixo x, rota -
cionamos novamente o sistema e o deslocamos para a extremidade no novo seg-
mento. Ficamos com a seguinte situação:

figura 5.3-d

Repetindo todo o processo mais duas vezes, temos:

figura 5.3-e

Nesse momento, fechamos o desenho com o comando closepath, estipu-


lamos a espessura da linha em dois pontos e, com o comando stroke, traçamos
as linhas, e ficamos com a figura 5.3-b.
É importante ter em mente: a origem e a orientação do sistema ainda se
encontram na posição anterior ao closepath. O ideal é repetir mais uma vez os
comandos 50 0 rlineto, 72 rotate e currentpoint translate antes do closepath.

45
Assim, garantiríamos que a origem do nosso sistema se encontra exatamente nas
coordenadas iniciais do desenho. Se desejamos que a origem volte para o canto
inferior esquerdo da página, fazemos

-100 -100 translate

desfazendo a primeira translação realizada.


Teremos a oportunidade de trabalhar com esses comandos em muitas
ilustrações. Tente fazer um hexágono apenas para se acostumar com com eles,
lembrando-se de que a rotação necessária nesse caso é de 60 o.

5.4 Ampliação e redução


Um desenho pode ser ampliado, reduzido e invertido com o comando sca-
le, que introduz na linguagem PostScript a noção matemática de homotetia.
Em verdade, o comando scale amplia ou reduz o tamanho do ponto
PostScript. Não amplia ou reduz a figura, mas os pontos que a constituem. Sua
forma geral é

x y scale

em que x é o fator de ampliação ou redução na direção horizontal e y o fator de


ampliação ou redução na vertical. Se x é maior que 1, o ponto PostScript será am-
pliado na direção x; se ficar entre 0 e 1, estamos diante de uma redução na mes-
ma direção. O mesmo ocorre com o argumento y.
Vamos pensar a partir de um exemplo. Suponha que queremos desenhar
um quadrado com 50 pontos de lado. Usaremos o código a seguir, mas ampliando
os pontos 4 vezes na direção x:

newpath
4 1 scale % multiplica por 4 na horizontal
% e 1 na vertical
50 50 moveto
50 0 rlineto
0 50 rlineto
-50 0 rlineto
closepath
stroke
Esse programa começa com o comando 4 1 scale. Isso significa que qua-
druplicamos as dimensões do ponto na horizontal, e mantemos a espessura 1 na
vertical. Nesse novo sistema, uma linha de 50 pontos na horizontal será 4 vezes
maior do que uma linha com 50 pontos na vertical. Por isso, apesar de traçarmos
um quadrado de lado 50, teremos, na prática, um retângulo de proporções 4:1,
como na figura a seguir:

figura 5.4

Repare também que os lados verticais ficaram mais espessos do que os


lados horizontais. Isso porque, como dissemos, ampliamos os pontos 4 vezes na
direção x. Os pontos, portanto, são quatro vezes maiores na horizontal do que na
vertical, ou seja, são retângulos de proporções 4:1. Essa característica, a de am-
pliar não a figura em si, mas os pontos que a constituem, fazem com que o co -
mando scale produza resultados por vezes imprevisíveis. Mas é um uma boa al-
ternativa para criar os efeitos que passamos a descrever.

5.5 Reflexão
O comando scale, como vimos, tem 2 argumentos: um para ampliação ou
redução na direção x, e outro na direção y. Podemos utilizá-lo para espelhar uma
figura em relação a um desses eixos. Por exemplo, considere o triângulo retângulo
abaixo:

figura 5.5-a

Se desejamos o mesmo triângulo espelhado em relação ao eixo y, como


na figura seguinte,

47
figura 5.5-b
basta acrescentarmos a linha

-1 1 scale

depois da última translação efetuada. Sim, é necessário que os eixos do desenho


estejam transladados para algum ponto mais ao centro da folha, pois senão o re -
sultado estará fora dos limites da folha, e você não conseguirá visualizá-lo.

5.6 Exercícios
1. Usando o comando translate pelo menos duas vezes no código do programa,
desenhe:
a) três segmentos de reta paralelos
b) três quadrados unidos por um de seus vértices
c) três circunferências de mesmo raio tangentes entre si duas a duas

2. Usando os comandos rotate e translate, desenhe:


a) um triângulo equilátero
b) um hexágono
c) um triângulo retângulo com a hipotenusa paralela à base da folha

3. Usando o comando scale, desenhe:


a) três circunferências concêntricas
b) dois triângulos equiláteros espelhados por um eixo paralelo a um dos lados
c) como no exercício anterior, mas com um dos triângulos com 1/3 do tamanho do
outro
Capítulo 6
Elementos de programação
No capítulo anterior, aprendemos os importantes comandos currentpoint, transla-
te, rotate e scale, que nos possibilitaram realizar desenhos de maneira mais sim-
ples e inteligente. Neste capítulo, daremos um passo adiante e aprenderemos
como realizar tarefas repetitivas, entender os conceitos de procedimento e de ar-
ray (vetor).

6.1 O comando de repetição repeat


Vamos reescrever o programa para desenhar o pentágono do capítulo an-
terior. Originalmente, o programa repetia 4 vezes as seguintes três linhas

currentpoint translate
50 0 rlineto
72 rotate

e o quinto lado do pentágono era resolvido com o comando closepath. Não há


nada de errado nisso, mas vamos agora reescrevê-lo de maneira que ele repita a
operação 5 vezes, deixando ao comando closepath a tarefa de fazer apenas o ar-
remate final:

newpath
100 100 moveto
currentpoint translate
50 0 rlineto
72 rotate
currentpoint translate
50 0 rlineto

49
72 rotate
currentpoint translate
50 0 rlineto
72 rotate
currentpoint translate
50 0 rlineto
72 rotate
currentpoint translate
50 0 rlineto
72 rotate
closepath
stroke

Essa é uma maneira um tanto cansativa de desenharmos um pentágono.


Não seria interessante se pudéssemos informar ao interpretador que algumas li-
nhas devem ser repetidas, economizando nosso tempo de digitação? Isso é possí-
vel com o comando repeat, que tem a seguinte estrutura:

número { ...
...
... } repeat

em que número é o numero de vezes que o código entre as chaves devem ser re-
petidos.
No programa do pentágono, esse comando é utilizado assim:

newpath
100 100 moveto
5 { currentpoint translate % início do repeat
50 0 rlineto
72 rotate } repeat % fim do repeat
closepath
stroke

Veja que o código acima produz exatamente o mesmo resultado, um pen-


tágono, mas agora com muito menos digitação. Além disso, revelou um padrão re -
petitivo, um pequeno programa dentro do programa, que poderá ser utilizado pos-
teriormente para realizar tarefas semelhantes.
Vamos agora desenhar uma estrela:
figura 6.1

Considerando que o desenho começa da ponta inferior esquerda, então


um programa possível é:

newpath
100 100 moveto
72 rotate % rotação inicial
5 { currentpoint translate % início do repeat
100 0 rlineto % lado de 100 pontos
-144 rotate } repeat % fim do repeat
closepath
stroke

Observe que o programa é extremamente semelhante ao do pentágono,


exceto pelo tamanho do lado e pelos ângulos de rotação. Também é notável a ro-
tação inicial dos eixos até que o programa comece a se repetir.
É possível desenhar essa estrela sem a rotação inicial. Você saberia es-
crever um programa assim, possivelmente começando de outro ponto?
Um segundo comando de repetição importante é o for, presente em quase
todas as linguagens de programação usuais. Sua sintaxe é

início passo fim { ...


...
... } for

ou seja, é uma estrutura como a do repeat, mas toma três números, chamados
início, passo e fim, para funcionar.
O início indica de que número partimos, e o fim, o número que desejamos
atingir. O passo indica o tamanho do “pulo” que damos até chegar lá. Por exem-

51
plo, se os número são 0 10 50, isso significa que, partindo de 0, avançaremos de
10 em 10 até alcançarmos 50, ou seja, geraremos a sequência 0, 10, 20, 30, 40,
50. Um exemplo vai esclarecer melhor esse comando.
Suponha que você deseja desenhar a figura seguinte:

figura 6.1-b

A figura 6.1-b consiste em 60 raios de 70 pontos de comprimento partindo


do centro da figura. A ângulo entre cada dois raios é de 6 o.
Se inicialmente transladamos nosso sistema de eixos para as coordena-
das (200, 200), podemos usar o comando for da seguinte maneira:
1 1 60 { ...
...
... } for

ou seja, 60 raios, começando do 1 e chegando até 60, pulando de 1 em 1.


O que está dentro do comando for? Apenas as linhas

0 0 moveto
70 0 rlineto
6 rotate

ou seja, movemos o lápis para a origem das coordenadas, traçamos uma linha de
70 pontos, e giramos os eixos. Fazemos isso 60 vezes, o que nos dá o programa
completo:
newpath
200 200 translate
0 0 moveto
1 1 60 {
0 0 moveto
70 0 rlineto
6 rotate} for
stroke

O comando repeat costuma ser suficiente para a maioria de nossas apli-


cações. O comando for serve de alternativa, e tem a virtude de explicitar o come-
ço, o passo e o fim de nosso laço de repetição, trazendo clareza para nossos pro -
gramas.

6.2 Procedimentos
Vimos que o comando def é usado para dar um nome a trechos de código,
nome que pode ser usado no corpo do programa como um novo comando. Em
nossa definição de centímetro

/cm {28.35 mul} def

o trecho de código {28.35 mul} ganha o nome cm. Sempre que o interpretador en-
contra cm no código, imediatamente o substitui por {28.35 mul}. Essa ideia pode
ser generalizada. No lugar de apenas um pequeno trecho de código, podemos de -
finir procedimentos inteiros.
Por exemplo, o trecho repetitivo que desenha a estrela

currentpoint translate
100 0 rlineto
-144 rotate

pode ganhar um nome, digamos, lado, e ser declarado no início do programa:

/lado {currentpoint translate % procedimento lado


100 0 rlineto
-144 rotate } def
newpath
100 100 moveto

53
72 rotate
5 {lado} repeat % usando o procedimento lado
closepath
stroke

O programa faz o mesmo desenho. Mas quando lemos o programa, come-


çamos com o que está entre newpath e stroke, e percebemos que, depois de um
movimento e uma rotação de eixos, o procedimento lado é executado cinco vezes.
Essa é a lógica, o propósito do programa. A lógica do procedimento lado é enten-
dida depois, se desejamos ir mais à fundo e entender os detalhes do procedimen -
to.
Podemos usar procedimentos dentro de procedimentos. Se queremos de-
senhar uma estrela de 5 cm de lado, declaramos /cm {28.35 mul} def antes do
procedimento lado e nele substituímos 100 0 rlineto por 5 cm 0 rlineto.
Procedimentos são os candidatos mais fortes para se tornarem trechos de
outros programas, através do recurso de copiar e colar. Um bom procedimento
pode ser aproveitado várias vezes em outros programas. Em verdade, programa -
dores costumam criar arquivos sem um programa principal contendo apenas uma
série de procedimentos reutilizáveis. Esses arquivos são chamados de bibliotecas,
usados por outros programas. É uma maneira de não termos que inventar a roda a
cada novo programa.

6.3 Arrays (vetores)


Um array, ou vetor, é simplesmente um conjunto de dados delimitado por
colchetes:

[20 40 70 10 50]

O vetor [20 40 70 10 50] tem cinco elementos. Dizemos que o primeiro


elemento, 20, está na posição zero, ou seja, tem índice 0. O segundo elementos
tem índice 1, e assim por diante, até o quinto elemento, 50, que tem índice 4. Ou
seja, um vetor de cinco elementos está enumerado de 0 a 4. Um vetor de 100 ele-
mentos estaria enumerado de 0 a 99.
Vetores são úteis quando precisamos lidar com dados externos, ou dados
que aparentemente não têm uma lógica interna. Suponhamos que o vetor [20 40
70 10 50] represente o lucro de uma empresa, em milhões de rais, durante um pe-
ríodo de 5 anos. Um gráfico de barras seria bastante adequado para visualizarmos
a evolução do lucro:
figura 6.3
Como realizar esse gráfico da maneira mais simples? Como escrever um
programa que desenhe gráficos de barra para vetores de qualquer tamanho?
Primeiro, vamos dar um nome ao nosso vetor, apenas por comodidade:

/dados [20 40 70 10 50] def

Agora podemos usar a palavra dados para nos referirmos ao vetor que
nos interessa. Futuramente, quando desejarmos trocar os dados, bastará substituir
o vetor original por outro.
Logo em seguida, vamos escrever o programa que realizará o gráfico:

newpath
100 100 translate
0 0 moveto
20 setlinewidth
dados {barra} forall % comando forall
stroke

O programa começa com o tradicional newpath, seguido de uma transla-


ção, um movimento até a nova origem e a especificação de que usaremos uma li-
nha com 20 pontos de espessura. A linha seguinte é o coração do programa:

dados {barra} forall

O comando forall recebe dois argumentos como entrada: um vetor e um


procedimento. Esse comando percorre os elementos do vetor, um a um, e realiza
sobre cada um deles o procedimento que aqui chamamos de barra. Quando o fo-
rall termina de percorrer todos os elementos do vetor, o comando stroke gera o
gráfico resultante.
Como funciona o procedimento barra? O procedimento barra, que deve
ser declarado logo depois do vetor dados, é o seguinte:

/barra {dup 0 exch rlineto 30 exch neg rmoveto} def

55
Vamos explicar seu funcionamento, que é bem simples.
O comando forall percorre o vetor, do primeiro ao último elemento, e colo-
ca na pilha o elemento da vez. No começo, ele encontra o primeiro elemento, 20, e
o coloca na pilha. Agora tem início o procedimento barra: ele duplica o elemento
com o comando dup, acrescenta 0 à pilha e, com o comando exch, troca de posi-
ção os dois últimos elementos. Nesse momento, a pilha é

20 0 20

O comando rlineto toma os dois últimos elementos da pilha, 0 e 20, e tra-


ça uma linha de 20 pontos de altura. Na pilha resta agora apenas o número 20, e a
ponta do lápis se encontra sobre o topo da primeira barra.
Logo em seguida, o número 30 é acrescentado à pilha, o comando exch o
troca de posição com o número 20 e o comando neg o transforma em -20. A pilha,
nesse momento, tem os seguinte elementos:

30 -20

Finalmente, o comando rmoveto parte do topo da primeira barra, toma 30


e -20 como argumentos, desloca a ponta do lápis 30 pontos para a direita e 20
pontos para baixo, posiciona a ponta do lápis na base da barra seguinte, que será
desenhada da mesma maneira. Assim será com todos os elementos, até que o co-
mando forall chegue ao fim do vetor.
O programa completo, da maneira que de agora em diante passaremos a
escrever, é o seguinte:
% procedimentos
/vetor [20 40 70 10 50] def
/barra {dup 0 exch rlineto 30 exch neg rmoveto} def

% rotina principal
newpath
100 100 translate
0 0 moveto
20 setlinewidth
vetor {barra} forall
stroke

A separação entre a declaração dos procedimentos e a rotina principal au-


menta a legibilidade do programa. Frequentemente precisamos ler nossos próprios
programas, e quase sempre teremos nos esquecido de como foi que pensamos
para criar esse ou aquele trecho de código.
6.4 Exercícios
1. Desenhe:
a) um hexágono regular
b) uma estrela de 11 pontas
c) um quadriculado para o jogo-da-velha
d) um tabuleiro de xadrez

2. Desenhe a pseudo-espiral áurea:

O retângulo externo tem proporções aproximadas de 1:1.618. Observe


que o padrão visual dessa figura é um quadrado com um arco de circunferência in-
terno, reduzido e reposicionado em relação ao quadrado original várias vezes até
ficar bem pequeno, dando a impressão de um processo infinito.

3. Modifique o programa de gráfico de barras da seção 6.3 de maneira que:


a) as barras tenham espessura de 1 cm, afastadas umas das outras em 0,5 cm
b) as barras estejam posicionadas na horizontal, sem o emprego do comando ro-
tate
c) as barras sejam substituídas por uma pequena circunferência na altura indicada

57
Capítulo 7
Fontes
Fontes constituem um assunto extenso na linguagem PostScript. Em verdade, a
PostScript foi criada com a intenção de servir como instrumento de formatação de
textos, e apenas secundariamente como ferramenta de desenho digital.
Apesar da extensão do assunto e da profusão de comandos da linguagem
PostScript que manipulam fontes, estudaremos neste capítulo apenas aqueles que
nos permitem imprimir letras na tela, e com isso nomear pontos, segmentos, cir-
cunferências e todos os demais elementos gráficos que servem à nossa intenção
de criar ilustrações matemáticas.

7.1 Fontes PostScript


Quando instalamos o GhostScript em nosso computador, ganhamos gra-
tuitamente também 35 fontes PostScript. Essa fontes, cujos nomes e formatos se
encontram no Apêndice C, serão usadas para nomearmos os elementos de nos-
sos desenhos.
Diferentemente das fontes que usamos em programas como Microsoft
Word, OpenOffice e outros, as fontes PostScript não estão disponíveis para esco-
lha em um menu. O acesso e a manipulação dessas fontes é feito através de uma
série de comandos específicos muito simples e intuitivos, que passaremos a expli-
car a seguir.

7.2 Principais comandos


Os principais comandos para operarmos com fontes em PostScript são 4:
findfont, scalefont, setfont e show. Na maioria das vezes, são utilizados como
se fossem um só, cada um responsável por uma parte do trabalho de imprimir na
tela uma letra ou um texto inteiro.
O comando findfont opera procurando no comutador a fonte desejada.
Por exemplo, se desejamos utilizar a fonte Helvetica (da qual a fonte Arial é uma
cópia ligeiramente modificada), usamos o comando

/Helvetica findfont

A fonte Helvetica é apenas uma das 35 fontes convencionais à disposição


do usuário no catálogo de fontes que acompanha o programa GhostScript, arma-
zenada em um diretório próprio. O Apêndice C, que lista as 35 fontes disponíveis,
deve ser consultado para a escolha de outras fontes.
Após a determinação da fonte, será necessário dizer ao interpretador
PostScript que tamanho ela terá. Usamos o comando scalefont, precedido do ta-
manho da fonte, em pontos, para essa função:

/Helvetica findfont 12 scalefont

Observe que estipulamos a medida de 12 pontos para a fonte. Logo após


a escolha do tamanho, o comando setfont diz que é aquela fonte, naquele tama-
nho, que será usada no programa daí em diante:

/Helvetica findfont 12 scalefont setfont

Agora estamos aptos a escrever com a fonte Helvetica, de tamanho 12,


em qualquer lugar da tela. A linha acima, com os comandos findfont, scalefont e
setfont costuma ser escrita como fizemos, como se fosse apenas um grande co-
mando composto.
Uma vez selecionada, escalada e estabelecida a fonte, como fazemos
para escrever na tela? Primeiramente, devemos mover o lápis para a posição de-
sejada:

/Helvetica findfont 12 scalefont setfont


200 300 moveto

Depois, colocamos nosso texto entre parênteses e adicionamos ao fim o


comando show:

/Helvetica findfont 12 scalefont setfont


200 300 moveto
(Eis aqui um texto!) show

59
Com isso, devemos ver o texto “Eis aqui um texto!” localizado na posição
(200, 300) de nossa folha. A posição (200, 300) se refere ao canto inferior esquer-
do do texto todo.
Para desenhar mais um texto, digamos, 15 pontos abaixo do texto anterior,
basta movermos a ponta do lápis até lá e escrever:

/Helvetica findfont 12 scalefont setfont


200 300 moveto
(Eis aqui um texto!) show
200 285 moveto
(E eis aqui um outro texto!!) show

O programa acima gera o seguinte texto:

figura 7.2-a

como esperávamos. Não se esqueça de que as coordenadas de cada linha, dadas


como parâmetros ao comando moveto, referem-se ao canto inferior esquerdo de
cada texto. Em nosso caso, às beiradas de baixo das letras “E”.
Podemos escrever o texto inclinado, ou em qualquer direção que desejar-
mos. Basta tratarmos o texto como um desenho qualquer.. Observe que o progra-
ma abaixo
/Helvetica findfont 12 scalefont setfont
200 300 translate
45 rotate
0 0 moveto
(Eis aqui um texto!) show

irá imprimir “Eis aqui um texto!” nas coordenadas (200,300) – agora a nova origem
de nosso sistema – girado 45o no sentido anti-horário:
figura 7.2-b
Um comando como, por exemplo, -1 1 scale, poderá ser usado livremente,
como em um desenho qualquer:

figura 7.2-c
Enfim, sobre textos podemos operar exatamente como com qualquer outro
elemento gráfico.

7.3 Outros comandos


Uma variação interessante do comando show é o comando ashow. Ele
provê maior flexibilidade na disposição das letras do texto a ser exibido.
O comando ashow recebe 3 argumentos, dois números e o texto entre pa-
rênteses:

12 0 (Eis aqui um texto!) ashow

e mostra na tela o mesmo texto, mas agora com as letras separadas 12 pontos
umas das outras na direção horizontal:

figura 7.3-a

Outro comando interessante é o charpath, que mostra apenas o contorno


da letra, sem preenchê-la por dentro. O programa seguinte

61
/Helvetica findfont 24 scalefont setfont
200 300 moveto
(Eis aqui um texto!) true charpath
stroke

desenha apenas o contorno das letras, agora com o tamanho 24:

figura 7.3-b

Observe que o comando charpath foi precedido não só do texto a ser im-
presso, mas da palavra true.

7.4 Exercícios
1. Desenhe um triângulo escaleno e rotule seus vértices as letras A, B e C.
2. Coloque as letras X e Y nos eixos da figura 1.1.
3. Nomeie os elementos do Teorema de Tales dos exercícios da seção 2.4.
4. Coloque as letras A, B, C, D, e E nos vértices da estrela da figura 6.1
5. Escreva seu nome espelhado.
Capítulo 8
Acabamentos, cores e clipping
Neste capítulo, vamos tratar de comandos que interferem diretamente na apresen-
tação das ilustrações, principalmente no seu acabamento e na sua cor, levando
uma qualidade estética superior às ilustrações.
Apresentamos também o conceito de clipping (recorte), em que usamos
uma figura para delimitar outra.

8.1 Acabamentos
Há três tipos de terminações para uma linha qualquer: linhas sem termina-
ção, linhas com terminação arredondada e linhas com terminação quadrada, como
nos mostra a figura a seguir:

figura 8.1-a

A linha de baixo, com uma linha em branco bem no meio (representando


o caminho abstrato que a PostScript faz antes de passar a tinta), mostra o padrão
de acabamento de linhas da linguagem PostScript. Não é necessário nenhum co-
mando para que as linhas fiquem assim.
A linha do meio mostra extremidades arredondadas, o que aumenta um
pouco o tamanho da linha.

63
A linha de cima mostra extremidades “quadradas” com um ligeiro acrésci-
mo em seu tamanho. Tanto neste quanto no acabamento anterior, o caminho é
“envolvido” pela tinta, o que não acontece no acabamento padrão.
As diferenças entre um e outro acabamento são conseguidas com o co-
mando setlinecap, com os argumentos 0 (o padrão), 1 ou 2. Por exemplo, a linha
do meio é conseguida com o comando

1 setlinecap

A escolha de um ou outro acabamento para a linha vai depender apenas


dos efeitos estéticos desejados.
Linhas podem também apresentar os seguintes efeitos quando unidas
umas às outras:

figura 8.1-b

O tipo de união de linhas na parte de baixo da figura é o padrão, a maneira


que temos utilizado até agora. O tipo de união de linhas no meio da figura mostra
que a PostScript pode arredondar as beiradas de uma figura para nós. Finalmente,
o tipo de união de linhas do topo da figura mostra que a PostScript também pode
cortar um pouco de cada linha, caso não desejemos que a união seja pontuda ou
arredondada.
O comando que usamos para selecionar uma ou outra maneira de unir li-
nhas é o setlinejoin, com argumentos 0 (o padrão), 1, ou 2. Por exemplo, se de-
sejamos uma união de linhas como aquela do topo da figura, escrevemos

2 setlinejoin

Observe que o padrão adotado pela PostScript (0 setlinejoin) aumenta li-


geiramente o tamanho da figura. Isso é ainda mais notável quanto menor for o ân -
gulo que uma linha faz com a outra. Nesses casos, o melhor é usar 2 setlinejoin.
8.2 Cores
A PostScript usa o padrão RGB (Red, Green, Blue – Vermelho, Verde,
Azul) para escolher a cor da tinta que usará. Esse padrão é dito aditivo, e cria co-
res a partir da mistura de vermelho, verde e azul.
O comando que faz essa seleção é o setrgbcolor, com três argumentos,
cada um variando de 0 a 1. Por exemplo, se desejamos uma linha com 10 pontos
de espessura, mas da cor vermelha, devemos inserir no programa o seguinte co-
mando

1 0 0 setrgbcolor

o que produziria a figura abaixo:

figura 8.2-a

Retome o programa que gerou a figura 3.2. Suponha agora que você de-
seja um quadrado amarelo cercado por uma borda azul. No lugar de setgray, você
deveria usar, para o amarelo,

1 1 0 setrgbcolor

e, para o azul,

0 0 1 setrgbcolor

gerando a figura

figura 8.2-b

65
No padrão RGB, o amarelo é criado pela adição de vermelho e verde.
Quais cores são criadas pela adição de vermelho e azul, e verde e azul? Teste
com o programa acima, e confira.
Observe também que escrever 0.5 0.5 0.5 setrgbcolor produz o mesmo
efeito de 0.5 setgray. Cinzas são criados com a adição de partes iguais de verme-
lho, verde e azul.
Existem outros sistemas de cores, mas é importante conhecer bem o pa-
drão RGB, usado também nos códigos de cores da linguagem HTML.

8.3 Clipping
Suponha que você deseja cria uma figura como a seguinte

figura 8.3-a
Como isso pode ser feito? O trabalho de calcular o tamanho de cada raio
parece muito difícil. Não seria melhor se desenhássemos primeiro

figura 8.3-b
e depois recortássemos um quadrado lá de dentro?
É exatamente essa a ideia de clipping: um recorte. Primeiro desenhamos a
figura com o programa

newpath
200 200 translate
0 0 moveto
72 {0 0 moveto
70 0 rlineto
5 rotate} repeat
stroke

mas antes definimos a figura que recortará essa:

150 150 moveto


100 0 rlineto
0 100 rlineto
-100 0 rlineto
0 -100 rlineto
clip % o comando clip no lugar de stroke

Observe que o quadrado que será recortado termina com o comando clip,
indicando que aquele é um caminho de recorte, não um caminho sobre o qual será
passada tinta com o comando stroke. O programa completo fica

150 150 moveto % o recorte


100 0 rlineto
0 100 rlineto
-100 0 rlineto
0 -100 rlineto
clip

newpath % a figura
200 200 translate
0 0 moveto
72 { 0 0 moveto
70 0 rlineto
5 rotate} repeat
stroke

67
O caminho de recorte pode ser qualquer desenho fechado. Basta declará-
lo logo no início.

8.4 Exercícios
1. Retome os três primeiros exercícios do capitulo 3 e substitua as linhas cinzas e
pontilhadas por linhas coloridas à sua escolha.

2. Escreva um texto de três palavras, cada uma com uma cor diferente.

3. Desenhe a figura abaixo (use clipping):


Bibliografia
ADOBE SYSTEMS. PostScript Language: Tutorial and Cookbook. Reading: Addi-
son-Wesley, 1985.

______________. PostScript Language Program Design. Reading: Addison-Wes-


ley, 1988.

______________. PostScript Language Reference Manual. 3rd edition. Reading:


Addison-Wesley, 1999.

______________. PostScript Language Reference Supplement. Reading: Addison-


Wesley, 1999.

CASSELMAN, Bill. Mathematical Illustrations: A Manual of Geometry and PostS-


cript. Cambridge: Cambridge University Press, 2005.

______________. Pictures and Proofs. In: Notices of AMS, volume 47, n. 10, pp.
1257-1266. Providence: AMS, 2000.

HOLZGANG, David A. Understanding PostScript Programming. 2nd edition. Berke-


ley: Sybex Inc., 1988.

McGILTON, Henry, e CAMPIONE, Mary. PostScript by Example. Reading: Addi-


son-Wesley, 1992.

REID, Glenn C. Thinking in PostScript. Reading: Addison-Wesley, 1990.

69
ROTH, Stephen. Real World Postscript: Techniques from Postscript Professionals.
Reading: Addison-Wesley, 1988.

SMITH, Ross. Learning PostScript: a Visual Approach. Berkeley: Peachpit Press,


1990.
Apêndices
A - Preparando o ambiente
Para utilizar a PostScript em ambiente Windows, você precisará de um
editor de texto simples, como o Bloco de Notas, e os programas GhostScript e GS-
View.
Esse programas serão usados em conjunto da seguinte maneira: o Bloco
de Notas será usado na escrita dos programas, e o GhostScript interpretará esses
programas, transformando-os em desenhos que serão visualizados na tela do
computador pelo GSView ou enviado diretamente para impressão em uma folha
de papel.
O Bloco de Notas vem com o Windows. Para instalar o GhostScript e o
GSView, siga os passos abaixo:
• Acesse a página http://pages.cs.wisc.edu/~ghost/
• Escolha a versão mais nova de "GPL GhostScript" e clique no link para
acessar a página de downloads. No fim da página, na seção "Microsoft
Windows", escolha a versão de 32 ou 64 bits, segundo a arquitetura de
seu computador. Na dúvida, escolha a versão de 32 bits. Clique no link e
baixe o arquivo em uma pasta de seu computador.
• Volte à página indicada e baixe também a mas recente versão do progra-
ma GSView.
• Acesse a pasta em que você gravou os dois programas e instale PRIMEI-
RO o GhostScript. Basta dar dois cliques no arquivo baixado e selecionar
"Setup" na primeira janela que aparecer, e em "Install" na segunda. O
GhostScript será instalado.
• Agora instale o GSView. Dê dois cliques no arquivo e clique em "Setup" na
primeira janela que aparecer. Logo depois, haverá uma nova janela para
escolha da língua. Escolha uma de sua preferência (infelizmente, o pro-
grama não dá a opção de escolher português). Vá clicando em "Next" a
cada nova janela, e no final em "Exit".

71
Pronto! Você já pode programar em Postscript e visualizar arquivos de ex-
tensão ps, a extensão em que devemos gravar os arquivo de agora em diante.
Observe que os programas acima são distribuídos pela internet. É possível
que, no momento em que você lê este livro, a página onde estão disponíveis tenha
mudado de endereço. Com a ajuda de algum buscador de sua preferência, procu-
re o novo endereço, acesse a nova página, e siga os passos acima.
B - Trabalhando com PostScript
Existe uma metodologia simples para trabalharmos com a PostScript:
• Abra o Bloco de Notas e crie um arquivo com o nome que desejar, salvan-
do-o com a extensão ps em algum diretório de seu computador. Por exem-
plo, se você deseja que seu gráfico se chame meugrafico, salve-o como
"meugrafico.ps". Mantenha o Bloco de Notas aberto.
• Abra o GSView. Clique no botão "OK" na janela que vai aparecer no centro
da tela. Agora abra o arquivo "meugrafico.ps". Por enquanto, nada deve
aparecer na tela.
Nesse momento, você deve estar com duas janelas abertas no seu com-
putador, uma para o Bloco de Notas e outra para o GSView. Para verificar se seu
sistema está bem configurado, digite, no arquivo "meugrafico.ps", as seguintes li-
nhas de código:

newpath
0 0 moveto
250 250 lineto
stroke

Salve o arquivo e observe o resultado no GSView. Uma linha diagonal


deve aparecer no canto inferior esquerdo da página. Se necessário, role a página
para baixo ou diminua o zoom. Se você ainda não viu a linha, aperte a tecla "R"
para atualizar a página. Agora você deve ter visto o gráfico, no canto inferior es-
querdo, e já sabe como proceder de agora em diante.

Trabalhando interativamente
Outra maneira de trabalhar com PostScript é interativamente, digitando
cada uma das linhas acima em um prompt de comandos do GhostScript. Nesse
caso, você precisará acrescentar o comando showpage no final do código para
que seu desenho seja mostrado em uma nova janela. Maximize essa nova janela
para visualizar o seu desenho. Após visto o desenho, aperte a tecla enter para vol -
tar ao prompt de comando. Proceda dessa maneira para testar trechos de seu có-
digo.
Esse método, porém, é recomendado apenas para testes rápidos, e não
para desenvolvimento de longos desenhos.

73
C – Fontes PostScript
As 35 fontes padronizadas da linguagem PostScript são:
Além dessas, existem muitas outras fontes disponíveis gratuitamente na
internet. Versões recenes do programa Ghostscript trazem muitas outras não lista -
das aqui.
A instalação de fontes PostScript está explicada em (Adobe Systems,
1999).

75
D - Criando um arquivo EPS
Arquivos EPS (Encapsulated PostScript) são extensamente utilizados na
indústria gráfica, pois permitem incorporar os gráficos gerados em documentos di-
versos. Em particular, os arquivos EPS são a opção preferencial de gráficos para o
sistema de tipografia LaTeX, e por isso muito importantes na área científica.
A geração de um arquivo EPS é simples:
• Depois de visualizado o gráfico desejado pelo GhostView, acesse o menu
“File” e clique na opção “PS to EPS”
• Nas próximas duas caixas de diálogo que aparecerem, clique em “Yes” ou
“Sim”, e escolha a pasta de destino onde será gerado o arquivo EPS.
O arquivo EPS gerado pode ser convertido para outros formatos, segundo
a conveniência. Um programa gratuito muito bom para visualizar e converter os ar-
quivos EPS em um grande número de outros formatos é o IrfanView, gratuitamen-
te disponível na internet.

Você também pode gostar