Little bit more of the proof.
[yomcat.git] / dcpic.sty
blobed01a29756091ecacf2eb76fa1bccd1a326a77ae
1 % $Id: dcpic.sty,v 1.31 2007/12/13 17:34:57 pedro Exp pedro $
2 %% DC-PiCTeX
3 %% Copyright (c) 1990-2007 Pedro Quaresma de Almeida, Coimbra
4 %% 11/1990 (version 1.0);
5 %% 10/1991 (version 1.1);
6 %% 9/1993 (version 1.2);
7 %% 3/1995 (version 1.3);
8 %% 7/1996 (version 2.1);
9 %% 5/2001 (version 3.0);
10 %% 11/2001 (version 3.1);
11 %% 1/2002 (version 3.2)
12 %% 5/2002 (version 4.0);
13 %% 3/2003 (version 4.1);
14 %% 12/2004 (version 4.1.1)
15 %% 3/2007 (version 4.1.2)
17 \immediate\write10{Package DCpic 2007/03/01 v4.1.2}
19 \ProvidesPackage{../dcpic}[2007/03/01 v4.1.2]
21 %% Version X.Y.Z
22 %% X - major versions
23 %% Y - minor versions
24 %% Z - bug corrections
26 %% Copyright (c) 1990-2007 Pedro Quaresma <pedro@mat.uc.pt>
27 %% The DCpic package is free software; you can redistribute it and/or
28 %% modify it under the terms of the GNU General Public License as
29 %% published by the Free Software Foundation; either version 2 of the
30 %% License, or (at your option) any later version.
32 %% The DCpic package is distributed in the hope that it will be
33 %% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
34 %% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 %% General Public License for more details.
37 %% You should have received a copy of the GNU General Public License
38 %% along with this package; if not, write to the Free Software
39 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 \catcode`!=11 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)
44 \newcount\aux%
45 \newcount\auxa%
46 \newcount\auxb%
47 \newcount\m%
48 \newcount\n%
49 \newcount\x%
50 \newcount\y%
51 \newcount\xl%
52 \newcount\yl%
53 \newcount\d%
54 \newcount\dnm%
55 \newcount\xa%
56 \newcount\xb%
57 \newcount\xmed%
58 \newcount\xc%
59 \newcount\xd%
60 \newcount\ya%
61 \newcount\yb%
62 \newcount\ymed%
63 \newcount\yc%
64 \newcount\yd
65 %% "variáveis globais"
66 \newcount\expansao%
67 \newcount\tipografo% versão 4.0
68 \newcount\distanciaobjmor% versão 4.0
69 \newcount\tipoarco% versão 4.0
70 %\newif\ifarredondada% versão 4.0 (valor inicial "false")
71 \newif\ifpara%
72 %% version 3.2
73 \newbox\caixa%
74 \newbox\caixaaux%
75 \newif\ifnvazia%
76 \newif\ifvazia%
77 \newif\ifcompara%
78 \newif\ifdiferentes%
79 \newcount\xaux%
80 \newcount\yaux%
81 \newcount\guardaauxa%
82 \newcount\alt%
83 \newcount\larg%
84 \newcount\prof%
85 %% para os ajustes
86 \newcount\auxqx
87 \newcount\auxqy
88 \newif\ifajusta%
89 \newif\ifajustadist
90 \def\objPartida{}%
91 \def\objChegada{}%
92 \def\objNulo{}%
95 %%
96 %% Stack specification
100 %% Emtpy stack
102 \def\!vazia{:}
105 %% Is Empty? : Stack -> Bool
107 %% nvazia - True if Not Empy
108 %% vazia - True if Empty
109 \def\!pilhanvazia#1{\let\arg=#1%
110 \if:\arg\ \nvaziafalse\vaziatrue \else \nvaziatrue\vaziafalse\fi}
113 %% Push : Elems x Stack -> Stack
115 \def\!coloca#1#2{\edef\pilha{#1.#2}}
118 %% Top : Stack -> Elems
120 %% the empty stack is not taken care
121 %% the element is "kept" ("guardado")
122 \def\!guarda(#1)(#2,#3)(#4,#5,#6){\def\id{#1}%
123 \xaux=#2%
124 \yaux=#3%
125 \alt=#4%
126 \larg=#5%
127 \prof=#6%
130 \def\!topaux#1.#2:{\!guarda#1}
131 \def\!topo#1{\expandafter\!topaux#1}
134 %% Pop : Stack -> Stack
136 %% the empty stack is not taken care
137 \def\!popaux#1.#2:{\def\pilha{#2:}}
138 \def\!retira#1{\expandafter\!popaux#1}
141 %% Compares words : Word x Word -> Bool
143 %% compara - True if equal
144 %% diferentes - True if not equal
145 \def\!comparaaux#1#2{\let\argA=#1\let\argB=#2%
146 \ifx\argA\argB\comparatrue\diferentesfalse\else\comparafalse\diferentestrue\fi}
148 \def\!compara#1#2{\!comparaaux{#1}{#2}}
150 %%Comando Interno
151 %% Valor absoluto (absolute value)
152 %% \absoluto{n}{absn}
153 %% entrada
154 %% n - natural
155 %% sa{\'\i}da
156 %% absn - o valor absoluto de n
157 \def\!absoluto#1#2{\n=#1%
158 \ifnum \n > 0
159 #2=\n
160 \else
161 \multiply \n by -1
162 #2=\n
163 \fi}
166 %% Name definitions for edge types and directions
167 \def\solidarrow{0}
168 \def\dasharrow{1}
169 \def\solidline{2}
170 \def\dashline{3}
171 \def\dotline{4}
172 \def\injectionarrow{5}
173 \def\aplicationarrow{6}
174 \def\surjectivearrow{7}
175 %% Name definitions for edge label placement
176 \def\atright{-1}
177 \def\atleft{1}
178 %% Tip direction for curved edges
179 \def\pup{0}
180 \def\pdown{1}
181 \def\pright{2}
182 \def\pleft{3}
183 %% Type of graph
184 \def\commdiag{0}
185 \def\digraph{1}
186 \def\undigraph{2}
187 \def\cdigraph{3}
188 \def\cundigraph{4}
189 %% Posicionamento da etiquetas nos grafos
190 \def\pcent{0}
191 \def\north{1}
192 \def\northeast{2}
193 \def\east{3}
194 \def\southeast{4}
195 \def\south{5}
196 \def\southwest{6}
197 \def\west{7}
198 \def\northwest{8}
202 %%Comando Interno
203 %% Ajusta a dist{\^a}ncia entre as setas e os objectos em fun{\c c}{\~a}o das
204 %% dimens{\~o}es destes {\'u}ltimos
205 %% \ajusta{x}{xl}{y}{yl}{d}{Objecto}
206 %% entrada
207 %% (x,y) e (xl,yl), coordenadas dos pontos de {\'\i}nicio e fim da seta
208 %% d, dist{\^a}ncia especificada pelo utilizador ou 10 (valor por
209 %% omiss{\~a}o), Objecto d{\'a}-nos a refer{\^e}ncia do objecto ao qual se est{\'a} a
210 %% efectuar o ajuste.
211 %% sa{\'\i}da
212 %% d, dist{\^a}ncia alterada.
214 %% A dist{\^a}ncia alterada {\'e} o maior valor entre 10 e as dimens{\~o}es
215 %% apropriadas da caixa que cont{\^e}m o objecto.
216 %% Se o utilizador especificar um valor essa especifica{\c c}{\~a}o
217 %% n{\~a}o {\'e} alterada.
219 %% Se a seta {\'e} horizontal usa-se o valor da largura
220 %% Se a seta {\'e} vertical usa-se:
221 %% o valor da altura se a seta est{\'a} no 1o ou 2o quadrante
222 %% o valor da profundidade se a seta est{\'a} no 3o ou 4o quadrante
223 %% Se a seta {\'e} {\'o}bliqua vai-se escolher o valor conforme:
224 %% de 315 a 45 graus usa-se a largura
225 %% de 45 a 135 graus usa-se a altura
226 %% de 135 a 225 graus usa-se a largura
227 %% de 225 a 315 graus usa-se a profundidade
228 \def\!ajusta#1#2#3#4#5#6{\aux=#5%
229 \let\auxobj=#6%
230 \ifcase \tipografo % diagramas comutativos
231 \ifnum\number\aux=10
232 \ajustadisttrue % se o valor é o valor por omissão ajusta
233 \else
234 \ajustadistfalse % caso contrário não ajusta
236 \else % grafos (dirigidos, não dirigidos, com molduras)
237 \ajustadistfalse
238 % \or % grafos não dirigidos
239 % \ajustadistfalse
240 % \else % grafos dirigidos com molduras circulares nos objectos
241 % \ifnum\number\aux=8
242 % \ajustadisttrue % se o valor é o valor por omissão ajusta
243 % \else
244 % \ajustadistfalse % caso contrário não ajusta
245 % \fi
247 \ifajustadist
248 % \tiny Vou ajustar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % \ifnum\number\aux=10% verificar se s{\~a}o os valores por omiss{\~a}o
250 \let\pilhaaux=\pilha%
251 \loop%
252 \!topo{\pilha}%
253 \!retira{\pilha}%
254 \!compara{\id}{\auxobj}%
255 \ifcompara\nvaziafalse \else\!pilhanvazia\pilha \fi%
256 \ifnvazia%
257 \repeat%
258 %% rep{\~o}e os valores na pilha
259 \let\pilha=\pilhaaux%
260 \ifvazia%
261 \ifdiferentes%
263 %% N{\~a}o {\'e} poss{\'\i}vel efectuar o ajuste dado o utilizador n{\~a}o ter
264 %% especificado uma etiqueta para o objecto em quest{\~a}o. {\'E} dado o
265 %% valor de 10, igual ao valor por omiss{\~a}o.
267 \larg=1310720% n{\~a}o faz o ajuste
268 \prof=655360%
269 \alt=655360%
270 \fi%
271 \fi%
272 \divide\larg by 131072
273 \divide\prof by 65536
274 \divide\alt by 65536
275 \ifnum\number\y=\number\yl
276 %% Caso 1 -- seta horizontal
278 %% divide-se por 131072 para se obter metade da largura da caixa em
279 %% pontos (pt), isto dado que o texto est{\'a} centrado na caixa. Soma-se
280 %% mais tr{\^e}s, que constitue um ajuste imp{\'\i}rico.
281 \advance\larg by 3
282 \ifnum\number\larg>\aux
283 #5=\larg
285 \else
286 \ifnum\number\x=\number\xl
287 \ifnum\number\yl>\number\y
288 %% Caso 2.1 -- seta vertical de cima para baixa
290 \ifnum\number\alt>\aux
291 #5=\alt
293 \else
294 %% Caso 2.2 -- seta vertical de baixo para cima
296 %% divide-se por 65536 para se obter a altura da caixa em pt. O ajuste
297 %% de 5 foi obtido imp{\'\i}ricamente
298 \advance\prof by 5
299 \ifnum\number\prof>\aux
300 #5=\prof
303 \else
304 %% Caso 3 -- seta obl{\'\i}qua
305 %% Caso 3.1 de 315o a 45o; |x-xl|>|y-yl| e
306 %% Caso 3.3 de 135o a 225o; |x-xl|>|y-yl|; Largura
307 \auxqx=\x
308 \advance\auxqx by -\xl
309 \!absoluto{\auxqx}{\auxqx}%
310 \auxqy=\y
311 \advance\auxqy by -\yl
312 \!absoluto{\auxqy}{\auxqy}%
313 \ifnum\auxqx>\auxqy
314 \ifnum\larg<10
315 \larg=10
317 \advance\larg by 3
318 #5=\larg
319 \else
320 %% Caso 3.2 de 45o a 135o; |x-xl|<|y-yl| e y>0; Largura
321 \ifnum\yl>\y
322 \ifnum\larg<10
323 \larg=10
325 \advance\alt by 6
326 #5=\alt
327 \else
328 %% Caso 3.4 de 225o a 315o; |x-xl|<|y-yl| e y<0; Profundidade
329 \advance\prof by 11
330 #5=\prof
335 \fi} % o ramo "else" {\'e} omisso
338 %%Comando Interno
339 %% C{\'a}lculo da Raiz Quadrada
340 %% raiz{n}{m}
341 %% entrada
342 %% n - natural
343 %% sa{\'\i}da
344 %% n - natural
345 %% m - maior natural contido na raiz quadrada de n
346 \def\!raiz#1#2{\n=#1%
347 \m=1%
348 \loop
349 \aux=\m%
350 \advance \aux by 1%
351 \multiply \aux by \aux%
352 \ifnum \aux < \n%
353 \advance \m by 1%
354 \paratrue%
355 \else\ifnum \aux=\n%
356 \advance \m by 1%
357 \paratrue%
358 \else\parafalse%
361 \ifpara%
362 \repeat
363 #2=\m}
365 %%Comando Interno
366 %% Calcula os pontos de
367 %% come{\c c}o da "seta"
368 %% fim da "seta"
369 %% coloca{\c c}{\~a}o do s{\'\i}mbolo
371 %% ucoord{x1}{x2}{x3}{x4}{x5}{x6}{+|- 1}
372 %% entrada
373 %% x1,x2,x3,x4,x5
374 %% sa{\'\i}da
375 %% x6
377 %% x2 - x1
378 %% x6 = x3 +|- ------- x4
379 %% x5
380 \def\!ucoord#1#2#3#4#5#6#7{\aux=#2%
381 \advance \aux by -#1%
382 \multiply \aux by #4%
383 \divide \aux by #5%
384 \ifnum #7 = -1 \multiply \aux by -1 \fi%
385 \advance \aux by #3%
386 #6=\aux}
388 %%Comando Interno
389 %% C{\'a}lculo do Quadrado da Dist{\^a}ncia Euclidiana entre dois pontos
390 %% quadrado{n}{m}{l}
391 %% entrada
392 %% n - natural
393 %% m - natural
394 %% sa{\'\i}da
395 %% l = (n-m)*(n-m)
396 \def\!quadrado#1#2#3{\aux=#1%
397 \advance \aux by -#2%
398 \multiply \aux by \aux%
399 #3=\aux}
401 %%Comando Interno
402 %% C{\'a}lculo auxiliar para determinar a dist{\^a}ncia entre o nome do
403 %% morfismo e a seta.
404 %% entrada
405 %% (x,y), (x',y') e o nome do morfismo
406 %% sa{\'\i}da
407 %% dnm - dist{\^a}ncia do nome ao morfismo respectivo devidamente
408 %% compensada pelo tamanho do objecto
409 %% Observa{\c c}{\~o}es
410 %% A compensa{\c c}{\~a}o s{\'o} est{\'a} a ser feita para setas
411 %% horizontais e verticais. As obl{\'\i}quas s{\~a}o tratadas de
412 %% outra forma.
413 %% algoritmo
414 %% caixa0 <- nome do morfismo
415 %% se x-xl = 0 entao {recta vertical}
416 %% aux <- largura da caixa0
417 %% dnm <- convers{\~a}o-sp-pt(aux)/2+3
418 %% sen{\~a}o {recta n{\~a}o vertical}
419 %% se y-yl = 0 entao {recta horizontal}
420 %% aux <- altura+profundidade da caixa0
421 %% dnm <- convers{\~a}o-sp-pt(aux)/2+3
422 %% sen{\~a}o {recta obl{\'\i}qua}
423 %% dnm <- 3
424 %% fimse
425 %% fimse
426 %% fimalgoritmo
427 \def\!distnomemor#1#2#3#4#5#6{\setbox0=\hbox{#5}%
428 \aux=#1
429 \advance \aux by -#3
430 \ifnum \aux=0
431 \aux=\wd0 \divide \aux by 131072
432 \advance \aux by 3
433 #6=\aux
434 \else
435 \aux=#2
436 \advance \aux by -#4
437 \ifnum \aux=0
438 \aux=\ht0 \advance \aux by \dp0 \divide \aux by 131072
439 \advance \aux by 3
440 #6=\aux%
441 \else
442 #6=3
449 %% O ambiente "begindc...enddc"
451 \def\begindc#1{\!ifnextchar[{\!begindc{#1}}{\!begindc{#1}[30]}}
452 \def\!begindc#1[#2]{\beginpicture
453 \let\pilha=\!vazia
454 \setcoordinatesystem units <1pt,1pt>
455 \expansao=#2
456 \ifcase #1
457 \distanciaobjmor=10
458 \tipoarco=0 % seta
459 \tipografo=0 % diagrama comutativo
461 \distanciaobjmor=2
462 \tipoarco=0 % seta
463 \tipografo=1 % grafo orientado
465 \distanciaobjmor=1
466 \tipoarco=2 % linha
467 \tipografo=2 % grafo não orientado
469 \distanciaobjmor=8
470 \tipoarco=0 % seta
471 \tipografo=3 % grafo orientado
472 % \arredondadotrue % objectos com molduras circulares
474 \distanciaobjmor=8
475 \tipoarco=2 % linha
476 \tipografo=4 % grafo não orientado
477 % \arredondadotrue % objectos com molduras circulares
478 \fi}
480 \def\enddc{\endpicture}
484 %% Comando para construir a "seta" entre dois objectos
486 %% Os pontos definidores da seta e da etiqueta respectiva s{\~a}o:
488 %% (xd,yd)
489 %% o
490 %% |
491 %% o------o---------o---------o------o
492 %%(x,y) (xa,ya) (xm,ym) (xb,yb)(xl,yl)
494 \def\mor{%
495 \!ifnextchar({\!morxy}{\!morObjA}}
496 \def\!morxy(#1,#2){%
497 \!ifnextchar({\!morxyl{#1}{#2}}{\!morObjB{#1}{#2}}}
498 \def\!morxyl#1#2(#3,#4){%
499 \!ifnextchar[{\!mora{#1}{#2}{#3}{#4}}{\!mora{#1}{#2}{#3}{#4}[\number\distanciaobjmor,\number\distanciaobjmor]}}%
500 \def\!morObjA#1{%
501 \let\pilhaaux=\pilha%
502 \def\objPartida{#1}%
503 \loop%
504 \!topo\pilha%
505 \!retira\pilha%
506 \!compara{\id}{\objPartida}%
507 \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi%
508 \ifnvazia%
509 \repeat%
510 \ifvazia%
511 \ifdiferentes%
513 %% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos
514 %% argumentos dos comandos que se seguem.
516 Error: Incorrect label specification%
517 \xaux=1%
518 \yaux=1%
519 \fi%
520 \fi%
521 \let\pilha=\pilhaaux%
522 \!ifnextchar({\!morxyl{\number\xaux}{\number\yaux}}{\!morObjB{\number\xaux}{\number\yaux}}}
523 \def\!morObjB#1#2#3{%
524 \x=#1
525 \y=#2
526 \def\objChegada{#3}%
527 \let\pilhaaux=\pilha%
528 \loop
529 \!topo\pilha %
530 \!retira\pilha%
531 \!compara{\id}{\objChegada}%
532 \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi
533 \ifnvazia
534 \repeat
535 \ifvazia
536 \ifdiferentes%
538 %% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos
539 %% argumentos dos comandos que se seguem.
541 Error: Incorrect label specification
542 \xaux=\x%
543 \advance\xaux by \x%
544 \yaux=\y%
545 \advance\yaux by \y%
548 \let\pilha=\pilhaaux
549 \!ifnextchar[{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}}{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}[\number\distanciaobjmor,\number\distanciaobjmor]}}
550 \def\!mora#1#2#3#4[#5,#6]#7{%
551 \!ifnextchar[{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}}{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}[1,\number\tipoarco] }}
552 \def\!morb#1#2#3#4#5#6#7[#8,#9]{\x=#1%
553 \y=#2%
554 \xl=#3%
555 \yl=#4%
556 \multiply \x by \expansao%
557 \multiply \y by \expansao%
558 \multiply \xl by \expansao%
559 \multiply \yl by \expansao%
561 %% calcular a dist{\^a}ncia Euclidiana entre dois pontos
562 %% d = \sqrt((x-xl)^2+(y-yl)^2)
564 \!quadrado{\number\x}{\number\xl}{\auxa}%
565 \!quadrado{\number\y}{\number\yl}{\auxb}%
566 \d=\auxa%
567 \advance \d by \auxb%
568 \!raiz{\d}{\d}%
570 %% o ponto (xa,ya) est{\'a} {\`a} dist{\^a}ncia #5 (valor por omiss{\~a}o 10) do ponto
571 %% (x,y)
573 %% como existem dois pontos em considera{\c c}{\~a}o, o ponto de partida e o
574 %% ponto de chegada, vai sei necess{\'a}rio recuperar de novo os seus
575 %% valores por pesquisa na pilha
576 \auxa=#5
577 \!compara{\objNulo}{\objPartida}%
578 \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
579 \!ajusta{\x}{\xl}{\y}{\yl}{\auxa}{\objPartida}%
580 \ajustatrue
581 \def\objPartida{}% re-inicializar o valor do Objecto de Partida
583 %% vai guardar o valor de auxa (ap{\'o}s ajuste) para ser usado no caso
584 %% dos morfismos de injec{\c c}{\~a}o.
585 \guardaauxa=\auxa
587 \!ucoord{\number\x}{\number\xl}{\number\x}{\auxa}{\number\d}{\xa}{1}%
588 \!ucoord{\number\y}{\number\yl}{\number\y}{\auxa}{\number\d}{\ya}{1}%
589 %% auxa vai ter o valor da dist{\^a}ncia entre os objectos menos a
590 %% dist{\^a}ncia da seta ao objecto (10 por omiss{\~a}o)
591 \auxa=\d%
593 %% o ponto (xb,yb) est{\'a} {\`a} dist{\^a}ncia #6 (valor por omiss{\~a}o 10) do ponto
594 %% (xl,yl)
596 \auxb=#6
597 \!compara{\objNulo}{\objChegada}%
598 \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
599 % Vou ajustar
600 \!ajusta{\x}{\xl}{\y}{\yl}{\auxb}{\objChegada}%
601 \def\objChegada{}% re-inicializar o valor do Objecto de Chegada
603 \advance \auxa by -\auxb%
604 \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xb}{1}%
605 \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\yb}{1}%
606 \xmed=\xa%
607 \advance \xmed by \xb%
608 \divide \xmed by 2
609 \ymed=\ya%
610 \advance \ymed by \yb%
611 \divide \ymed by 2
614 \!distnomemor{\number\x}{\number\y}{\number\xl}{\number\yl}{#7}{\dnm}%
615 \!ucoord{\number\y}{\number\yl}{\number\xmed}{\number\dnm}{\number\d}{\xc}{-#8}%
616 \!ucoord{\number\x}{\number\xl}{\number\ymed}{\number\dnm}{\number\d}{\yc}{#8}%
617 \ifcase #9 % Seta S{\'o}lida
618 \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
619 \or % Seta a Tracejado
620 \setdashes
621 \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
622 \setsolid
623 \or % Linha S{\'o}lida
624 \setlinear
625 \plot {\xa} {\ya} {\xb} {\yb} /
626 \or % Linha Tracejado
627 \setdashes
628 \setlinear
629 \plot {\xa} {\ya} {\xb} {\yb} /
630 \setsolid
631 \or % Linha a Ponteado
632 \setdots
633 \setlinear
634 \plot {\xa} {\ya} {\xb} {\yb} /
635 \setsolid
636 \or % Seta de Injec{\c c}{\~a}o
637 %% C{\'a}lculos auxiliares
639 %% 3 valor para o raio do "rabo" da "seta"
641 %% repor o valor de auxa
642 \auxa=\guardaauxa
643 %% dar a compensa{\c c}{\~a}o para o "rabo"
644 \advance \auxa by 3%
646 %% IMPORTANTE os valores de xa e ya v{\~a}o ser alterados
648 \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xa}{1}%
649 \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\ya}{1}%
650 \!ucoord{\number\y}{\number\yl}{\number\xa}{3}{\number\d}{\xd}{-1}%
651 \!ucoord{\number\x}{\number\xl}{\number\ya}{3}{\number\d}{\yd}{1}%
652 %% Constru{\c c}{\~a}o da "seta"
653 \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
654 %% e do seu "rabo"
655 \circulararc -180 degrees from {\xa} {\ya} center at {\xd} {\yd}
656 \or % Seta de Aplica{\c c}{\~a}o ("|-->")
657 \auxa=3% valor para o meio-segmento do "rabo" da "seta"
658 %% c{\'a}lculo dos pontos (xmed,ymed) e (xd,yd) para o segmento de recta que
659 %% define o "rabo" da seta
660 \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xmed}{-1}%
661 \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\ymed}{1}%
662 \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xd}{1}%
663 \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\yd}{-1}%
664 %% Constru{\c c}{\~a}o da "seta"
665 \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
666 %% e do seu "rabo"
667 \setlinear
668 \plot {\xmed} {\ymed} {\xd} {\yd} /
669 \or % Seta de Sobrejec{\c c}{\~a}o ("-->>")
670 \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
671 %% e da segunda "seta"
672 \setlinear
673 \arrow <6pt> [0,.72] from {\xa} {\ya} to {\xb} {\yb}
675 %% Coloca{\c c}{\~a}o do nome do morfismo.
676 %% Se os morfismos s{\~a}o horizontais ou verticais constro{\'\i} uma caixa
677 %% centrada no ponto pr{\'e}viamente calculado. Se as setas s{\~a}o
678 %% obl{\'\i}quas coloca a caixa de forma a n{\~a}o colidir com o morfismo
679 %% tendo em aten{\c c}{\~a}o o quadrante assim como a posi{\c c}{\~a}o
680 %% relativa do morfismo e do respectivo nome.
681 \auxa=\xl
682 \advance \auxa by -\x%
683 \ifnum \auxa=0
684 \put {#7} at {\xc} {\yc}
685 \else
686 \auxb=\yl
687 \advance \auxb by -\y%
688 \ifnum \auxb=0 \put {#7} at {\xc} {\yc}
689 \else
690 \ifnum \auxa > 0
691 \ifnum \auxb > 0
692 \ifnum #8=1
693 \put {#7} [rb] at {\xc} {\yc}
694 \else
695 \put {#7} [lt] at {\xc} {\yc}
697 \else
698 \ifnum #8=1
699 \put {#7} [lb] at {\xc} {\yc}
700 \else
701 \put {#7} [rt] at {\xc} {\yc}
704 \else
705 \ifnum \auxb > 0
706 \ifnum #8=1
707 \put {#7} [rt] at {\xc} {\yc}
708 \else
709 \put {#7} [lb] at {\xc} {\yc}
711 \else
712 \ifnum #8=1
713 \put {#7} [lt] at {\xc} {\yc}
714 \else
715 \put {#7} [rb] at {\xc} {\yc}
724 %% Comando para construir a "seta" curvilinea entre dois objectos
726 %% \cmor(<lista de pontos (n. impar)>){<etiqueta>}
728 %% Em primeiro lugar {\'e} necess{\'a}rio modificar o comando plot de forma a
729 %% que a sintaxe de utiliza{\c c}{\~a}o do novo comando seja coerente com a
730 %% sintaxe dos restantes comandos
732 \def\modifplot(#1{\!modifqcurve #1}
733 \def\!modifqcurve(#1,#2){\x=#1%
734 \y=#2%
735 \multiply \x by \expansao%
736 \multiply \y by \expansao%
737 \!start (\x,\y)
738 \!modifQjoin}
739 \def\!modifQjoin(#1,#2)(#3,#4){\x=#1%
740 \y=#2%
741 \xl=#3%
742 \yl=#4%
743 \multiply \x by \expansao%
744 \multiply \y by \expansao%
745 \multiply \xl by \expansao%
746 \multiply \yl by \expansao%
747 \!qjoin (\x,\y) (\xl,\yl) % \!qjoin is defined in QUADRATIC
748 \!ifnextchar){\!fim}{\!modifQjoin}}
749 \def\!fim){\ignorespaces}
752 %% O comando para desenhar a seta vai receber a lista de pontos da qual
753 %% retira o {\'u}ltimo par de pontos, dependente da escolha dada pelo
754 %% utilizador a seta vai ser desenhada para cima, para baixo, para a
755 %% direita ou para a esquerda
757 \def\setaxy(#1{\!pontosxy #1}
758 \def\!pontosxy(#1,#2){%
759 \!maispontosxy}
760 \def\!maispontosxy(#1,#2)(#3,#4){%
761 \!ifnextchar){\!fimxy#3,#4}{\!maispontosxy}}
762 \def\!fimxy#1,#2){\x=#1%
763 \y=#2
764 \multiply \x by \expansao
765 \multiply \y by \expansao
766 \xl=\x%
767 \yl=\y%
768 \aux=1%
769 \multiply \aux by \auxa%
770 \advance\xl by \aux%
771 \aux=1%
772 \multiply \aux by \auxb%
773 \advance\yl by \aux%
774 \arrow <4pt> [.2,1.1] from {\x} {\y} to {\xl} {\yl}}
778 %% Temos agora a defini{\c c}{\~a}o do comando "cmor"
780 \def\cmor#1 #2(#3,#4)#5{%
781 \!ifnextchar[{\!cmora{#1}{#2}{#3}{#4}{#5}}{\!cmora{#1}{#2}{#3}{#4}{#5}[0] }}
782 \def\!cmora#1#2#3#4#5[#6]{%
783 \ifcase #2% para cima "\pup" (pointing up)
784 \auxa=0% x mant{\^e}m-se
785 \auxb=1% o y "sobe"
786 \or% para baixo "\pdown" (pointing down)
787 \auxa=0% x mant{\^e}m-se
788 \auxb=-1% o y "desce"
789 \or% para a direita "\pright" (pointing right)
790 \auxa=1% o x move-se para a direita
791 \auxb=0% o y mant{\^e}m-se
792 \or% para a esquerda "\pleft" (pointing left)
793 \auxa=-1% o x move-se para a esquerda
794 \auxb=0% o y mant{\^e}m-se
795 \fi % constru{\c c}{\~a}o do arco
796 \ifcase #6 % arco (com seta) s{\'o}lido
797 \modifplot#1% Desenhar o arco
798 % constru{\c c}{\~a}o da seta
799 \setaxy#1
800 \or % arco (com seta) a tracejado
801 \setdashes
802 \modifplot#1% Desenhar o arco
803 \setaxy#1
804 \setsolid
805 \or % arco sem seta
806 \modifplot#1% Desenhar o arco
807 \fi % seta de injec{\c c}{\~a}o
808 %% coloca{\c c}{\~a}o da etiqueta do morfismo
809 \x=#3%
810 \y=#4%
811 \multiply \x by \expansao%
812 \multiply \y by \expansao%
813 \put {#5} at {\x} {\y}}
816 %% Comando para construir os Objectos
817 %% \obj(x,y){<texto>}[<etiqueta>]
819 \def\obj(#1,#2){%
820 \!ifnextchar[{\!obja{#1}{#2}}{\!obja{#1}{#2}[Nulo]}}
821 \def\!obja#1#2[#3]#4{%
822 \!ifnextchar[{\!objb{#1}{#2}{#3}{#4}}{\!objb{#1}{#2}{#3}{#4}[1]}}
823 \def\!objb#1#2#3#4[#5]{%
824 \x=#1%
825 \y=#2%
826 \def\!pinta{\normalsize$\bullet$}% para definir o tamanho normal das pintas
827 \def\!nulo{Nulo}%
828 \def\!arg{#3}%
829 \!compara{\!arg}{\!nulo}%
830 \ifcompara\def\!arg{#4}\fi%
831 \multiply \x by \expansao%
832 \multiply \y by \expansao%
833 \setbox\caixa=\hbox{#4}%
834 \!coloca{(\!arg)(#1,#2)(\number\ht\caixa,\number\wd\caixa,\number\dp\caixa)}{\pilha}%
835 \auxa=\wd\caixa \divide \auxa by 131072
836 \advance \auxa by 5
837 \auxb=\ht\caixa
838 \advance \auxb by \number\dp\caixa
839 \divide \auxb by 131072
840 \advance \auxb by 5
841 %(\number\auxa,
842 %\number\auxb)
843 % \aux=\ht\caixa \divide \auxa by 131072
844 % \advance \auxa by 5
845 % \auxb=\dp\caixa \divide \auxb by 131072
846 % \advance \auxb by 8
847 \ifcase \tipografo % diagramas comutativos
848 \put{#4} at {\x} {\y}
849 \or % grafos dirigidos
850 \ifcase #5 % c=0
851 \put{#4} at {\x} {\y}
852 \or % n=1
853 \put{\!pinta} at {\x} {\y}
854 \advance \y by \number\auxb % height+depth+5
855 \put{#4} at {\x} {\y}
856 \or % ne=2
857 \put{\!pinta} at {\x} {\y}
858 \advance \auxa by -2 % para fazer o ajuste (imperfeito)
859 \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
860 \advance \x by \number\auxa % width+5
861 \advance \y by \number\auxb % height+depth+5
862 \put{#4} at {\x} {\y}
863 \or % e=3
864 \put{\!pinta} at {\x} {\y}
865 \advance \x by \number\auxa % width+5
866 \put{#4} at {\x} {\y}
867 \or % se=4
868 \put{\!pinta} at {\x} {\y}
869 \advance \auxa by -2 % para fazer o ajuste (imperfeito)
870 \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
871 \advance \x by \number\auxa % width+5
872 \advance \y by -\number\auxb % height+depth+5
873 \put{#4} at {\x} {\y}
874 \or % s=5
875 \put{\!pinta} at {\x} {\y}
876 \advance \y by -\number\auxb % height+depth+5
877 \put{#4} at {\x} {\y}
878 \or % sw=6
879 \put{\!pinta} at {\x} {\y}
880 \advance \auxa by -2 % para fazer o ajuste (imperfeito)
881 \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
882 \advance \x by -\number\auxa % width+5
883 \advance \y by -\number\auxb % height+depth+5
884 \put{#4} at {\x} {\y}
885 \or % w=7
886 \put{\!pinta} at {\x} {\y}
887 \advance \x by -\number\auxa % width+5
888 \put{#4} at {\x} {\y}
889 \or % nw=8
890 \put{\!pinta} at {\x} {\y}
891 \advance \auxa by -2 % para fazer o ajuste (imperfeito)
892 \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
893 \advance \x by -\number\auxa % width+5
894 \advance \y by \number\auxb % height+depth+5
895 \put{#4} at {\x} {\y}
897 \or % grafos não dirigidos
898 \ifcase #5 % c=0
899 \put{#4} at {\x} {\y}
900 \or % n=1
901 \put{\!pinta} at {\x} {\y}
902 \advance \y by \number\auxb % height+depth+5
903 \put{#4} at {\x} {\y}
904 \or % ne=2
905 \put{\!pinta} at {\x} {\y}
906 \advance \auxa by -2 % para fazer o ajuste (imperfeito)
907 \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
908 \advance \x by \number\auxa % width+5
909 \advance \y by \number\auxb % height+depth+5
910 \put{#4} at {\x} {\y}
911 \or % e=3
912 \put{\!pinta} at {\x} {\y}
913 \advance \x by \number\auxa % width+5
914 \put{#4} at {\x} {\y}
915 \or % se=4
916 \put{\!pinta} at {\x} {\y}
917 \advance \auxa by -2 % ver acima
918 \advance \auxb by -2
919 \advance \x by \number\auxa % width+5
920 \advance \y by -\number\auxb % height+depth+5
921 \put{#4} at {\x} {\y}
922 \or % s=5
923 \put{\!pinta} at {\x} {\y}
924 \advance \y by -\number\auxb % height+depth+5
925 \put{#4} at {\x} {\y}
926 \or % sw=6
927 \put{\!pinta} at {\x} {\y}
928 \advance \auxa by -2 % ver acima
929 \advance \auxb by -2
930 \advance \x by -\number\auxa % width+5
931 \advance \y by -\number\auxb % height+depth+5
932 \put{#4} at {\x} {\y}
933 \or % w=7
934 \put{\!pinta} at {\x} {\y}
935 \advance \x by -\number\auxa % width+5
936 \put{#4} at {\x} {\y}
937 \or % nw=8
938 \put{\!pinta} at {\x} {\y}
939 \advance \auxa by -2 % ver acima
940 \advance \auxb by -2
941 \advance \x by -\number\auxa % width+5
942 \advance \y by \number\auxb % height+depth+5
943 \put{#4} at {\x} {\y}
945 % \or % grafos dirigidos com molduras circulares nos objectos
946 % \advance \auxa by 4
947 % \put{\circle{\auxa}} [Bl] at {\x} {\y}
948 % \put{#4} at {\x} {\y}
949 % \or % grafos não dirigidos com molduras circulares nos objectos
950 \else % grafos com molduras circulares nos objectos
951 \ifnum\auxa<\auxb % determina a maior das dimensões
952 \aux=\auxb
953 \else
954 \aux=\auxa
956 % se a largura da caixa é menor do que 1em então o tamanho
957 % tamanho é ajustado para esse valor mínimo
958 \ifdim\wd\caixa<1em
959 \dimen99 = 1em
960 \aux=\dimen99 \divide \aux by 131072
961 \advance \aux by 5
963 \advance\aux by -2 %folga entre o objecto e a moldura
964 \multiply\aux by 2 %
965 \ifnum\aux<30
966 \put{\circle{\aux}} [Bl] at {\x} {\y}
967 \else
968 \multiply\auxa by 2
969 \multiply\auxb by 2
970 \put{\oval(\auxa,\auxb)} [Bl] at {\x} {\y}
972 \put{#4} at {\x} {\y}
973 \fi
977 \catcode`!=12 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)