[metapost] Labeling an angle
John Kitzmiller
jkitz at verizon.net
Wed Dec 27 20:06:25 CET 2006
mailanholgerpeters at web.de wrote:
> Hi,
>
> thanks for your help, but I'd rather have a sector of a circle drawn around it, as in:
> http://de.wikipedia.org/wiki/Bild:Vertical_angles.png
>
> Is there an easier way than to do hard-coded positioning of the circle and the label?
>
> Holger
>
Holger, (I am new to mp and forums. Apologies if I break decorum and
please advise.)
Use macros, either within the mp document, or stored as a file to be
used with input.
Hobby's mpman (around page 45) and Heck's tutorial (pp 38 and 52 at
least) present macros for marking congruency. Links to both can be
found at <<http://www.tug.org/metapost.html>>
Similar code snippets can be found among the many offerings of the mp
giants listed on that page.
Below are copies+hacks which I put in a path for mp to access, in my
case C:\texmf\metapost\base which can then be called with
input <filename>
at the beginning of the mp document(s). (None of this is clean, but it
works for me.)
The first commented section, from Heck, uses multiple arcs to show angle
congruency. I prefer tick-marks across one arc. One weakness in the code
is that when all four vertical angles are marked one ends up with a
circle where arcs of a slightly different radius might be preferable. I
am sure this could be cobbled from the codes below. So far I have
avoided that requirement.
%angle_radius := 4mm;
%angle_delta := 0.5mm;
%mark_size := 2mm;
% % --- draw 1, 2, 3 or 4 arcs ---
% def mark_angle(expr A, common, B, n) =
% draw_angle(A, common, B, angle_radius);
% if n>1: draw_angle(A, common, B,
% angle_radius+angle_delta); fi;
% if n>2: draw_angle(A, common, B,
% angle_radius-angle_delta); fi;
% if n>3: draw_angle(A, common, B,
% angle_radius+2*angle_delta); fi;
% enddef;
%
% def draw_angle(expr endofa, common, endofb, r) =
% begingroup
% save tn;
% tn := turningnumber(common--endofa--endofb--cycle);
% draw (unitvector(endofa-common){(endofa-common)
% rotated(tn*90)} .. unitvector(endofb-common))
% scaled r shifted common;
% endgroup
% enddef;
% -- arcs with ticks for angles --
marksize=4pt;
angle_radius:=8pt;
def draw_mark(expr p, a) =
begingroup
save t, dm; pair dm;
t = arctime a of p;
dm = marksize*unitvector direction t of p
rotated 90;
draw (-.5dm.. .5dm) shifted point t of p;
endgroup
enddef;
def draw_marked(expr p, n) =
begingroup
save amid;
amid = .5*arclength p;
for i=-(n-1)/2 upto (n-1)/2:
draw_mark(p, amid+.6marksize*i);
endfor
draw p;
endgroup
enddef;
def mark_angle(expr a, b, c, n) =
begingroup
save s, p; path p;
p = unitvector(a-b){(a-b)rotated 90}..unitvector(c-b);
s = .9marksize/length(point 1 of p - point 0 of p);
if s<angle_radius: s:=angle_radius; fi
draw_marked(p scaled s shifted b, n);
endgroup
enddef;
% --- right angle mark ---
def mark_rt_angle(expr endofa, common, endofb) =
begingroup
save tn; tn :=
turningnumber(common--endofa--endofb--cycle);
draw ((1,0)--(1,1)--(0,1)) zscaled(mark_size*
unitvector((1+tn)*endofa+(1-tn)*endofb-2*common))
shifted common;
endgroup
enddef;
% --- tick marks ---
def tick(expr p, n) =
begingroup
save midpnt;
midpnt = 0.5*arclength(p); % find the time when
half-way the path
for i=-(n-1)/2 upto (n-1)/2:
draw_mark(p, midpnt+mark_size*i/2); % place n tick marks
endfor;
endgroup
enddef;
def draw_mark(expr p, m) =
begingroup
save t, dm; pair dm;
t = arctime m of p; % find a
vector orthogonal to p at time t
dm = mark_size*unitvector(direction t of p rotated 90);
draw(-1/2dm..1/2dm) shifted (point t of p); % draw tick mark
endgroup
enddef;
% --- parallel marks ---
def para(expr p, n) =
begingroup
save midpnt;
midpnt = 0.5*arclength(p); % find the time when
half-way the path
for i=-(n-1)/2 upto (n-1)/2:
draw_para(p, midpnt+mark_size*i/2); % place n para marks
endfor;
endgroup
enddef;
def draw_para(expr p, m) =
begingroup
save t, dm, mm; pair dm, mm;
t = arctime m of p; % find
a vector orthogonal to p at time t
dm = mark_size*unitvector(direction t of p rotated 90);
mm = unitvector(direction t of p);
draw(-.5dm--2.2*mm--.5dm) shifted (point t of p); % draw
para mark
endgroup
enddef;
For example:
input <macro>;
u:=50;
beginfig(1);
z0 = (0,0);
z1 = z0 - u*dir(20);
z2 = z0 + u*dir(20);
z3 = z0 - u*dir(152);
z4 = z0 + u*dir(152);
drawdblarrow z1--z2;
drawdblarrow z3--z4;
mark_angle(z3,z0,z2,0);
mark_angle(z4,z0,z1,0);
label.bot(btex $\theta$ etex,z0);
label.rt(btex $48^\circ$ etex,z0) shifted (9,0);
label.lft(btex $\alpha$ etex,z0) shifted (-7,0);
endfig;
Regards, with many thanks to the mp community,
John
More information about the metapost
mailing list