[metapost] workaround for turningnumber bug
Werner LEMBERG
wl at gnu.org
Fri Jan 28 09:32:02 CET 2005
I've written a small function which computes the orientation of a
path, see below -- it is intended for use with mf2pt1. It works
without problems (at least for the font outlines which I'm working on)
and gives reliable results in contrast to the buggy `turningnumber'
function.
Since I'm a poor metapost programmer I wonder whether it can be
made more elegant.
For your enjoyment I've also attached a (non-intersecting) curve where
metapost's `turningnumber' reports -3 instead of the correct 1.
Werner
======================================================================
%% \begin{explaincode}
%% Determine the direction of a closed curve. \mfcomment
% Returns |true| if the curve is clockwise, |false| if counterclockwise.
%% Since the `turningnumber' command in MetaPost is buggy, we compute
%% the path orientation by ourselves.
%% \end{explaincode}
vardef Angle primary d =
if d <> (0, 0):
angle d
else:
0
fi
enddef;
vardef is_clockwise primary p =
save res, alpha, beta, gamma;
res := 0;
for t = 0 upto length p - 1:
alpha := Angle (postcontrol t of p - point t of p)
- Angle (point t of p - precontrol t of p);
if alpha > 180:
alpha := alpha - 360;
fi;
if alpha <= -180:
alpha := alpha + 360;
fi;
beta := Angle (precontrol t + 1 of p - postcontrol t of p)
- Angle (postcontrol t of p - point t of p);
if beta > 180:
beta := beta - 360;
fi;
if beta <= -180:
beta := beta + 360;
fi;
gamma := Angle (point t + 1 of p - precontrol t + 1 of p)
- Angle (precontrol t + 1 of p - postcontrol t of p);
if gamma > 180:
gamma := gamma - 360;
fi;
if gamma <= -180:
gamma := gamma + 360;
fi;
res := res + alpha + beta + gamma;
endfor;
res <= 0
enddef;
-------------- next part --------------
beginfig (0);
save bulb, p, radius, thin, inner_r, penh, pedalh, h, w;
path pat;
penh = 10;
pedalh = 100;
thin = 5;
w = 7/9 pedalh;
h = pedalh;
z0 = (1/2 w, h - 1/2 w);
bulb + 2 radius = w;
0.9 thin + bulb = (radius * 3.1415 * 2) / 8;
pickup pencircle scaled penh;
penpos1 (bulb, 180);
penpos2 (bulb, 0);
penpos3 (thin, 0);
z1 = z0 + (0, radius);
z2 = z1;
inner_r = .45 radius;
z4l = z0 + inner_r * dir (90 + 360/16);
z4r = z0 + inner_r * dir (90 - 360/16);
z4 = .5 [z4l, z4r];
z3 = .75 [z1, z4];
% labels (0);
% penlabels (1, 2, 3, 4);
pat := z3r{up}
.. z1l{up}
.. z2l{down}
.. z3l{down}
.. z4l{dir (180 + 360/16)};
for i = 1 upto 7:
pat := pat
.. ((z3r{up}
.. z1l{up}
.. z2l{down}
.. z3l{down}
.. z4l{dir (180 + 360/16)})
rotatedaround (z0, 360/8 i));
endfor;
pat := pat
.. cycle;
show turningnumber pat;
fill pat;
endfig;
end;
More information about the metapost
mailing list