diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs index c7325e5e..d6542764 100644 --- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs +++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs @@ -18,21 +18,19 @@ namespace Ink_Canvas { private StrokeCollection newStrokes = new StrokeCollection(); private List circles = new List(); - private const double LINE_STRAIGHTEN_THRESHOLD = 0.20; // 默认灵敏度阈值,与UI默认值对应 + private const double LINE_STRAIGHTEN_THRESHOLD = 0.20; - // 矩形参考线系统 private List rectangleGuideLines = new List(); - private const double RECTANGLE_ENDPOINT_THRESHOLD = 30.0; // 端点相交判断阈值 - private const double RECTANGLE_ANGLE_THRESHOLD = 15.0; // 角度判断阈值(度) + private const double RECTANGLE_ENDPOINT_THRESHOLD = 30.0; + private const double RECTANGLE_ANGLE_THRESHOLD = 15.0; - // 矩形参考线数据结构 private class RectangleGuideLine { public Stroke OriginalStroke { get; set; } public Point StartPoint { get; set; } public Point EndPoint { get; set; } public DateTime CreatedTime { get; set; } - public double Angle { get; set; } // 直线角度(弧度) + public double Angle { get; set; } public bool IsHorizontal { get; set; } public bool IsVertical { get; set; } @@ -64,7 +62,6 @@ namespace Ink_Canvas var startPoint = e.Stroke.StylusPoints.Count > 0 ? e.Stroke.StylusPoints[0].ToPoint() : new Point(); var endPoint = e.Stroke.StylusPoints.Count > 0 ? e.Stroke.StylusPoints[e.Stroke.StylusPoints.Count - 1].ToPoint() : new Point(); - // 确保InkCanvas保持Ink编辑模式,防止自动切换到鼠标模式 if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink) { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; @@ -80,19 +77,15 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("StrokeCollected: 墨迹渐隐管理器为空,无法添加墨迹", LogHelper.LogType.Error); } - // 延迟移除墨迹,避免立即移除导致模式切换 - // 使用Dispatcher.BeginInvoke确保在UI线程上异步执行 Dispatcher.BeginInvoke(new Action(() => { try { - // 再次确保InkCanvas保持Ink编辑模式 if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink) { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; } - // 从InkCanvas中移除墨迹,因为我们要用渐隐管理器来管理它 if (inkCanvas.Strokes.Contains(e.Stroke)) { inkCanvas.Strokes.Remove(e.Stroke); @@ -104,21 +97,18 @@ namespace Ink_Canvas } }), DispatcherPriority.Background); - // 墨迹渐隐模式下不参与墨迹纠正和其他处理,直接返回 return; } // 标记是否进行了直线拉直 bool wasStraightened = false; - // 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑 if (Settings.Canvas.FitToCurve) drawingAttributes.FitToCurve = false; try { inkCanvas.Opacity = 1; - // 应用屏蔽压感功能 - 如果启用,所有笔画都使用统一粗细 if (Settings.Canvas.DisablePressure) { var uniformPoints = new StylusPointCollection(); @@ -129,13 +119,11 @@ namespace Ink_Canvas } e.Stroke.StylusPoints = uniformPoints; } - // 应用压感触屏模式 - 如果启用并且检测到触屏输入 else if (Settings.Canvas.EnablePressureTouchMode) { bool isTouchInput = true; foreach (StylusPoint point in e.Stroke.StylusPoints) { - // 检测是否为压感笔输入(压感笔的PressureFactor不等于0.5或0) if ((point.PressureFactor > 0.501 || point.PressureFactor < 0.5) && point.PressureFactor != 0) { isTouchInput = false; @@ -143,7 +131,6 @@ namespace Ink_Canvas } } - // 如果是触屏输入,则应用模拟压感 if (isTouchInput) { switch (Settings.Canvas.InkStyle) @@ -1551,11 +1538,66 @@ namespace Ink_Canvas return distance; } + /// + /// 判断一个 stroke 是否是直线(排除虚线和点线) + /// + /// 要检查的 stroke + /// 如果是直线返回 true,否则返回 false + private bool IsStraightLine(Stroke stroke) + { + if (stroke == null || stroke.StylusPoints.Count == 0) + return false; + + int pointCount = stroke.StylusPoints.Count; + + if (pointCount == 1) + return false; + + // 最简单的直线:只有2个点 + if (pointCount == 2) + { + Point p1 = stroke.StylusPoints[0].ToPoint(); + Point p2 = stroke.StylusPoints[1].ToPoint(); + double lineLength = GetDistance(p1, p2); + + if (lineLength < 10) + return false; + + return true; + } + + if (pointCount > 3) + return false; + + // 对于3个点的情况,检查它们是否基本在一条直线上 + if (pointCount == 3) + { + Point p1 = stroke.StylusPoints[0].ToPoint(); + Point p2 = stroke.StylusPoints[1].ToPoint(); + Point p3 = stroke.StylusPoints[2].ToPoint(); + + double totalLength = GetDistance(p1, p3); + if (totalLength < 10) + return false; + + // 计算点到直线的距离 + // 使用 p1 和 p3 作为直线端点,检查 p2 是否在这条直线上 + double distance = DistanceFromLineToPoint(p1, p3, p2); + + // 如果点到直线的距离相对于线段长度很小,认为是直线 + // 使用相对误差阈值(比如 1%) + if (totalLength > 0 && distance / totalLength < 0.01) + return true; + + return false; + } + + return false; + } + // New method: Attempts to snap endpoints to existing stroke endpoints private Point[] GetSnappedEndpoints(Point start, Point end) { - // 如果端点吸附功能关闭,直接返回null - // 这里不再返回原始点,因为调用此方法的地方会判断返回值是否为null if (!Settings.Canvas.LineEndpointSnapping) return null; @@ -1572,6 +1614,10 @@ namespace Ink_Canvas { if (stroke.StylusPoints.Count == 0) continue; + // 只对直线进行端点吸附,跳过虚线和点线 + if (!IsStraightLine(stroke)) + continue; + // Get stroke endpoints Point strokeStart = stroke.StylusPoints.First().ToPoint(); Point strokeEnd = stroke.StylusPoints.Last().ToPoint();