Skip to content

Commit

Permalink
add asymptote code for drawing automata of Coxeter groups
Browse files Browse the repository at this point in the history
  • Loading branch information
neozhaoliang committed Mar 16, 2021
1 parent 114c2ef commit d581f5e
Show file tree
Hide file tree
Showing 5 changed files with 391 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/uniform-tilings/asy_automata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This folder contains asymptote scripts for drawing automata of Coxeter groups.

The script `simplenode` is a third-party module developed by [Liu HaiYang]([email protected]).
97 changes: 97 additions & 0 deletions src/uniform-tilings/asy_automata/dfa_73.asy
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import simplenode;

settings.tex="xelatex";
usepackage("mathpazo");
settings.outformat="eps";

real u = 2cm;
Arrow = Arrow(4);
pen text = white;
pen starttext = black;
pen temp = linewidth(0.8) + fontsize(9pt);

pen nodepen = deepgreen;

draw_t Initial = none;
draw_t State = compose(shadow, filldrawer(nodepen, darkgreen+0.6));
draw_t Accepting = compose(shadow, filler(nodepen),
drawer(darkgreen+1.8), drawer(white+0.6));
draw_t Starting = compose(shadow, filler(red),
drawer(darkgreen+1.8), drawer(white+0.6));

pair V = dir(60);
pair V_conj = dir(270);
pair V_neg = dir(120);
pair S7 = dir(180/7.0);
real a = 120;
real c = 180*5/7;
real dt = 180/6;
real L = 1.6 * u;
pair U = dir(240);

node q8 = Circle("$q_{8}$", (0,0), text, Accepting),
q9 = Circle("$q_9$", q8.pos + u*V_conj, text, Accepting),
q10 = Circle("$q_{10}$", rotate(-a, q9.pos)*q8.pos, text, Accepting),
q11 = Circle("$q_{11}$", rotate(-a, q10.pos)*q9.pos, text, Accepting),
q12 = Circle("$q_{12}$", rotate(-a, q11.pos)*q10.pos, text, Accepting),
q6 = Circle("$q_{6}$", rotate(-a, q12.pos)*q11.pos , text, Accepting),
q18 = Circle("$q_{18}$", rotate(-c, q11.pos)*q12.pos, text, Accepting),
q16 = Circle("$q_{16}$", rotate(-c, q18.pos)*q11.pos, text, Accepting),
q15 = Circle("$q_{15}$", rotate(-c, q16.pos)*q18.pos, text, Accepting),
q14 = Circle("$q_{14}$", rotate(-c, q15.pos)*q16.pos, text, Accepting),
q13 = Circle("$q_{13}$", rotate(-c, q14.pos)*q15.pos, text, Accepting),
q17 = Circle("$q_{17}$", rotate(-108, q13.pos)*q12.pos, text, Accepting),
q7 = Circle("$q_{7}$", rotate(-108, q17.pos)*q13.pos, text, Accepting),
q1 = Circle("$q_{1}$", q8.pos+L*U, text, Accepting),
q0 = Circle("$q_{0}$", rotate(-dt, q8.pos)*q1.pos, text, Starting),
q2 = Circle("$q_{2}$", rotate(-dt, q8.pos)*q0.pos, text, Accepting),
q3 = Circle("$q_{3}$", rotate(-dt, q8.pos)*q2.pos, text, Accepting),
q4 = Circle("$q_{4}$", rotate(-dt, q8.pos)*q3.pos, text, Accepting),
q5 = Circle("$q_{5}$", rotate(-dt, q8.pos)*q4.pos, text, Accepting);

currentpen = temp;
node start = Circle("$\mathrm{Start}$", q0.pos + u*W, starttext, Initial);
draw(start, q6, q8, q9, q10, q11, q12, q18, q16, q15,
q14, q13, q17, q7, q1, q2, q0, q3, q4, q5);

draw(start -- q0 @ shorten(-2, 2), Arrow);

currentpen = temp + red*0.8;
draw("$s_0$", q0 -- q1 @ shorten, Arrow);
draw("$s_0$", q2 -- q3 @ shorten, Arrow);
draw("$s_0$", q4 -- q5 @ shorten, Arrow);
draw("$s_0$", q6 -- q7 @ shorten, Arrow);
draw("$s_0$", q9 -- q10 @ shorten, Arrow);
draw("$s_0$", q11 -- q12 @ shorten, Arrow);
draw("$s_0$", q14 -- q15 @ shorten, Arrow);
draw(Label("$s_0$", LeftSide), q16 .. bend(-80) .. q17 @ shorten, Arrow);

