Here I present a very simple angle-based polygon reduction algorithm as described in the chapter "A Simple Algorithm" of David Eberly's "Polyline Reduction". ItThe only addition is that I treat the list as cyclic since we work with closed polygon, not with an open polyline. The algorithm is vastly inefficient and has no quality control (other than visual), but demonstrates the idea.
The implementation (as weighting function for vertex I use π
minus vector angle at the vertex):
###Update: using another weighting function###
A bit of experimentation showed that much better results can be obtained with more sophisticated weighting function:
nextPoint[list_] :=
Ordering[((Pi - Re@VectorAngle[#2 - #1, #2 - #3])*
(Norm[#2 - #1] Norm[#2 - #3])/(Norm[#2 - #1] + Norm[#2 - #3])) & @@@
Partition[ArrayPad[list, {{1, 1}}, "Periodic"], 3, 1], 1];
Selecting more initial sampling points allows to get better approximation:
list = sample[30];
seq = NestList[deleteOnePoint, {nextPoint[list], list}, Length[list] - 6];
Here is Manipulate
where at the top at left shown current approximation and on the right shown initial sample:
Manipulate[Graphics[{Text[
Row[{Dynamic[Length[list] - n], " points"}, BaseStyle -> FontSize -> 22],
Scaled[{.15, .92}]], EdgeForm[{Black, Thickness[.015]}], FaceForm[None], Red,
PointSize[.04], Point[seq[[n + 1, 2]][[seq[[n + 1, 1]]]]], Polygon[seq[[n + 1, 2]]],
Yellow, PointSize[.015], Point[seq[[n + 1, 2]]], EdgeForm[{Thickness[.01]}],
Translate[Scale[Polygon[seq[[n + 1, 2]]], 1/20, c], {-.5, 9}],
Translate[Scale[Polygon[list], 1/20, c], {.5, 9}], EdgeForm[], FaceForm[Blue],
Translate[Scale[Polygon[seq[[n + 1, 2]]], 1/20, c], {-.5, 10}],
Translate[Scale[Polygon[list], 1/20, c], {.5, 10}]},
PlotRange -> {{0, 14}, {3, 22}}], {{n, Length[list] - 50}, Length[list] - 70,
Length[seq] - 1, 1, AnimationRate -> 5, AnimationRepetitions -> None,
RefreshRate -> 60}]
As one can see, an approximation containing only 50 points is indistinguishable from the original at the usual letter sizes. For comparison, the original Bézier curves extracted from the glyph contain 101 control points...