この質問を読んで、以前の投稿を思い出しました。そのため、最終的に単純な削減スキームを実装することにしました。
List<PointF> ReducePath(List<PointF> points, float epsilon)
{
if (points.Count < 3) return points;
var newPoints = new List<PointF>();
newPoints.Add(points[0]);
float delta = 0f;
float prevAngle = (float)(Angle(points[0], points[1]) /10f);
for (int i = 1; i < points.Count - 1; i++)
{
float ang = Angle(points[i-1], points[i])/10f;
delta += ang - prevAngle;
prevAngle = ang;
if (Math.Abs(delta) > epsilon)
{
delta = 0;
newPoints.Add(points[i]);
}
}
newPoints.Add(points[ points.Count -1]);
return newPoints;
}
float Angle(PointF p1, PointF p2)
{
if (p1.Y == p2.Y) return p1.X > p2.Y ? 0 : 180;
else if (p1.X == p2.X) return p1.Y > p2.Y ? 90 : 270;
else return (float)Math.Atan((p1.Y - p2.Y)/(p1.X - p2.X));
}
//float Slope(PointF p1, PointF p2)
//{
// if (p1.Y == p2.Y) return 0;
// else if (p1.X == p2.X) return 12345;
// else return (p1.Y - p2.Y)/(p1.X - p2.X);
//}
イプシロン値が 1、0.1、および 0.01 の場合の結果を次に示します。

GraphicsPath.PathPoints
は読み取り専用なので、新しいポイント リストからパスを再作成する必要があることに注意してください。
更新:勾配の代わりに 1°/10 で機能するように数学を更新し、Slope
関数を関数に置き換えましたAngle
..これにより、さまざまな方向でより均一な結果が得られるはずです..
更新 2:
エフライムに称賛を。適切な開始角度を使用するために提案された編集を追加しました..