currentpen = temp + olive;
draw("$s_1$", q0 -- q2 @ shorten, Arrow);
draw("$s_1$", q3 -- q4 @ shorten, Arrow);
draw("$s_1$", q12 -- q6 @ shorten, Arrow);
draw("$s_1$", q10 -- q11 @ shorten, Arrow);
draw("$s_1$", q13 -- q14 @ shorten, Arrow);
draw("$s_1$", q15 -- q16 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q8 -- q9 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q17 -- q7 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q1 .. bend(70) .. q2 @ shorten, Arrow);
draw(shift(-0.15*u, 0.1*u)*Label("$s_1$", LeftSide), q5 .. bend(30) .. q6 @ shorten, Arrow);

currentpen = temp + rgb(30, 144, 255);
draw("$s_2$", q0 -- q8 @ shorten, Arrow);
draw("$s_2$", q1 -- q8 @ shorten, Arrow);
draw("$s_2$", q2 -- q8 @ shorten, Arrow);
draw("$s_2$", q3 -- q8 @ shorten, Arrow);
draw("$s_2$", q4 -- q8 @ shorten, Arrow);
draw("$s_2$", q5 -- q8 @ shorten, Arrow);
draw("$s_2$", q6 -- q8 @ shorten, Arrow);
draw("$s_2$", q17 -- q13 @ shorten, Arrow);
draw("$s_2$", q16 -- q18 @ shorten, Arrow);
draw("$s_2$", q12 -- q13 @ shorten, Arrow);
draw(Label("$s_2$", RightSide), q7 .. bend(-25) .. q8 @ shorten, Arrow);
draw(Label("$s_2$", LeftSide), q11 -- q18 @ shorten, Arrow);

//label("$\Delta(7,2,3)=\langle s_{0},s_{1},s_{2} \, |\, s^2_{0}=s^2_{1}=s^2_{2}=(s_{0}s_{1})^7=(s_{0}s_{2})^2=(s_{1}s_{2})^3=1\rangle.$",(-0.8u, -2.5u));

shipout(bbox(xmargin=0.3cm, ymargin=0.2cm, FillDraw(fillpen=white, drawpen=white)));
71 changes: 71 additions & 0 deletions src/uniform-tilings/asy_automata/dfa_A2.asy
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import simplenode;

settings.tex="xelatex";
usepackage("mathpazo");
settings.outformat="eps";

real u = 4cm;
Arrow = Arrow(5);
pen text = white;
pen starttext = black;
pen temp = linewidth(1.2) + fontsize(9pt);

pen nodepen = deepgreen;

draw_t Initial = none;
draw_t State = compose(shadow, filldrawer(nodepen, darkgreen+0.6));
draw_t Accepting = compose(shadow, filler(nodepen),
drawer(darkgreen+1.8), drawer(white+0.6));
draw_t Starting = compose(shadow, filler(red),
drawer(darkgreen+1.8), drawer(white+0.6));

real u2 = u / sqrt(3);

node
q0 = Circle("$q_{0}$", (0, 0), text, Starting),
q1 = Circle("$q_{1}$", q0.pos + u2*dir(30), text, Accepting),
q2 = Circle("$q_{2}$", q0.pos + u2*N, text, Accepting),
q3 = Circle("$q_{3}$", q0.pos + u2*dir(-30), text, Accepting),
q4 = Circle("$q_{4}$", q3.pos + u2*S, text, Accepting),
q5 = Circle("$q_{5}$", q4.pos + u2*S, text, Accepting),
q6 = Circle("$q_{6}$", q5.pos + u2*dir(30), text, Accepting),
q7 = Circle("$q_{7}$", q1.pos + u2*dir(-30), text, Accepting),
q8 = Circle("$q_{8}$", q3.pos + u2*dir(-30), text, Accepting),
q9 = Circle("$q_{9}$", q8.pos + u2*dir(30), text, Accepting),
q10 = Circle("$q_{10}$", q9.pos + u2*N, text, Accepting),
q11 = Circle("$q_{11}$", q10.pos + u2*N, text, Accepting),
q12 = Circle("$q_{12}$", q10.pos + u2*dir(150), text, Accepting);

currentpen = temp;
node start = Circle("$\mathrm{Start}$", q0.pos + u/2.5*W, starttext, Initial);
draw(start, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12);
draw(start -- q0 @ shorten(-2, 4), Arrow);

