From 6dafde97352e465121b4db3b813f306beca5d425 Mon Sep 17 00:00:00 2001
From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com>
Date: Wed, 18 Jun 2025 15:10:33 +0800
Subject: [PATCH] =?UTF-8?q?improve:=E7=9B=B4=E7=BA=BF=E6=8B=89=E7=9B=B4?=
=?UTF-8?q?=E7=81=B5=E6=95=8F=E5=BA=A6=E8=AE=BE=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Ink Canvas/MainWindow.xaml | 12 +-
Ink Canvas/MainWindow.xaml.cs | 7 +
Ink Canvas/MainWindow_cs/MW_Settings.cs | 7 +
Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 3 +
Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs | 24 +-
.../MW_SimulatePressure&InkToShape.cs | 91 +-
Ink Canvas/Resources/Settings.cs | 2 +
.../net472/InkCanvasForClass.g.resources | Bin 5177953 -> 5178682 bytes
Ink Canvas/obj/Debug/net472/MainWindow.g.cs | 3355 +++++++++--------
Ink Canvas/obj/Debug/net472/MainWindow.g.i.cs | 3355 +++++++++--------
10 files changed, 3510 insertions(+), 3346 deletions(-)
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index 6c479042..0aa2c659 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -940,7 +940,17 @@
-
+
+
+
+
+
+
diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs
index ec542037..88d3ee33 100644
--- a/Ink Canvas/MainWindow.xaml.cs
+++ b/Ink Canvas/MainWindow.xaml.cs
@@ -391,6 +391,13 @@ namespace Ink_Canvas {
{
// 使用辅助方法设置光标
SetCursorBasedOnEditingMode(inkCanvas);
+
+ // 确保光标可见
+ if (Settings.Canvas.IsShowCursor) {
+ inkCanvas.ForceCursor = true;
+ inkCanvas.UseCustomCursor = true;
+ System.Windows.Forms.Cursor.Show();
+ }
}
#endregion Definations and Loading
diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs
index f079a173..f510d29f 100644
--- a/Ink Canvas/MainWindow_cs/MW_Settings.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs
@@ -749,6 +749,13 @@ namespace Ink_Canvas {
Settings.Canvas.LineEndpointSnappingThreshold = (int)e.NewValue;
SaveSettingsToFile();
}
+
+ private void LineStraightenSensitivitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) {
+ if (!isLoaded) return;
+
+ Settings.InkToShape.LineStraightenSensitivity = e.NewValue;
+ SaveSettingsToFile();
+ }
#endregion
diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
index 09c723f9..c974d1a3 100644
--- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
@@ -578,6 +578,9 @@ namespace Ink_Canvas {
ToggleCheckboxEnableInkToShapeRectangle.IsChecked = Settings.InkToShape.IsInkToShapeRectangle;
ToggleCheckboxEnableInkToShapeRounded.IsChecked = Settings.InkToShape.IsInkToShapeRounded;
+
+ // 初始化直线拉直灵敏度
+ LineStraightenSensitivitySlider.Value = Settings.InkToShape.LineStraightenSensitivity;
} else {
Settings.InkToShape = new InkToShape();
}
diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs
index 4bce1cc6..597fae62 100644
--- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs
+++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs
@@ -452,6 +452,7 @@ namespace Ink_Canvas {
// 触摸移动时保持自定义光标显示
if (Settings.Canvas.IsShowCursor) {
inkCanvas.ForceCursor = true;
+ inkCanvas.UseCustomCursor = true; // 确保使用自定义光标
System.Windows.Forms.Cursor.Show();
}
@@ -484,6 +485,12 @@ namespace Ink_Canvas {
inkCanvas.EraserShape = new EllipseStylusShape(boundsWidth * k * eraserMultiplier,
boundsWidth * k * eraserMultiplier);
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
+
+ // 立即应用光标设置
+ if (Settings.Canvas.IsShowCursor) {
+ inkCanvas.Cursor = Cursors.Cross;
+ System.Windows.Forms.Cursor.Show();
+ }
}
else {
if (StackPanelPPTControls.Visibility == Visibility.Visible && inkCanvas.Strokes.Count == 0 &&
@@ -1669,9 +1676,24 @@ namespace Ink_Canvas {
private void MainWindow_OnMouseMove(object sender, MouseEventArgs e) {
if (e.StylusDevice == null) {
+ // 鼠标移动时保持光标可见
System.Windows.Forms.Cursor.Show();
+
+ // 如果用户设置了显示光标,则确保光标显示正确
+ if (Settings.Canvas.IsShowCursor && inkCanvas != null) {
+ inkCanvas.ForceCursor = true;
+ inkCanvas.UseCustomCursor = true;
+ }
} else {
- System.Windows.Forms.Cursor.Hide();
+ // 只有当用户未设置显示光标时才隐藏
+ if (!Settings.Canvas.IsShowCursor) {
+ System.Windows.Forms.Cursor.Hide();
+ } else if (inkCanvas != null) {
+ // 如果用户设置了显示光标,则确保光标显示正确
+ inkCanvas.ForceCursor = true;
+ inkCanvas.UseCustomCursor = true;
+ System.Windows.Forms.Cursor.Show();
+ }
}
}
}
diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
index 2deb2968..78a4f5b6 100644
--- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
@@ -14,7 +14,7 @@ namespace Ink_Canvas {
private StrokeCollection newStrokes = new StrokeCollection();
private List circles = new List();
private const double SNAP_THRESHOLD = 15.0; // Distance threshold for endpoint snapping
- private const double LINE_STRAIGHTEN_THRESHOLD = 0.15; // Threshold for line straightening
+ private const double LINE_STRAIGHTEN_THRESHOLD = 0.10; // 降低阈值,让直线检测更严格
private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) {
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = false;
@@ -566,7 +566,7 @@ namespace Ink_Canvas {
// New method: Checks if a stroke is potentially a straight line
private bool IsPotentialStraightLine(Stroke stroke) {
- // Minimum length for line detection
+ // 确保有足够的点来进行线条分析
if (stroke.StylusPoints.Count < 5)
return false;
@@ -574,8 +574,40 @@ namespace Ink_Canvas {
Point end = stroke.StylusPoints.Last().ToPoint();
double lineLength = GetDistance(start, end);
- // Line should be longer than 30 pixels
- return lineLength > 30;
+ // 线条必须足够长才考虑拉直,至少30像素
+ if (lineLength < 30)
+ return false;
+
+ // 获取用户设置的灵敏度值
+ double sensitivity = Settings.InkToShape.LineStraightenSensitivity;
+ // 快速检查使用略宽松的阈值
+ double quickThreshold = Math.Min(sensitivity * 1.5, 0.20);
+
+ // 快速检查:计算几个关键点与直线的距离
+ if (stroke.StylusPoints.Count >= 10) {
+ // 取中点和1/4、3/4位置的点,快速检查偏差
+ int quarterIdx = stroke.StylusPoints.Count / 4;
+ int midIdx = stroke.StylusPoints.Count / 2;
+ int threeQuarterIdx = quarterIdx * 3;
+
+ Point quarterPoint = stroke.StylusPoints[quarterIdx].ToPoint();
+ Point midPoint = stroke.StylusPoints[midIdx].ToPoint();
+ Point threeQuarterPoint = stroke.StylusPoints[threeQuarterIdx].ToPoint();
+
+ double quarterDeviation = DistanceFromLineToPoint(start, end, quarterPoint);
+ double midDeviation = DistanceFromLineToPoint(start, end, midPoint);
+ double threeQuarterDeviation = DistanceFromLineToPoint(start, end, threeQuarterPoint);
+
+ // 如果任一点偏离太大,直接排除
+ double quickRelativeThreshold = lineLength * quickThreshold;
+ if (quarterDeviation > quickRelativeThreshold ||
+ midDeviation > quickRelativeThreshold ||
+ threeQuarterDeviation > quickRelativeThreshold) {
+ return false;
+ }
+ }
+
+ return true;
}
// New method: Determines if a stroke should be straightened into a line
@@ -588,15 +620,62 @@ namespace Ink_Canvas {
double maxDeviation = 0;
double lineLength = GetDistance(start, end);
+ // 如果线条太短,不进行拉直处理
+ if (lineLength < 50) {
+ return false;
+ }
+
+ // 获取用户设置的灵敏度值
+ double sensitivity = Settings.InkToShape.LineStraightenSensitivity;
+
+ // 计算点与直线的偏差
+ double totalDeviation = 0;
+ int pointCount = 0;
+
// Calculate deviation for each point
foreach (StylusPoint sp in stroke.StylusPoints) {
Point p = sp.ToPoint();
double deviation = DistanceFromLineToPoint(start, end, p);
maxDeviation = Math.Max(maxDeviation, deviation);
+ totalDeviation += deviation;
+ pointCount++;
}
- // If maximum deviation is less than threshold relative to line length
- return (maxDeviation / lineLength) < LINE_STRAIGHTEN_THRESHOLD;
+ // 计算平均偏差
+ double avgDeviation = totalDeviation / pointCount;
+
+ // 检查点分布的一致性 - 如果有些点偏离很大而其他点很接近直线,表明线条有明显弯曲
+ double deviationVariance = 0;
+ foreach (StylusPoint sp in stroke.StylusPoints) {
+ Point p = sp.ToPoint();
+ double deviation = DistanceFromLineToPoint(start, end, p);
+ deviationVariance += Math.Pow(deviation - avgDeviation, 2);
+ }
+ deviationVariance /= pointCount;
+
+ // 如果最大偏差超过线长的阈值比例,或者偏差方差较大(表示不均匀弯曲),则不拉直
+ if ((maxDeviation / lineLength) > sensitivity) {
+ return false;
+ }
+
+ // 如果偏差方差大,说明线条弯曲不均匀
+ if (deviationVariance > (sensitivity * lineLength * 0.05)) {
+ return false;
+ }
+
+ // 检查中点偏离情况 - 针对弧形线条特别有效
+ if (stroke.StylusPoints.Count > 10) {
+ int midIndex = stroke.StylusPoints.Count / 2;
+ Point midPoint = stroke.StylusPoints[midIndex].ToPoint();
+ double midDeviation = DistanceFromLineToPoint(start, end, midPoint);
+
+ // 如果中点偏离过大,不拉直
+ if (midDeviation > (lineLength * sensitivity * 0.8)) {
+ return false;
+ }
+ }
+
+ return true;
}
// New method: Creates a straight line stroke between two points
diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs
index 3d3f1eeb..ea8b4c73 100644
--- a/Ink Canvas/Resources/Settings.cs
+++ b/Ink Canvas/Resources/Settings.cs
@@ -409,6 +409,8 @@ namespace Ink_Canvas
public bool IsInkToShapeRectangle { get; set; } = true;
[JsonProperty("isInkToShapeRounded")]
public bool IsInkToShapeRounded { get; set; } = true;
+ [JsonProperty("lineStraightenSensitivity")]
+ public double LineStraightenSensitivity { get; set; } = 0.10; // 直线检测灵敏度,值越小越严格(0.05-0.75)
}
public class RandSettings {
diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.g.resources b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.g.resources
index 5de98a0df7915962f28de21fdbe4cbafe6212089..977fc01171f075340462a0fb8bd14ecab48a1632 100644
GIT binary patch
delta 81543
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