6 proofrulethickness 1pt#;
7 makegrid(0pt,0pt for i:=-5pt step 1pt until 5pt: ,i endfor)
8 (0pt,0pt for i:=-5pt step 1pt until 5pt: ,i endfor);
9 proofrulethickness .1pt#;
10 makegrid(0pt,0pt for i:=-4.8pt step .2pt until 4.8pt: ,i endfor)
11 (0pt,0pt for i:=-4.8pt step .2pt until 4.8pt: ,i endfor);
16 tracingequations := tracingonline := 1;
20 def draw_staff(expr first, last, offset)=
22 pickup pencircle scaled stafflinethickness;
23 for i:= first step 1 until last:
24 draw (- staff_space, (i + offset) * staff_space) .. (4 staff_space,( i+ offset)* staff_space);
35 def scaledabout(expr point, scale) =
36 shifted -point scaled scale shifted point
41 % make a local (restored after endgroup) copy of t_var
43 def local_copy(text type, t_var)=
54 % Urgh! Want to do parametric types
57 def del_picture_stack=
58 save save_picture_stack, picture_stack_idx;
61 % better versions of Taupin/Egler savepic cmds
64 def make_picture_stack =
65 % override previous stack.
67 picture save_picture_stack[];
68 numeric picture_stack_idx;
69 picture_stack_idx := 0;
70 def push_picture(expr p) =
71 save_picture_stack[picture_stack_idx] := p ;
72 picture_stack_idx := picture_stack_idx + 1;
74 def pop_picture = save_picture_stack[decr picture_stack_idx] enddef;
75 def top_picture = save_picture_stack[picture_stack_idx] enddef;
80 % why can't I delete individual pens?
84 numeric pen_stack_idx;
86 def push_pen(expr p) =
87 save_pen_stack[pen_stack_idx] := p ;
88 pen_stack_idx := pen_stack_idx +1;
90 def pop_pen = save_pen_stack[decr pen_stack_idx] enddef;
91 def top_pen = save_pen_stack[pen_stack_idx] enddef;
94 save save_pen_stack, pen_stack_idx;
101 def soft_penstroke text t =
102 forsuffixes e = l,r: path_.e:=t; endfor
106 fill path_.l .. tension1.5 .. reverse path_.r .. tension1.5 .. cycle
112 % make a round path segment going from P to Q. 2*A is the angle that the
116 def simple_serif(expr p,q, a)=
117 p{dir(angle(q-p) -a)} .. q{ - dir(angle(p -q) + a)}
122 % draw an axis aligned block making sure that edges are on pixels.
125 def draw_rounded_block (expr bottom_left, top_right, roundness) =
127 round = floor min(roundness,xpart (top_right-bottom_left),
128 ypart (top_right-bottom_left));
131 pickup pencircle scaled round;
135 z2+(round/2,round/2) = top_right;
136 z4-(round/2,round/2) = bottom_left;
141 fill bot z1 .. rt z1 --- rt z2 .. top z2 ---
142 top z3 .. lft z3 --- lft z4 .. bot z4 --- cycle;
148 def draw_block (expr bottom_left, top_right) =
149 draw_rounded_block (bottom_left, top_right, blot_diameter);
152 def draw_square_block (expr bottom_left, top_right) =
154 x1 = xpart bottom_left;
155 y1 = ypart bottom_left;
156 x2 = xpart top_right;
157 y2 = ypart top_right;
160 fill (x1,y1) --- (x2,y1) --- (x2,y2) --- (x1,y2) --- cycle;
164 def draw_gridline (expr bottom_left,top_right,thickness) =
165 draw_rounded_block (bottom_left-(thickness/2,thickness/2),
166 top_right+(thickness/2,thickness/2),
171 def draw_brush(expr a,w,b,v) =
174 penpos3(w,angle(z2-z1)+90);
175 penpos4(w,angle(z2-z1));
176 penpos5(v,angle(z1-z2)+90);
177 penpos6(v,angle(z1-z2));
181 fill z3r{z3r-z5l}..z4l..{z5r-z3l}z3l..z5r{z5r-z3l}..z6l..{z3r-z5l}z5l..cycle;
187 % make a superellipsoid segment going from FROM to TO, with SUPERNESS.
188 % Take superness = sqrt(2)/2 to get a circle segment
190 % see Knuth, p. 267 and p.126
191 def super_curvelet(expr from, to, superness, dir) =
193 (superness [xpart to, xpart from], superness [ypart from,ypart to]){to - from}
195 (superness [xpart from, xpart to], superness [ypart to,ypart from]){to - from}
201 % Bulb with smooth inside curve.
203 % alpha = start direction.
204 % beta = which side to turn to.
205 % flare = diameter of the bulb
206 % line = diameter of line attachment
207 % direction = is ink on left or right side (1 or -1)
209 def flare_path(expr pos,alpha,beta,line,flare, direction) =
212 penpos1(line,180+beta+alpha);
214 penpos2(flare,180+beta+alpha);
216 penpos3(flare,0+alpha);
217 z3l=z1r+(1/2+0.43)*flare*dir(alpha+beta) ;
220 z4=z2r- line * dir(alpha);
226 p:=z1r{dir(alpha)}..z3r{dir(180+alpha-beta)}..z2l{dir(alpha+180)}
227 ..z3l{dir(180+alpha+beta)}..tension t
228 ..z4{dir(180+alpha+beta)}..z1l{dir(alpha+180)};
240 def brush(expr a,w,b,v) =
248 % Draw a (rest) crook, starting at thickness STEM in point A,
249 % ending a ball W to the left, diameter BALLDIAM
250 % ypart of the center of the ball is BALLDIAM/4 lower than ypart A
252 def balled_crook(expr a, w, balldiam, stem) =
255 penpos1(balldiam/2,-90);
256 penpos2(balldiam/2,0);
257 penpos3(balldiam/2,90);
258 penpos4(balldiam/2,180);
259 x4r=xpart a-w; y3r=ypart a+balldiam/4;
263 x5=x4r+9/8balldiam; y5r=y1r;
265 x6l=xpart a; y6l=ypart a;
266 penstroke z1e..z2e..z3e..z4e..z1e..z5e{right}..z6e;
267 penlabels(1,2,3,4,5,6);
273 currentpicture := currentpicture yscaled -1;
274 set_char_box(charbp, charwd, charht, chardp);
279 currentpicture := currentpicture scaled -1;
280 set_char_box(charwd, charbp, charht, chardp);
285 % center_factor: typically .5, the larger, the larger the radius of the bulb
286 % radius factor: how much the bulb curves inward
288 def draw_bulb(expr turndir, zl, zr, bulb_rad, radius_factor)=
295 % don't get near infinity
296 %z0 = zr + bulb_rad * (zl-zr)/length(zr -zl);
297 z0 = zr + bulb_rad /length(zr -zl) * (zl-zr);
301 z1 = z0 + radius_factor* rad * dir(ang + turndir* 100);
302 z2 = z0 + rad * dir(ang + turndir*300);
304 fill zr{dir (ang + turndir* 90)} .. z1 .. z2 -- cycle;