shorten = shorten(4, 4);
currentpen = temp + red*0.8;
draw(Label("$s_0$", LeftSide), q0 -- q2 @ shorten, Arrow);
draw(Label("$s_0$", LeftSide), q1 -- q7 @ shorten, Arrow);
draw(Label("$s_0$", RightSide), q3 -- q8 @ shorten, Arrow);
draw(Label("$s_0$", RightSide), q9 -- q7 @ shorten, Arrow);
draw(Label("$s_0$", LeftSide), q4 -- q6 @ shorten, Arrow);
draw(Label("$s_0$", LeftSide), q10 -- q12 @ shorten, Arrow);

currentpen = temp + olive;
draw(Label("$s_1$", RightSide), q0 -- q1 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q2 -- q1 @ shorten, Arrow);
draw(Label("$s_1$", RightSide), q3 -- q4 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q5 -- q4 @ shorten, Arrow);
draw(Label("$s_1$", RightSide), q8 -- q9 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q12 -- q11 @ shorten, Arrow);

currentpen = temp + rgb(30, 144, 255);
draw(Label("$s_2$", RightSide), q0 -- q3 @ shorten, Arrow);
draw(Label("$s_2$", RightSide), q1 -- q3 @ shorten, Arrow);
draw(Label("$s_2$", RightSide), q7 -- q3 @ shorten, Arrow);
draw(Label("$s_2$", LeftSide), q6 -- q5 @ shorten, Arrow);
draw(Label("$s_2$", RightSide), q9 -- q10 @ shorten, Arrow);
draw(Label("$s_2$", LeftSide), q11 -- q10 @ shorten, Arrow);
draw(Label("$s_2$", RightSide), q2 .. bend(-110) .. q3 @ shorten, Arrow);

currentpen = temp;
shipout(bbox(xmargin=0.3cm, ymargin=0.2cm, FillDraw(fillpen=white, drawpen=white)));
51 changes: 51 additions & 0 deletions src/uniform-tilings/asy_automata/dfa_S4.asy
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import simplenode;

settings.tex="xelatex";
usepackage("mathpazo");
settings.outformat = "eps";

real u = 2cm;
Arrow = Arrow(4);
pen text = white;
pen starttext = black;

pen temp = linewidth(0.8) + fontsize(9pt);

pen nodepen = deepgreen;

draw_t Initial = none;
draw_t State = compose(shadow, filldrawer(nodepen, darkgreen+0.6));
draw_t Accepting = compose(shadow, filler(nodepen),
drawer(darkgreen+1.8), drawer(white+0.6));
draw_t Starting = compose(shadow, filler(red),
drawer(darkgreen+1.8), drawer(white+0.6));

node q0 = Circle("$q_0$", (0, 0), text, Starting),
q1 = Circle("$q_1$", q0.pos + u*S, text, Accepting),
q3 = Circle("$q_3$", q1.pos + u*E, text, Accepting),
q2 = Circle("$q_2$", q0.pos + u*E, text, Accepting),
q4 = Circle("$q_4$", q2.pos + u*E + 0.5u*S, text, Accepting),
q5 = Circle("$q_5$", q4.pos + u*E, text, Accepting),
q6 = Circle("$q_6$", q5.pos + u*E, text, Accepting);

node start = Circle("$\mathrm{Start}$", q0.pos + 0.7u*W, starttext, Initial);
draw(start, q0, q1, q2, q3, q4, q5, q6);
draw(start -- q0 @ shorten(-2, 2), Arrow);

currentpen = temp + red*0.8;
draw(Label("$s_0$", RightSide), q0 -- q1 @ shorten, Arrow);
draw(Label("$s_0$", RightSide), q2 -- q3 @ shorten, Arrow);
draw("$s_0$", q5 -- q6 @ shorten, Arrow);

currentpen = temp + olive;
draw(Label("$s_1$", LeftSide), q0 -- q2 @ shorten, Arrow);
draw("$s_1$", q4 -- q5 @ shorten, Arrow);
draw(Label("$s_1$", LeftSide), q1 -- q2 @ shorten, Arrow);

currentpen = temp + rgb(30, 144, 255);
draw(Label("$s_2$", LeftSide), q2 -- q4 @ shorten, Arrow);
draw("$s_2$", q3 -- q4 @ shorten, Arrow);
draw(Label("$s_2$", LeftSide), q0 .. bend(60) .. q4 @ shorten, Arrow);
draw("$s_2$", q1 .. bend(-60) .. q4 @ shorten, Arrow);

