diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-12 23:54:05 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-12 23:54:05 +0000 |
commit | 8e3144f440d5dc8f7b1ae3bd01db67e10fab5eb2 (patch) | |
tree | 22b2f11eda7ee917617962605b673f51eaa175f6 | |
parent | 399efd9f62691744f76149b577407c495e4b2ee7 (diff) |
dcpic
git-svn-id: svn://tug.org/texlive/trunk@818 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/tex/latex/dcpic/dcpic.sty | 1200 |
1 files changed, 1200 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/dcpic/dcpic.sty b/Master/texmf-dist/tex/latex/dcpic/dcpic.sty new file mode 100644 index 00000000000..b1a65327c08 --- /dev/null +++ b/Master/texmf-dist/tex/latex/dcpic/dcpic.sty @@ -0,0 +1,1200 @@ +% $Id: dcpic.sty,v 1.24 2002/11/25 13:51:57 pedro Exp $ +%% DC-PiCTeX +%% Realizado por Pedro Quaresma de Almeida, Coimbra +%% 11/1990 (vers{\~a}o 1.0); 10/1991 (vers{\~a}o 1.1); +%% 9/1993 (vers{\~a}o 1.2); 3/1995 (vers{\~a}o 1.3); +%% 7/1996 (vers{\~a}o 2.1); +%% 5/2001 (vers{\~a}o 3.0); 11/2001 (vers{\~a}o 3.1); +%% 1/2002 (vers{\~a}o 3.2) +%% 5/2002 (versão 4.0) +\immediate\write10{Package DCpic 2002/05/16 v4.0} + +%% Copyright (c) 1990-2002 Pedro Quaresma <pedro@mat.uc.pt> +%% The DCpic package is free software; you can redistribute it and/or +%% modify it under the terms of the GNU General Public License as +%% published by the Free Software Foundation; either version 2 of the +%% License, or (at your option) any later version. +%% +%% The DCpic package is distributed in the hope that it will be +%% useful, but WITHOUT ANY WARRANTY; without even the implied warranty +%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%% General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with this package; if not, write to the Free Software +%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +%% +%% +%% Coimbra, 16 de Maio de 2002 +%% Pedro Quaresma de Almeida +%% +%% DCpic is a package of \TeX\ macros for graph modelling in a +%% (La)\TeX\ or Con\TeX t document. Its distinguishing features are: +%% the use of \PiCTeX\ a powerful graphical engine, and a simple +%% specification syntax. A graph is described in terms of its objects +%% and its edges. The objects are textual elements and the edges can +%% have various straight or curved forms. +%% +%% +%% A graph in DCpic is a "picture" in \PiCTeX, in which we place our +%% {\em objects} and {\em morphisms} (edges). The user's commands in +%% DCpic are: {\tt begindc} and {\tt enddc} which establishe the +%% coordinate system where the objects will by placed; {\tt obj}, the +%% command which defines the place and the contents of each object; +%% {\tt mor}, and {\tt cmor}, the commands which define the +%% morphisms, linear and curved edges, and its labels. +%% +%% Example: +%% \begindc{\commdiag}[3] +%% \obj(10,15){$A$} +%% \obj(25,15){$B$} +%% \obj(40,15){$C$} +%% \mor{$A$}{$B$}{$f$} +%% \mor{$B$}{$C$}{$g$} +%% \cmor((10,11)(11,7)(15,6)(25,6)(35,6)(39,7)(40,11)) +%% \pup(25,3){$g\circ f$} +%% \enddc +%% +%% NOTES: +%% all the numeric values should be integer values. +%% +%% Available commands: +%% +%% The environment: +%% \begindc{#1}[#2] +%% Tipo do grafo +%% 0 = "commdiag" (diagrama comutativo) +%% 1 = "digraph" (grafo orientado) +%% 2 = "undigraph" (grafo não orientado) +%% (optional) #2 - magnification factor (default value, 30) +%% +%% \enddc +%% +%% Objects: +%% \obj(#1,#2)[#3]{#4}[#5] +%% #1 and #2 - coordenates +%% (optional) #3 - Label, to be used in the morphims command, if not +%% present the #4 will be used to that purpose +%% #4 - Object contents +%% #5 - placement of the object (default value \north) +%% 0="\pcent", center +%% 1="\north", north +%% 2="\northeast", northeast +%% 3="\east", east +%% 4="\southeast", southeast +%% 5="\south", south +%% 6="\southwest", southwest +%% 7="\west", west +%% 8="\northwest", northwest +%% !!! Note !!! +%% if you omit the #3 argument (label) and the #4 argument is a +%% complex LaTeX command this can cause this command to crash. In +%% this case you must specify a label (the empty label [], if you do +%% needed it it for nothing). +%% +%% Morphims (linear edges). This commando has to two major variants +%% i) Starting and Ending objects specification +%% \mor{#1}{#2}[#5,#6]{#7}[#8,#9] +%% +%% As you can see this first form is (intencionaly) badly formed, the +%% arguments #3 and #4 are missing (the actual command is correctly +%% formed). +%% +%% #1 - The starting object reference +%% #2 - The ending object reference +%% +%% from this two we will obtain the objects coordinates, and also the +%% dimensions of the enclosing box. +%% +%% The objects box dimensions are used to do an automatic adjustment of +%% the edge width. +%% +%% from #1 we obtain (x,y), (#1,#2) in the second form +%% from #2 we obtain (x',y'), (#3,#4) in the second form +%% +%% this values will be passed to the command second form +%% +%%ii) Two points coordinates specification +%% \mor(#1,#2)(#3,#4)[#5,#6]{#7}[#8,#9] +%% +%% Now we can describe all the arguments +%% +%% #1 and #2 - coordenates (beginning) +%% #3 and #4 - coordenantes (ending) +%%(optional)#5,#6 - correction factor (defaul value, 10 and 10) +%% #5 - actual beginning of the edge +%% #6 - actual ending of the edge +%% #7 - text (morphism label) +%%(optional)#8,#9 +%% #8 - label placement +%% 1 = \atright, at right, default value +%% -1 = \atleft, at left +%% #9 - edge type +%% 0 = "\solidarrow", default edge +%% 1 = "\dasharrow" +%% 2 = "\solidline" +%% 3 = "\injectionarrow" +%% 4 = "\aplicationarrow" +%% +%% Note: insert a space after the command. +%% +%% Curved Morphisms (quadratic edges): +%% \cmor(#1) #2(#3,#4){#5}[#6] +%% #1 - list of points (odd number) +%% #2 - tip direction +%% 0 = "\pup", pointing up +%% 1 = "\pdown", pointing down +%% 2 = "\pright", pointing right +%% 3 = "\pleft", pointing left +%% #3 and #4 - coordenates of the label +%% #5 - morphism label +%% #6 - edge type +%% 0 ="\solidarrow", default value +%% 1 = "\dasharrow" +%% 2 = "\solidline" +%% +%% Notes: insert a space after the command. +%% the space after the list of points is mandatory +%% +%% Exemples: +%%\documentclass[a4paper,11pt]{article} +%%\usepackage{dcpic,pictexwd} +%% +%%\begin{document} +%%\begindc[3] +%%\obj(14,11){$A$} +%%\obj(39,11){$B$} +%%\mor(14,12)(39,12){$f$}%[\atright,\solidarrow] +%%\mor(39,10)(14,10){$g$}%[\atright,\solidarrow] +%%\cmor((10,10)(6,11)(5,15)(6,19)(10,20)(14,19)(15,15)) +%% \pdown(2,20){$id_A$} +%%\cmor((40,7)(41,3)(45,2)(49,3)(50,7)(49,11)(45,12)) +%% \pleft(54,3){$id_B$} +%%\enddc +%% +%%\begindc{\commdiag}[3] +%%\obj(10,15)[A]{$A$} +%%\obj(40,15)[Aa]{$A$} +%%\obj(25,15)[B]{$B$} +%%\mor{A}{B}{$f$}%[\atright,\solidarrow] +%%\mor{B}{Aa}{$g$}%[\atright,\solidarrow] +%%\cmor((10,11)(11,7)(15,6)(25,6)(35,6)(39,7)(40,11)) +%% \pup(25,3){$id_A$} +%%\enddc +%% +%%\newcommand{\barraA}{\vrule height2em width0em depth0em} +%%\newcommand{\barraB}{\vrule height1.6em width0em depth0em} +%%\begindc{\commdiag}[35] +%%\obj(1,1)[Gr]{$G$} +%%\obj(3,1)[Grstar]{$G_{r^*}$} +%%\obj(5,1)[H]{$H$} +%%\obj(2,2)[SigmaG]{$\Sigma^G$} +%%\obj(6,2)[SigmaH]{$\Sigma^H$} +%%\obj(1,3)[Lm]{$L_m$} +%%\obj(3,3)[Krm]{$K_{r,m}$} +%%\obj(5,3)[Rmstar]{$R_{m^*}$} +%%\obj(1,5)[L]{$L$} +%%\obj(3,5)[Lr]{$L_r$} +%%\obj(5,5)[R]{$R$} +%%\obj(2,6)[SigmaL]{$\Sigma^L$} +%%\obj(6,6)[SigmaR]{$\Sigma^R$} +%%\mor{Gr}{SigmaG}{$\lambda^G$} +%%\mor{Grstar}{Gr}{$i_5$}[\atleft,\aplicationarrow] +%%\mor{Grstar}{H}{$r^*$}[\atright,\solidarrow] +%%\mor{H}{SigmaH}{$\lambda^H$}[\atright,\dasharrow] +%%\mor{SigmaG}{SigmaH}{$\varphi^{r^*}$}[\atright,\solidarrow] +%%\mor{Lm}{Gr}{$m$}[\atright,\solidarrow] +%%\mor{Lm}{L}{$i_2$}[\atleft,\aplicationarrow] +%%\mor{Krm}{Lm}{$i_3\quad$}[\atright,\aplicationarrow] +%%\mor{Krm}{Rmstar}{$r$} +%%\mor{Krm}{Lr}{$i_4$}[\atright,\aplicationarrow] +%%\mor{Krm}{Grstar}{$m$} +%%\mor{Rmstar}{R}{$i_6$}[\atright,\aplicationarrow] +%%\mor{Rmstar}{H}{$m^*$} +%%\mor{L}{SigmaL}{$\lambda^L$} +%%\mor{Lr}{L}{$i_1\quad$}[\atright,\aplicationarrow] +%%\mor{Lr}{R}{$r$} +%%\mor{R}{SigmaR}{$\lambda^R$}[\atright,\solidarrow] +%%\mor{SigmaL}{SigmaG}{$\varphi^m$}[\atright,\solidarrow] +%%\mor{SigmaL}{SigmaR}{$\varphi^r$} +%%\mor{SigmaR}{SigmaH}{$\varphi^{m^*}$} +%%\enddc +%% +%%\end{document} +%%-----------------//------------- +%% Modifica{\c c}{\~o}es (9/1993) +%% argumento "dist{\^a}ncia entre as extremidades da seta e os +%% objectos" passou a ser opcional; uma nova op{\c c}{\~a}o para as +%% "setas" (op{\c c}{\~a}o 3). +%% +%% 2/3/1995 (vers{\~a}o 1.3) +%% foi acrescentado o tipo de seta de aplica{\c c}{\~a}o +%% (op{\c c}{\~a}o 4) a dist{\^a}ncia da etiqueta {\`a} seta respectiva +%% passou a ser fixa (10 unidades de medida). +%% 15/7/1996 (versão 2.1) +%% O comando "\mor" passou a ter uma sintaxe distinta. Os +%% par{\^a}metros 5 e 6 passaram a ser a dist{\^a}ncia entre os +%% objectos e os extremos da seta o par{\^a}metro 7 {\'e} o nome do +%% morfismo e os par{\^a}metros 8 e 9, coloca{\c c}{\~a}o do morfismo +%% e tipo de morfismo passaram a ser opcionais. +%% +%% 5/2001 (vers{\~a}o 3.0) +%% Implementa{\c c}{\~a}o do comando "\cmor" baseado no comando +%% de desenho de curvas quadr{\'a}ticas pelo PiCTeX +%% +%% 11/2001 (vers{\~a}o 3.1) +%% Modifica{\c c}{\~a}o das pontas das setas de forma a estas ficarem +%% semelhantes {\`a}s setas (s{\'\i}mbolos) dos TeX. +%% +%% 1/2002 (vers{\~a}o 3.2) +%% Modifica{\c c}{\~a}o dos comandos "obj" e "mor" de forma a introduzir +%% a especifica{\c c}{\~a}o l{\'o}gica dos morfismos, isto {\'e}, passa-se a +%% dizer qual {\'e} o objecto de partida e/ou o objecto de chegada +%% em vez de ter de especificar o morfismo em termos de +%% coordenadas. +%% Por outro lado o tamanho das setas passa a ser ajustado +%% automaticamente em rela{\c c}{\~a}o ao tamanho dos objectos. +%% +%% 5/2002 (versão 4.0) +%% Modificação dos comandos "begindc" e "obj" +%% !!! Modificação da sintaxe destes comandos !!! +%% O comando "begindc" passou a ter um argumento (obrigatório) +%% que nos permite especificar o tipo de grafo que estamos a +%% querer especificar: +%% "commdiag" (0), para diagramas comutativos +%% "digraph" (1), para grafos orientados +%% "undigraph" (1), para grafos não orientados +%% O comando "obj" modificou a sua sintaxe passou a ter um (após +%% a especificação das coordenadas, um argumento opcional, um +%% argumento obrigatório, e um argumento opcional. O primeiro +%% argumento opcional dá-nos a etiqueta que serve como +%% referência para a especificação dos morfismos, na sua +%% ausência usa-se o argumento obrigatório para esse efeito, o +%% argumento obrigatório dá-nos o "conteúdo" do objecto, nos +%% diagramas comutativos é centrado no ponto dado pelas +%% coordenadas sendo o argumento seguinte simplesmente ignorado, +%% nos grafos o "conteúdo" é colocado numa posição a norte, a +%% noroeste, a este, ..., sendo que a posição concreta é +%% especificada pelo último dos argumentos deste comando, o +%% valor por omissão é o "norte". +%% +%%-----------------//------------- + +\catcode`!=11 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX) + +\newcount\aux% +\newcount\auxa% +\newcount\auxb% +\newcount\m% +\newcount\n% +\newcount\x% +\newcount\y% +\newcount\xl% +\newcount\yl% +\newcount\d% +\newcount\dnm% +\newcount\xa% +\newcount\xb% +\newcount\xmed% +\newcount\xc% +\newcount\xd% +\newcount\ya% +\newcount\yb% +\newcount\ymed% +\newcount\yc% +\newcount\yd +%% "variáveis globais" +\newcount\expansao% +\newcount\tipografo% versão 4.0 +\newcount\distanciaobjmor% versão 4.0 +\newcount\tipoarco% versão 4.0 +%\newif\ifarredondada% versão 4.0 (valor inicial "false") +\newif\ifpara% +%% version 3.2 +\newbox\caixa% +\newbox\caixaaux% +\newif\ifnvazia% +\newif\ifvazia% +\newif\ifcompara% +\newif\ifdiferentes% +\newcount\xaux% +\newcount\yaux% +\newcount\guardaauxa% +\newcount\alt% +\newcount\larg% +\newcount\prof% +%% para os ajustes +\newcount\auxqx +\newcount\auxqy +\newif\ifajusta% +\newif\ifajustadist +\def\objPartida{}% +\def\objChegada{}% +\def\objNulo{}% + + +%% +%% Stack specification +%% + +%% +%% Emtpy stack +%% +\def\!vazia{:} + +%% +%% Is Empty? : Stack -> Bool +%% +%% nvazia - True if Not Empy +%% vazia - True if Empty +\def\!pilhanvazia#1{\let\arg=#1% +\if:\arg\ \nvaziafalse\vaziatrue \else \nvaziatrue\vaziafalse\fi} + +%% +%% Push : Elems x Stack -> Stack +%% +\def\!coloca#1#2{\edef\pilha{#1.#2}} + +%% +%% Top : Stack -> Elems +%% +%% the empty stack is not taken care +%% the element is "kept" ("guardado") +\def\!guarda(#1)(#2,#3)(#4,#5,#6){\def\id{#1}% +\xaux=#2% +\yaux=#3% +\alt=#4% +\larg=#5% +\prof=#6% +} + +\def\!topaux#1.#2:{\!guarda#1} +\def\!topo#1{\expandafter\!topaux#1} + +%% +%% Pop : Stack -> Stack +%% +%% the empty stack is not taken care +\def\!popaux#1.#2:{\def\pilha{#2:}} +\def\!retira#1{\expandafter\!popaux#1} + +%% +%% Compares words : Word x Word -> Bool +%% +%% compara - True if equal +%% diferentes - True if not equal +\def\!comparaaux#1#2{\let\argA=#1\let\argB=#2% +\ifx\argA\argB\comparatrue\diferentesfalse\else\comparafalse\diferentestrue\fi} + +\def\!compara#1#2{\!comparaaux{#1}{#2}} + +%%Comando Interno +%% Valor absoluto (absolute value) +%% \absoluto{n}{absn} +%% entrada +%% n - natural +%% sa{\'\i}da +%% absn - o valor absoluto de n +\def\!absoluto#1#2{\n=#1% + \ifnum \n > 0 + #2=\n + \else + \multiply \n by -1 + #2=\n + \fi} + + +%% Name definitions for edge types and directions +\def\solidarrow{0} +\def\dasharrow{1} +\def\solidline{2} +\def\injectionarrow{3} +\def\aplicationarrow{4} +%% Name definitions for edge label placement +\def\atright{-1} +\def\atleft{1} +%% Tip direction for curved edges +\def\pup{0} +\def\pdown{1} +\def\pright{2} +\def\pleft{3} +%% Type of graph +\def\commdiag{0} +\def\digraph{1} +\def\undigraph{2} +\def\cdigraph{3} +\def\cundigraph{4} +%% Posicionamento da etiquetas nos grafos +\def\pcent{0} +\def\north{1} +\def\northeast{2} +\def\east{3} +\def\southeast{4} +\def\south{5} +\def\southwest{6} +\def\west{7} +\def\northwest{8} + + + +%%Comando Interno +%% Ajusta a dist{\^a}ncia entre as setas e os objectos em fun{\c c}{\~a}o das +%% dimens{\~o}es destes {\'u}ltimos +%% \ajusta{x}{xl}{y}{yl}{d}{Objecto} +%% entrada +%% (x,y) e (xl,yl), coordenadas dos pontos de {\'\i}nicio e fim da seta +%% d, dist{\^a}ncia especificada pelo utilizador ou 10 (valor por +%% omiss{\~a}o), Objecto d{\'a}-nos a refer{\^e}ncia do objecto ao qual se est{\'a} a +%% efectuar o ajuste. +%% sa{\'\i}da +%% d, dist{\^a}ncia alterada. +%% +%% A dist{\^a}ncia alterada {\'e} o maior valor entre 10 e as dimens{\~o}es +%% apropriadas da caixa que cont{\^e}m o objecto. +%% Se o utilizador especificar um valor essa especifica{\c c}{\~a}o +%% n{\~a}o {\'e} alterada. +%% +%% Se a seta {\'e} horizontal usa-se o valor da largura +%% Se a seta {\'e} vertical usa-se: +%% o valor da altura se a seta est{\'a} no 1o ou 2o quadrante +%% o valor da profundidade se a seta est{\'a} no 3o ou 4o quadrante +%% Se a seta {\'e} {\'o}bliqua vai-se escolher o valor conforme: +%% de 315 a 45 graus usa-se a largura +%% de 45 a 135 graus usa-se a altura +%% de 135 a 225 graus usa-se a largura +%% de 225 a 315 graus usa-se a profundidade +\def\!ajusta#1#2#3#4#5#6{\aux=#5% + \let\auxobj=#6% + \ifcase \tipografo % diagramas comutativos + \ifnum\number\aux=10 + \ajustadisttrue % se o valor é o valor por omissão ajusta + \else + \ajustadistfalse % caso contrário não ajusta + \fi + \else % grafos (dirigidos, não dirigidos, com molduras) + \ajustadistfalse +% \or % grafos não dirigidos +% \ajustadistfalse +% \else % grafos dirigidos com molduras circulares nos objectos +% \ifnum\number\aux=8 +% \ajustadisttrue % se o valor é o valor por omissão ajusta +% \else +% \ajustadistfalse % caso contrário não ajusta +% \fi + \fi + \ifajustadist +% \tiny Vou ajustar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \ifnum\number\aux=10% verificar se s{\~a}o os valores por omiss{\~a}o + \let\pilhaaux=\pilha% + \loop% + \!topo{\pilha}% + \!retira{\pilha}% + \!compara{\id}{\auxobj}% + \ifcompara\nvaziafalse \else\!pilhanvazia\pilha \fi% + \ifnvazia% + \repeat% +%% rep{\~o}e os valores na pilha + \let\pilha=\pilhaaux% + \ifvazia% + \ifdiferentes% +%% +%% N{\~a}o {\'e} poss{\'\i}vel efectuar o ajuste dado o utilizador n{\~a}o ter +%% especificado uma etiqueta para o objecto em quest{\~a}o. {\'E} dado o +%% valor de 10, igual ao valor por omiss{\~a}o. +%% + \larg=1310720% n{\~a}o faz o ajuste + \prof=655360% + \alt=655360% + \fi% + \fi% + \divide\larg by 131072 + \divide\prof by 65536 + \divide\alt by 65536 + \ifnum\number\y=\number\yl +%% Caso 1 -- seta horizontal +%% +%% divide-se por 131072 para se obter metade da largura da caixa em +%% pontos (pt), isto dado que o texto est{\'a} centrado na caixa. Soma-se +%% mais tr{\^e}s, que constitue um ajuste imp{\'\i}rico. + \advance\larg by 3 + \ifnum\number\larg>\aux + #5=\larg + \fi + \else + \ifnum\number\x=\number\xl + \ifnum\number\yl>\number\y +%% Caso 2.1 -- seta vertical de cima para baixa +%% + \ifnum\number\alt>\aux + #5=\alt + \fi + \else +%% Caso 2.2 -- seta vertical de baixo para cima +%% +%% divide-se por 65536 para se obter a altura da caixa em pt. O ajuste +%% de 5 foi obtido imp{\'\i}ricamente + \advance\prof by 5 + \ifnum\number\prof>\aux + #5=\prof + \fi + \fi + \else +%% Caso 3 -- seta obl{\'\i}qua +%% Caso 3.1 de 315o a 45o; |x-xl|>|y-yl| e +%% Caso 3.3 de 135o a 225o; |x-xl|>|y-yl|; Largura + \auxqx=\x + \advance\auxqx by -\xl + \!absoluto{\auxqx}{\auxqx}% + \auxqy=\y + \advance\auxqy by -\yl + \!absoluto{\auxqy}{\auxqy}% + \ifnum\auxqx>\auxqy + \ifnum\larg<10 + \larg=10 + \fi + \advance\larg by 3 + #5=\larg + \else +%% Caso 3.2 de 45o a 135o; |x-xl|<|y-yl| e y>0; Largura + \ifnum\yl>\y + \ifnum\larg<10 + \larg=10 + \fi + \advance\alt by 6 + #5=\alt + \else +%% Caso 3.4 de 225o a 315o; |x-xl|<|y-yl| e y<0; Profundidade + \advance\prof by 11 + #5=\prof + \fi + \fi + \fi + \fi +\fi} % o ramo "else" {\'e} omisso + + +%%Comando Interno +%% C{\'a}lculo da Raiz Quadrada +%% raiz{n}{m} +%% entrada +%% n - natural +%% sa{\'\i}da +%% n - natural +%% m - maior natural contido na raiz quadrada de n +\def\!raiz#1#2{\n=#1% + \m=1% + \loop + \aux=\m% + \advance \aux by 1% + \multiply \aux by \aux% + \ifnum \aux < \n% + \advance \m by 1% + \paratrue% + \else\ifnum \aux=\n% + \advance \m by 1% + \paratrue% + \else\parafalse% + \fi + \fi + \ifpara% + \repeat +#2=\m} + +%%Comando Interno +%% Calcula os pontos de +%% come{\c c}o da "seta" +%% fim da "seta" +%% coloca{\c c}{\~a}o do s{\'\i}mbolo +%% +%% ucoord{x1}{x2}{x3}{x4}{x5}{x6}{+|- 1} +%% entrada +%% x1,x2,x3,x4,x5 +%% sa{\'\i}da +%% x6 +%% +%% x2 - x1 +%% x6 = x3 +|- ------- x4 +%% x5 +\def\!ucoord#1#2#3#4#5#6#7{\aux=#2% + \advance \aux by -#1% + \multiply \aux by #4% + \divide \aux by #5% + \ifnum #7 = -1 \multiply \aux by -1 \fi% + \advance \aux by #3% +#6=\aux} + +%%Comando Interno +%% C{\'a}lculo do Quadrado da Dist{\^a}ncia Euclidiana entre dois pontos +%% quadrado{n}{m}{l} +%% entrada +%% n - natural +%% m - natural +%% sa{\'\i}da +%% l = (n-m)*(n-m) +\def\!quadrado#1#2#3{\aux=#1% + \advance \aux by -#2% + \multiply \aux by \aux% +#3=\aux} + +%%Comando Interno +%% C{\'a}lculo auxiliar para determinar a dist{\^a}ncia entre o nome do +%% morfismo e a seta. +%% entrada +%% (x,y), (x',y') e o nome do morfismo +%% sa{\'\i}da +%% dnm - dist{\^a}ncia do nome ao morfismo respectivo devidamente +%% compensada pelo tamanho do objecto +%% Observa{\c c}{\~o}es +%% A compensa{\c c}{\~a}o s{\'o} est{\'a} a ser feita para setas +%% horizontais e verticais. As obl{\'\i}quas s{\~a}o tratadas de +%% outra forma. +%% algoritmo +%% caixa0 <- nome do morfismo +%% se x-xl = 0 entao {recta vertical} +%% aux <- largura da caixa0 +%% dnm <- convers{\~a}o-sp-pt(aux)/2+3 +%% sen{\~a}o {recta n{\~a}o vertical} +%% se y-yl = 0 entao {recta horizontal} +%% aux <- altura+profundidade da caixa0 +%% dnm <- convers{\~a}o-sp-pt(aux)/2+3 +%% sen{\~a}o {recta obl{\'\i}qua} +%% dnm <- 3 +%% fimse +%% fimse +%% fimalgoritmo +\def\!distnomemor#1#2#3#4#5#6{\setbox0=\hbox{#5}% + \aux=#1 + \advance \aux by -#3 + \ifnum \aux=0 + \aux=\wd0 \divide \aux by 131072 + \advance \aux by 3 + #6=\aux + \else + \aux=#2 + \advance \aux by -#4 + \ifnum \aux=0 + \aux=\ht0 \advance \aux by \dp0 \divide \aux by 131072 + \advance \aux by 3 + #6=\aux% + \else + #6=3 + \fi + \fi +} + + +%% +%% O ambiente "begindc...enddc" +%% +\def\begindc#1{\!ifnextchar[{\!begindc{#1}}{\!begindc{#1}[30]}} +\def\!begindc#1[#2]{\beginpicture + \let\pilha=\!vazia + \setcoordinatesystem units <1pt,1pt> + \expansao=#2 + \ifcase #1 + \distanciaobjmor=10 + \tipoarco=0 % seta + \tipografo=0 % diagrama comutativo + \or + \distanciaobjmor=2 + \tipoarco=0 % seta + \tipografo=1 % grafo orientado + \or + \distanciaobjmor=1 + \tipoarco=2 % linha + \tipografo=2 % grafo não orientado + \or + \distanciaobjmor=8 + \tipoarco=0 % seta + \tipografo=3 % grafo orientado +% \arredondadotrue % objectos com molduras circulares + \or + \distanciaobjmor=8 + \tipoarco=2 % linha + \tipografo=4 % grafo não orientado +% \arredondadotrue % objectos com molduras circulares + \fi} + +\def\enddc{\endpicture} + + +%% +%% Comando para construir a "seta" entre dois objectos +%% +%% Os pontos definidores da seta e da etiqueta respectiva s{\~a}o: +%% +%% (xd,yd) +%% o +%% | +%% o------o---------o---------o------o +%%(x,y) (xa,ya) (xm,ym) (xb,yb)(xl,yl) +%% +\def\mor{% + \!ifnextchar({\!morxy}{\!morObjA}} +\def\!morxy(#1,#2){% + \!ifnextchar({\!morxyl{#1}{#2}}{\!morObjB{#1}{#2}}} +\def\!morxyl#1#2(#3,#4){% + \!ifnextchar[{\!mora{#1}{#2}{#3}{#4}}{\!mora{#1}{#2}{#3}{#4}[\number\distanciaobjmor,\number\distanciaobjmor]}}% +\def\!morObjA#1{% + \let\pilhaaux=\pilha% + \def\objPartida{#1}% + \loop% + \!topo\pilha% + \!retira\pilha% + \!compara{\id}{\objPartida}% + \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi% + \ifnvazia% + \repeat% + \ifvazia% + \ifdiferentes% +%% +%% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos +%% argumentos dos comandos que se seguem. +%% + Error: Incorrect label specification% + \xaux=1% + \yaux=1% + \fi% + \fi% + \let\pilha=\pilhaaux% + \!ifnextchar({\!morxyl{\number\xaux}{\number\yaux}}{\!morObjB{\number\xaux}{\number\yaux}}} +\def\!morObjB#1#2#3{% + \x=#1 + \y=#2 + \def\objChegada{#3}% + \let\pilhaaux=\pilha% + \loop + \!topo\pilha % + \!retira\pilha% + \!compara{\id}{\objChegada}% + \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi + \ifnvazia + \repeat + \ifvazia + \ifdiferentes% +%% +%% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos +%% argumentos dos comandos que se seguem. +%% + Error: Incorrect label specification + \xaux=\x% + \advance\xaux by \x% + \yaux=\y% + \advance\yaux by \y% + \fi + \fi + \let\pilha=\pilhaaux + \!ifnextchar[{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}}{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}[\number\distanciaobjmor,\number\distanciaobjmor]}} +\def\!mora#1#2#3#4[#5,#6]#7{% + \!ifnextchar[{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}}{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}[1,\number\tipoarco] }} +\def\!morb#1#2#3#4#5#6#7[#8,#9]{\x=#1% + \y=#2% + \xl=#3% + \yl=#4% + \multiply \x by \expansao% + \multiply \y by \expansao% + \multiply \xl by \expansao% + \multiply \yl by \expansao% +%% +%% calcular a dist{\^a}ncia Euclidiana entre dois pontos +%% d = \sqrt((x-xl)^2+(y-yl)^2) +%% + \!quadrado{\number\x}{\number\xl}{\auxa}% + \!quadrado{\number\y}{\number\yl}{\auxb}% + \d=\auxa% + \advance \d by \auxb% + \!raiz{\d}{\d}% +%% +%% o ponto (xa,ya) est{\'a} {\`a} dist{\^a}ncia #5 (valor por omiss{\~a}o 10) do ponto +%% (x,y) +%% +%% como existem dois pontos em considera{\c c}{\~a}o, o ponto de partida e o +%% ponto de chegada, vai sei necess{\'a}rio recuperar de novo os seus +%% valores por pesquisa na pilha + \auxa=#5 + \!compara{\objNulo}{\objPartida}% + \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio + \!ajusta{\x}{\xl}{\y}{\yl}{\auxa}{\objPartida}% + \ajustatrue + \def\objPartida{}% re-inicializar o valor do Objecto de Partida + \fi +%% vai guardar o valor de auxa (ap{\'o}s ajuste) para ser usado no caso +%% dos morfismos de injec{\c c}{\~a}o. + \guardaauxa=\auxa +%% + \!ucoord{\number\x}{\number\xl}{\number\x}{\auxa}{\number\d}{\xa}{1}% + \!ucoord{\number\y}{\number\yl}{\number\y}{\auxa}{\number\d}{\ya}{1}% +%% auxa vai ter o valor da dist{\^a}ncia entre os objectos menos a +%% dist{\^a}ncia da seta ao objecto (10 por omiss{\~a}o) + \auxa=\d% +%% +%% o ponto (xb,yb) est{\'a} {\`a} dist{\^a}ncia #6 (valor por omiss{\~a}o 10) do ponto +%% (xl,yl) +%% + \auxb=#6 + \!compara{\objNulo}{\objChegada}% + \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio +% Vou ajustar + \!ajusta{\x}{\xl}{\y}{\yl}{\auxb}{\objChegada}% + \def\objChegada{}% re-inicializar o valor do Objecto de Chegada + \fi + \advance \auxa by -\auxb% + \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xb}{1}% + \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\yb}{1}% + \xmed=\xa% + \advance \xmed by \xb% + \divide \xmed by 2 + \ymed=\ya% + \advance \ymed by \yb% + \divide \ymed by 2 +%% +%% + \!distnomemor{\number\x}{\number\y}{\number\xl}{\number\yl}{#7}{\dnm}% + \!ucoord{\number\y}{\number\yl}{\number\xmed}{\number\dnm}{\number\d}{\xc}{-#8}% + \!ucoord{\number\x}{\number\xl}{\number\ymed}{\number\dnm}{\number\d}{\yc}{#8}% +\ifcase #9 % seta s{\'o}lida + \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb} +\or % seta a tracejado + \setdashes + \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb} + \setsolid +\or % linha s{\'o}lida + \setlinear + \plot {\xa} {\ya} {\xb} {\yb} / +\or % seta de injec{\c c}{\~a}o +%% C{\'a}lculos auxiliares +%% +%% 3 valor para o raio do "rabo" da "seta" +%% +%% repor o valor de auxa + \auxa=\guardaauxa +%% dar a compensa{\c c}{\~a}o para o "rabo" + \advance \auxa by 3% +%% +%% IMPORTANTE os valores de xa e ya v{\~a}o ser alterados +%% + \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xa}{1}% + \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\ya}{1}% + \!ucoord{\number\y}{\number\yl}{\number\xa}{3}{\number\d}{\xd}{-1}% + \!ucoord{\number\x}{\number\xl}{\number\ya}{3}{\number\d}{\yd}{1}% +%% Constru{\c c}{\~a}o da "seta" + \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb} +%% e do seu "rabo" + \circulararc -180 degrees from {\xa} {\ya} center at {\xd} {\yd} +\or % seta de aplica{\c c}{\~a}o ("|-->") + \auxa=3% valor para o meio-segmento do "rabo" da "seta" +%% c{\'a}lculo dos pontos (xmed,ymed) e (xd,yd) para o segmento de recta que +%% define o "rabo" da seta + \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xmed}{-1}% + \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\ymed}{1}% + \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xd}{1}% + \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\yd}{-1}% +%% Constru{\c c}{\~a}o da "seta" + \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb} +%% e do seu "rabo" + \setlinear + \plot {\xmed} {\ymed} {\xd} {\yd} / +\fi +%% Coloca{\c c}{\~a}o do nome do morfismo. +%% Se os morfismos s{\~a}o horizontais ou verticais constro{\'\i} uma caixa +%% centrada no ponto pr{\'e}viamente calculado. Se as setas s{\~a}o +%% obl{\'\i}quas coloca a caixa de forma a n{\~a}o colidir com o morfismo +%% tendo em aten{\c c}{\~a}o o quadrante assim como a posi{\c c}{\~a}o +%% relativa do morfismo e do respectivo nome. +\auxa=\xl +\advance \auxa by -\x% +\ifnum \auxa=0 + \put {#7} at {\xc} {\yc} +\else + \auxb=\yl + \advance \auxb by -\y% + \ifnum \auxb=0 \put {#7} at {\xc} {\yc} + \else + \ifnum \auxa > 0 + \ifnum \auxb > 0 + \ifnum #8=1 + \put {#7} [rb] at {\xc} {\yc} + \else + \put {#7} [lt] at {\xc} {\yc} + \fi + \else + \ifnum #8=1 + \put {#7} [lb] at {\xc} {\yc} + \else + \put {#7} [rt] at {\xc} {\yc} + \fi + \fi + \else + \ifnum \auxb > 0 + \ifnum #8=1 + \put {#7} [rt] at {\xc} {\yc} + \else + \put {#7} [lb] at {\xc} {\yc} + \fi + \else + \ifnum #8=1 + \put {#7} [lt] at {\xc} {\yc} + \else + \put {#7} [rb] at {\xc} {\yc} + \fi + \fi + \fi + \fi +\fi +} + +%% +%% Comando para construir a "seta" curvilinea entre dois objectos +%% +%% \cmor(<lista de pontos (n. impar)>){<etiqueta>} +%% +%% Em primeiro lugar {\'e} necess{\'a}rio modificar o comando plot de forma a +%% que a sintaxe de utiliza{\c c}{\~a}o do novo comando seja coerente com a +%% sintaxe dos restantes comandos +%% +\def\modifplot(#1{\!modifqcurve #1} +\def\!modifqcurve(#1,#2){\x=#1% + \y=#2% + \multiply \x by \expansao% + \multiply \y by \expansao% + \!start (\x,\y) + \!modifQjoin} +\def\!modifQjoin(#1,#2)(#3,#4){\x=#1% + \y=#2% + \xl=#3% + \yl=#4% + \multiply \x by \expansao% + \multiply \y by \expansao% + \multiply \xl by \expansao% + \multiply \yl by \expansao% + \!qjoin (\x,\y) (\xl,\yl) % \!qjoin is defined in QUADRATIC + \!ifnextchar){\!fim}{\!modifQjoin}} +\def\!fim){\ignorespaces} + +%% +%% O comando para desenhar a seta vai receber a lista de pontos da qual +%% retira o {\'u}ltimo par de pontos, dependente da escolha dada pelo +%% utilizador a seta vai ser desenhada para cima, para baixo, para a +%% direita ou para a esquerda +%% +\def\setaxy(#1{\!pontosxy #1} +\def\!pontosxy(#1,#2){% + \!maispontosxy} +\def\!maispontosxy(#1,#2)(#3,#4){% + \!ifnextchar){\!fimxy#3,#4}{\!maispontosxy}} +\def\!fimxy#1,#2){\x=#1% + \y=#2 + \multiply \x by \expansao + \multiply \y by \expansao + \xl=\x% + \yl=\y% + \aux=1% + \multiply \aux by \auxa% + \advance\xl by \aux% + \aux=1% + \multiply \aux by \auxb% + \advance\yl by \aux% + \arrow <4pt> [.2,1.1] from {\x} {\y} to {\xl} {\yl}} + + +%% +%% Temos agora a defini{\c c}{\~a}o do comando "cmor" +%% +\def\cmor#1 #2(#3,#4)#5{% + \!ifnextchar[{\!cmora{#1}{#2}{#3}{#4}{#5}}{\!cmora{#1}{#2}{#3}{#4}{#5}[0] }} +\def\!cmora#1#2#3#4#5[#6]{% + \ifcase #2% para cima "\pup" (pointing up) + \auxa=0% x mant{\^e}m-se + \auxb=1% o y "sobe" + \or% para baixo "\pdown" (pointing down) + \auxa=0% x mant{\^e}m-se + \auxb=-1% o y "desce" + \or% para a direita "\pright" (pointing right) + \auxa=1% o x move-se para a direita + \auxb=0% o y mant{\^e}m-se + \or% para a esquerda "\pleft" (pointing left) + \auxa=-1% o x move-se para a esquerda + \auxb=0% o y mant{\^e}m-se + \fi % constru{\c c}{\~a}o do arco + \ifcase #6 % arco (com seta) s{\'o}lido + \modifplot#1% Desenhar o arco + % constru{\c c}{\~a}o da seta + \setaxy#1 + \or % arco (com seta) a tracejado + \setdashes + \modifplot#1% Desenhar o arco + \setaxy#1 + \setsolid + \or % arco sem seta + \modifplot#1% Desenhar o arco + \fi % seta de injec{\c c}{\~a}o +%% coloca{\c c}{\~a}o da etiqueta do morfismo + \x=#3% + \y=#4% + \multiply \x by \expansao% + \multiply \y by \expansao% + \put {#5} at {\x} {\y}} + +%% +%% Comando para construir os Objectos +%% \obj(x,y){<texto>}[<etiqueta>] +%% +\def\obj(#1,#2){% + \!ifnextchar[{\!obja{#1}{#2}}{\!obja{#1}{#2}[Nulo]}} +\def\!obja#1#2[#3]#4{% + \!ifnextchar[{\!objb{#1}{#2}{#3}{#4}}{\!objb{#1}{#2}{#3}{#4}[1]}} +\def\!objb#1#2#3#4[#5]{% + \x=#1% + \y=#2% + \def\!pinta{\normalsize$\bullet$}% para definir o tamanho normal das pintas + \def\!nulo{Nulo}% + \def\!arg{#3}% + \!compara{\!arg}{\!nulo}% + \ifcompara\def\!arg{#4}\fi% + \multiply \x by \expansao% + \multiply \y by \expansao% + \setbox\caixa=\hbox{#4}% + \!coloca{(\!arg)(#1,#2)(\number\ht\caixa,\number\wd\caixa,\number\dp\caixa)}{\pilha}% + \auxa=\wd\caixa \divide \auxa by 131072 + \advance \auxa by 5 + \auxb=\ht\caixa + \advance \auxb by \number\dp\caixa + \divide \auxb by 131072 + \advance \auxb by 5 +%(\number\auxa, +%\number\auxb) +% \aux=\ht\caixa \divide \auxa by 131072 +% \advance \auxa by 5 +% \auxb=\dp\caixa \divide \auxb by 131072 +% \advance \auxb by 8 + \ifcase \tipografo % diagramas comutativos + \put{#4} at {\x} {\y} + \or % grafos dirigidos + \ifcase #5 % c=0 + \put{#4} at {\x} {\y} + \or % n=1 + \put{\!pinta} at {\x} {\y} + \advance \y by \number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % ne=2 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % para fazer o ajuste (imperfeito) + \advance \auxb by -2 % ao raio da circunferência de centro (x,y) + \advance \x by \number\auxa % width+5 + \advance \y by \number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % e=3 + \put{\!pinta} at {\x} {\y} + \advance \x by \number\auxa % width+5 + \put{#4} at {\x} {\y} + \or % se=4 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % para fazer o ajuste (imperfeito) + \advance \auxb by -2 % ao raio da circunferência de centro (x,y) + \advance \x by \number\auxa % width+5 + \advance \y by -\number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % s=5 + \put{\!pinta} at {\x} {\y} + \advance \y by -\number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % sw=6 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % para fazer o ajuste (imperfeito) + \advance \auxb by -2 % ao raio da circunferência de centro (x,y) + \advance \x by -\number\auxa % width+5 + \advance \y by -\number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % w=7 + \put{\!pinta} at {\x} {\y} + \advance \x by -\number\auxa % width+5 + \put{#4} at {\x} {\y} + \or % nw=8 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % para fazer o ajuste (imperfeito) + \advance \auxb by -2 % ao raio da circunferência de centro (x,y) + \advance \x by -\number\auxa % width+5 + \advance \y by \number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \fi + \or % grafos não dirigidos + \ifcase #5 % c=0 + \put{#4} at {\x} {\y} + \or % n=1 + \put{\!pinta} at {\x} {\y} + \advance \y by \number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % ne=2 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % para fazer o ajuste (imperfeito) + \advance \auxb by -2 % ao raio da circunferência de centro (x,y) + \advance \x by \number\auxa % width+5 + \advance \y by \number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % e=3 + \put{\!pinta} at {\x} {\y} + \advance \x by \number\auxa % width+5 + \put{#4} at {\x} {\y} + \or % se=4 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % ver acima + \advance \auxb by -2 + \advance \x by \number\auxa % width+5 + \advance \y by -\number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % s=5 + \put{\!pinta} at {\x} {\y} + \advance \y by -\number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % sw=6 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % ver acima + \advance \auxb by -2 + \advance \x by -\number\auxa % width+5 + \advance \y by -\number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \or % w=7 + \put{\!pinta} at {\x} {\y} + \advance \x by -\number\auxa % width+5 + \put{#4} at {\x} {\y} + \or % nw=8 + \put{\!pinta} at {\x} {\y} + \advance \auxa by -2 % ver acima + \advance \auxb by -2 + \advance \x by -\number\auxa % width+5 + \advance \y by \number\auxb % height+depth+5 + \put{#4} at {\x} {\y} + \fi +% \or % grafos dirigidos com molduras circulares nos objectos +% \advance \auxa by 4 +% \put{\circle{\auxa}} [Bl] at {\x} {\y} +% \put{#4} at {\x} {\y} +% \or % grafos não dirigidos com molduras circulares nos objectos + \else % grafos com molduras circulares nos objectos + \ifnum\auxa<\auxb % determina a maior das dimensões + \aux=\auxb + \else + \aux=\auxa + \fi +% se a largura da caixa é menor do que 1em então o tamanho +% tamanho é ajustado para esse valor mínimo + \ifdim\wd\caixa<1em + \dimen99 = 1em + \aux=\dimen99 \divide \aux by 131072 + \advance \aux by 5 + \fi + \advance\aux by -2 %folga entre o objecto e a moldura + \multiply\aux by 2 % + \ifnum\aux<30 + \put{\circle{\aux}} [Bl] at {\x} {\y} + \else + \multiply\auxa by 2 + \multiply\auxb by 2 + \put{\oval(\auxa,\auxb)} [Bl] at {\x} {\y} + \fi + \put{#4} at {\x} {\y} + \fi +} + + +\catcode`!=12 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX) |