diff --git a/Ink Canvas/AssemblyInfo.cs b/Ink Canvas/AssemblyInfo.cs
index 0f179263..6b93c545 100644
--- a/Ink Canvas/AssemblyInfo.cs
+++ b/Ink Canvas/AssemblyInfo.cs
@@ -49,5 +49,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.7.1.3")]
-[assembly: AssemblyFileVersion("1.7.1.3")]
+[assembly: AssemblyVersion("1.7.1.6")]
+[assembly: AssemblyFileVersion("1.7.1.6")]
diff --git a/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs b/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs
new file mode 100644
index 00000000..16ac88c8
--- /dev/null
+++ b/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs
@@ -0,0 +1,147 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using Point = System.Windows.Point;
+
+namespace Ink_Canvas.Helpers
+{
+ ///
+ /// 适合手写/触摸的墨迹平滑方案:指数平滑+等距重采样+Catmull-Rom样条插值,防止自交和异常填充
+ ///
+ public class AdvancedBezierSmoothing
+ {
+ public double SmoothingStrength { get; set; } = 0.8;
+ public double ResampleInterval { get; set; } = 0.8;
+ public int InterpolationSteps { get; set; } = 64;
+
+ public Stroke SmoothStroke(Stroke stroke)
+ {
+ if (stroke == null || stroke.StylusPoints.Count < 2)
+ return stroke;
+ var originalPoints = stroke.StylusPoints.ToList();
+ var smoothedPoints = ApplyExponentialSmoothing(originalPoints, SmoothingStrength);
+ var resampledPoints = ResampleEquidistant(smoothedPoints, ResampleInterval);
+ var interpolatedPoints = SlidingBezierFit(resampledPoints, 4, 24);
+ var finalPoints = ApplyExponentialSmoothing(interpolatedPoints, 0.5); // 二次平滑
+ var ultraSmoothPoints = SlidingWindowSmooth(finalPoints, 7); // 滑动窗口平滑
+ var smoothedStroke = new Stroke(new StylusPointCollection(ultraSmoothPoints))
+ {
+ DrawingAttributes = stroke.DrawingAttributes.Clone()
+ };
+ return smoothedStroke;
+ }
+
+ private List ApplyExponentialSmoothing(List points, double alpha)
+ {
+ var result = new List();
+ if (points.Count == 0) return result;
+ result.Add(points[0]);
+ double lastX = points[0].X;
+ double lastY = points[0].Y;
+ float lastPressure = points[0].PressureFactor;
+ for (int i = 1; i < points.Count; i++)
+ {
+ var p = points[i];
+ lastX = alpha * p.X + (1 - alpha) * lastX;
+ lastY = alpha * p.Y + (1 - alpha) * lastY;
+ lastPressure = (float)(alpha * p.PressureFactor + (1 - alpha) * lastPressure);
+ if (lastPressure < 0.1f) lastPressure = 0.1f;
+ result.Add(new StylusPoint(lastX, lastY, lastPressure));
+ }
+ return result;
+ }
+
+ private List ResampleEquidistant(List points, double interval = 2.0)
+ {
+ var result = new List();
+ if (points.Count == 0) return result;
+ result.Add(points[0]);
+ double accumulated = 0;
+ for (int i = 1; i < points.Count; i++)
+ {
+ var prev = result.Last();
+ var curr = points[i];
+ double dx = curr.X - prev.X;
+ double dy = curr.Y - prev.Y;
+ double dist = Math.Sqrt(dx * dx + dy * dy);
+ if (dist + accumulated >= interval)
+ {
+ double t = (interval - accumulated) / dist;
+ double x = prev.X + t * dx;
+ double y = prev.Y + t * dy;
+ float pressure = (float)(prev.PressureFactor * (1 - t) + curr.PressureFactor * t);
+ if (pressure < 0.1f) pressure = 0.1f;
+ var newPoint = new StylusPoint(x, y, pressure);
+ result.Add(newPoint);
+ accumulated = 0;
+ i--; // 重新处理当前点
+ }
+ else
+ {
+ accumulated += dist;
+ }
+ }
+ return result;
+ }
+
+ private List SlidingBezierFit(List points, int window = 4, int steps = 24)
+ {
+ var result = new List();
+ if (points.Count < window) return points;
+ for (int i = 0; i <= points.Count - window; i++)
+ {
+ var p0 = points[i];
+ var p1 = points[i + 1];
+ var p2 = points[i + 2];
+ var p3 = points[i + 3];
+ for (int j = 0; j < steps; j++)
+ {
+ double t = (double)j / steps;
+ var pt = CubicBezier(p0, p1, p2, p3, t);
+ result.Add(pt);
+ }
+ }
+ // 保证最后一个点被包含
+ result.Add(points.Last());
+ return result;
+ }
+
+ private StylusPoint CubicBezier(StylusPoint p0, StylusPoint p1, StylusPoint p2, StylusPoint p3, double t)
+ {
+ double u = 1 - t;
+ double tt = t * t;
+ double uu = u * u;
+ double uuu = uu * u;
+ double ttt = tt * t;
+ double x = uuu * p0.X + 3 * uu * t * p1.X + 3 * u * tt * p2.X + ttt * p3.X;
+ double y = uuu * p0.Y + 3 * uu * t * p1.Y + 3 * u * tt * p2.Y + ttt * p3.Y;
+ float pressure = (float)(p1.PressureFactor * (1 - t) + p2.PressureFactor * t);
+ if (pressure < 0.1f) pressure = 0.1f;
+ return new StylusPoint(x, y, pressure);
+ }
+
+ private List SlidingWindowSmooth(List points, int window = 5)
+ {
+ var result = new List();
+ int half = window / 2;
+ for (int i = 0; i < points.Count; i++)
+ {
+ double sumX = 0, sumY = 0, sumP = 0;
+ int count = 0;
+ for (int j = Math.Max(0, i - half); j <= Math.Min(points.Count - 1, i + half); j++)
+ {
+ sumX += points[j].X;
+ sumY += points[j].Y;
+ sumP += points[j].PressureFactor;
+ count++;
+ }
+ result.Add(new StylusPoint(sumX / count, sumY / count, (float)(sumP / count)));
+ }
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index 1b5bb979..d4040534 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -210,8 +210,18 @@
+