[metapost] workaround for turningnumber bug
Werner LEMBERG
wl at gnu.org
Sun Jan 30 10:24:00 CET 2005
> When I try your algorithm on this path:
> path p;
> p := (0,0) ..controls (48,-18) and (24,-18).. (72,0)
> ..controls (90,48) and (90,24).. (72,72)
> ..controls (24,90) and (48,90).. (0,72)
> ..controls (-18,24) and (-18,48).. cycle;
>
> it returns true (with res = -1080). But the path is clearly
> counterclockwise.
Thanks for the counterexample. Is such a curve possible (this is,
with a `reversed' order of the control points) in mpost if I don't
specify the control points explictly?
What are the constraints for a curve (P, P+, Q-, Q) so that there is a
self-intersection? My algorithm can be improved by using only the
directions of `P -> P+' and `Q- -> Q' and assuring that no
self-intersection does happen. Actually, I can drop the
self-intersection constraint, simply insisting that the curve doesn't
self-intersect (which must not happen in font outlines).
Are there any errors in my assumptions?
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 (point t + 1 of p - precontrol t + 1 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;
res := res + alpha + beta;
endfor;
res <= 0
enddef;
More information about the metapost
mailing list