shipout(bbox(xmargin=0.3cm, ymargin=0.2cm, FillDraw(fillpen=white, drawpen=white)));
169 changes: 169 additions & 0 deletions src/uniform-tilings/asy_automata/simplenode.asy
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
struct node {
path outline;
picture stuff;
pair pos;
pair E, N, W, S;
pair dir(pair v)
{
path g = shift(pos) * outline;
pair M = max(g), m = min(g), c = 0.5*(M+m);
path ray = c -- c + length(M-m)*unit(v);
return intersectionpoint(g, ray);
}
pair angle(real ang)
{
return this.dir(dir(ang));
}
}

void draw(picture pic=currentpicture, node[] nodearr)
{
for (node nd: nodearr)
add(pic, shift(nd.pos) * nd.stuff);
}

void draw(picture pic=currentpicture ... node[] nodearr)
{
draw(pic, nodearr);
}

typedef void draw_t(picture pic, path g);

draw_t compose(... draw_t[] drawfns)
{
return new void(picture pic, path g) {
for (draw_t f : drawfns)
f(pic, g);
};
}

draw_t none = new void(picture pic, path g){};

draw_t drawer(pen p)
{
return new void(picture pic, path g) {
draw(pic, g, p);
};
}
draw_t drawer=drawer(currentpen);

draw_t filler(pen p)
{
return new void(picture pic, path g) {
fill(pic, g, p);
};
}
draw_t filler=filler(currentpen);

draw_t filldrawer(pen fillpen, pen drawpen=currentpen)
{
return new void(picture pic, path g) {
filldraw(pic, g, fillpen, drawpen);
};
}

draw_t doubledrawer(pen p, pen bg=white)
{
return compose(drawer(p+linewidth(p)*3), drawer(bg+linewidth(p)));
}
draw_t doubledrawer = doubledrawer(currentpen);

draw_t shadow(pair shift=2SE, real scale=1, pen color=gray)
{
return new void(picture pic, path g) {
fill(pic, shift(shift)*scale(scale)*g, color);
};
}
draw_t shadow=shadow();

node Circle(Label text, pair pos, pen textpen=currentpen,
draw_t drawfn, real maxrad=0.4cm)
{
node nd;
nd.pos = pos;
label(nd.stuff, text, textpen);
pair M = max(nd.stuff), m = min(nd.stuff);
nd.outline = circle(0.5*(M+m), max(0.5*length(M-m), maxrad));
drawfn(nd.stuff, nd.outline);
nd.E = nd.dir(E);
nd.N = nd.dir(N);
nd.W = nd.dir(W);
nd.S = nd.dir(S);
return nd;
}

path operator--(node nd1, node nd2)
{
path g1 = shift(nd1.pos) * nd1.outline;
path g2 = shift(nd2.pos) * nd2.outline;
pair c1 = (max(g1)+min(g1)) / 2;
pair c2 = (max(g2)+min(g2)) / 2;
path edge = c1 -- c2;
edge = firstcut(edge, g1).after;
edge = lastcut(edge, g2).before;
return edge;
}

typedef path edgeconnector(node nd1, node nd2);

typedef path edgemaker(node nd);

edgemaker operator..(node nd, edgeconnector con)
{
return new path(node nd2) {
return con(nd, nd2);
};
}

path operator..(edgemaker maker, node nd)
{
return maker(nd);
}

path operator..(node nd, edgemaker maker)
{
return maker(nd);
}

edgeconnector bend(real ang)
{
return new path (node nd1, node nd2) {
path g1 = shift(nd1.pos) * nd1.outline;
path g2 = shift(nd2.pos) * nd2.outline;
pair c1 = (max(g1)+min(g1)) / 2;
pair c2 = (max(g2)+min(g2)) / 2;
real deg = degrees(c2 - c1);
return nd1.angle(deg+ang) {dir(deg+ang)}
.. {dir(deg-ang)} nd2.angle(180+deg-ang);
};
}

edgeconnector bendleft = bend(30);
edgeconnector bendright = bend(-30);

edgemaker loop(pair direction, real ratio=1.5)
{
return new path(node nd) {
real deg = degrees(direction);
real angle1 = deg - 15, angle2 = deg + 15;
pair mid = nd.angle(deg)
+ ratio*fontsize(currentpen)*unit(direction);
return nd.angle(angle1) {dir(angle1)} .. mid
.. {-dir(angle2)} nd.angle(angle2);
};
}

typedef path fpath(path);

path operator@(path p, fpath t)
{
return t(p);
}

fpath shorten(real pre=0, real post=2)
{
return new path(path p) {
return subpath(p, arctime(p, pre), arctime(p, arclength(p)-post));
};
}
fpath shorten=shorten(2,2);

0 comments on commit d581f5e

Please sign in to comment.