From d7df39290f18cc3da84a0384332b2caf56d45f53 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 30 Aug 2025 22:59:12 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E6=8F=92=E5=85=A5=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=8F=8A=E5=A2=A8=E8=BF=B9=E5=B9=B3=E6=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/AdvancedBezierSmoothing.cs | 66 +++++++++++++++---- .../MainWindow_cs/MW_ElementsControls.cs | 25 +++++-- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs b/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs index a9015cd6..ab7aa9fd 100644 --- a/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs +++ b/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs @@ -97,13 +97,20 @@ namespace Ink_Canvas.Helpers cancellationToken.ThrowIfCancellationRequested(); - // 确保点数合理 - if (smoothedPoints.Length > originalPoints.Length * 3) + // 严格控制点数,避免产生过多点 + if (smoothedPoints.Length > originalPoints.Length * 2) { // 如果点数增加太多,进行重采样 smoothedPoints = ResampleEquidistantOptimized(smoothedPoints, ResampleInterval); } + // 最终检查:确保点数不会过多 + if (smoothedPoints.Length > originalPoints.Length * 1.5) + { + // 如果仍然太多点,使用原始笔画 + return stroke; + } + // 创建平滑后的笔画 var smoothedStroke = new Stroke(new StylusPointCollection(smoothedPoints)) { @@ -125,23 +132,23 @@ namespace Ink_Canvas.Helpers // 添加第一个点 result.Add(points[0]); - // 使用滑动窗口进行贝塞尔曲线拟合 - for (int i = 0; i <= points.Length - 4; i++) + // 使用非重叠的窗口进行贝塞尔曲线拟合 + for (int i = 0; i < points.Length - 3; i += 3) // 每次移动3个点,避免重叠 { var p0 = points[i]; - var p1 = points[i + 1]; - var p2 = points[i + 2]; - var p3 = points[i + 3]; + var p1 = points[Math.Min(i + 1, points.Length - 1)]; + var p2 = points[Math.Min(i + 2, points.Length - 1)]; + var p3 = points[Math.Min(i + 3, points.Length - 1)]; // 计算改进的控制点 var controlPoints = CalculateImprovedControlPoints(p0, p1, p2, p3); - // 自适应插值步数 - int steps = UseAdaptiveInterpolation ? - CalculateAdaptiveSteps(p0, p1, p2, p3) : InterpolationSteps; + // 限制插值步数,避免点数爆炸 + int steps = Math.Min(UseAdaptiveInterpolation ? + CalculateAdaptiveSteps(p0, p1, p2, p3) : InterpolationSteps, 16); - // 生成贝塞尔曲线点 - for (int j = 1; j <= steps; j++) // 从1开始避免重复第一个点 + // 生成贝塞尔曲线点,但跳过第一个点避免重复 + for (int j = 1; j <= steps; j++) { double t = (double)j / steps; var bezierPoint = CubicBezierWithControlPoints(controlPoints, t, p0, p3); @@ -152,7 +159,8 @@ namespace Ink_Canvas.Helpers // 添加最后一个点 result.Add(points[points.Length - 1]); - return result.ToArray(); + // 去重和优化点数 + return RemoveDuplicatePoints(result.ToArray()); } /// @@ -233,6 +241,38 @@ namespace Ink_Canvas.Helpers return (angle1 + angle2) / Math.PI; // 归一化到0-1 } + /// + /// 去除重复和过近的点 + /// + private StylusPoint[] RemoveDuplicatePoints(StylusPoint[] points) + { + if (points.Length < 2) return points; + + var result = new List(); + result.Add(points[0]); + + double minDistance = ResampleInterval * 0.5; // 最小距离阈值 + + for (int i = 1; i < points.Length; i++) + { + var lastPoint = result[result.Count - 1]; + var currentPoint = points[i]; + + // 计算距离 + double distance = Math.Sqrt( + (currentPoint.X - lastPoint.X) * (currentPoint.X - lastPoint.X) + + (currentPoint.Y - lastPoint.Y) * (currentPoint.Y - lastPoint.Y)); + + // 如果距离足够大,添加这个点 + if (distance >= minDistance) + { + result.Add(currentPoint); + } + } + + return result.ToArray(); + } + /// /// 使用控制点的三次贝塞尔曲线计算 /// diff --git a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs index 4c2e89c0..ca5a5f8b 100644 --- a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs @@ -40,11 +40,6 @@ namespace Ink_Canvas string timestamp = "img_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff"); image.Name = timestamp; - // 初始化TransformGroup - InitializeElementTransform(image); - - CenterAndScaleElement(image); - // 设置图片属性,避免被InkCanvas选择系统处理 image.IsHitTestVisible = true; image.Focusable = false; @@ -52,8 +47,15 @@ namespace Ink_Canvas // 初始化InkCanvas选择设置 InitializeInkCanvasSelectionSettings(); + // 先添加到画布 inkCanvas.Children.Add(image); + // 初始化TransformGroup + InitializeElementTransform(image); + + // 居中缩放 + CenterAndScaleElement(image); + // 绑定事件处理器 BindElementEvents(image); @@ -99,6 +101,8 @@ namespace Ink_Canvas { if (sender is FrameworkElement element) { + LogHelper.WriteLogToFile($"图片鼠标按下: {element.Name}"); + // 取消之前选中的元素 if (currentSelectedElement != null && currentSelectedElement != element) { @@ -151,6 +155,8 @@ namespace Ink_Canvas { if (sender is FrameworkElement element) { + LogHelper.WriteLogToFile($"图片滚轮事件: {element.Name}, Delta={e.Delta}"); + // 使用滚轮缩放的核心机制 ApplyWheelScaleTransform(element, e); @@ -890,8 +896,13 @@ namespace Ink_Canvas InkCanvas.SetLeft(element, centerX); InkCanvas.SetTop(element, centerY); - // 清除任何现有的RenderTransform - element.RenderTransform = Transform.Identity; + // 保持TransformGroup,不清除RenderTransform + // 这样可以保持滚轮缩放和拖动功能 + if (element.RenderTransform == null || element.RenderTransform == Transform.Identity) + { + // 只有在没有TransformGroup时才创建 + InitializeElementTransform(element); + } LogHelper.WriteLogToFile($"元素居中完成: 位置({centerX}, {centerY}), 尺寸({newWidth}x{newHeight})"); }