From 60c6e0632df2e9863b0f89e25fe3aa19c0e785a2 Mon Sep 17 00:00:00 2001
From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com>
Date: Sun, 29 Jun 2025 14:15:20 +0800
Subject: [PATCH] =?UTF-8?q?add:=E9=AB=98=E7=B2=BE=E5=BA=A6=E7=9B=B4?=
=?UTF-8?q?=E7=BA=BF=E6=8B=89=E7=9B=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Ink Canvas/MainWindow.xaml | 10 +-
Ink Canvas/MainWindow.xaml.cs | 2 +-
Ink Canvas/MainWindow_cs/MW_Settings.cs | 8 +
Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 2 +
.../MW_SimulatePressure&InkToShape.cs | 169 ++++++++++++++++--
Ink Canvas/Resources/Settings.cs | 2 +
6 files changed, 179 insertions(+), 14 deletions(-)
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index 2ebb8efb..546a061f 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -970,7 +970,15 @@
-
+
+
+
+
+
diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs
index c9b41a61..98de85fd 100644
--- a/Ink Canvas/MainWindow.xaml.cs
+++ b/Ink Canvas/MainWindow.xaml.cs
@@ -395,7 +395,7 @@ namespace Ink_Canvas {
if (string.IsNullOrEmpty(releaseNotes))
{
releaseNotes = $@"# InkCanvasForClass v{AvailableLatestVersion}更新
-
+
无法获取更新日志,但新版本已准备就绪。";
}
diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs
index 099212cf..074e9dd6 100644
--- a/Ink Canvas/MainWindow_cs/MW_Settings.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs
@@ -782,6 +782,14 @@ namespace Ink_Canvas {
// 立即保存设置到文件,确保设置不会丢失
SaveSettingsToFile();
}
+
+ private void ToggleSwitchHighPrecisionLineStraighten_Toggled(object sender, RoutedEventArgs e) {
+ if (!isLoaded) return;
+
+ Settings.Canvas.HighPrecisionLineStraighten = ToggleSwitchHighPrecisionLineStraighten.IsOn;
+ System.Diagnostics.Debug.WriteLine($"HighPrecisionLineStraighten changed: {Settings.Canvas.HighPrecisionLineStraighten}");
+ SaveSettingsToFile();
+ }
#endregion
diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
index d36a7f9d..100de955 100644
--- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
@@ -533,6 +533,8 @@ namespace Ink_Canvas {
AutoStraightenLineThresholdSlider.Value = Settings.Canvas.AutoStraightenLineThreshold;
// 直线拉直灵敏度也在这里初始化,即使它存储在InkToShape中
LineStraightenSensitivitySlider.Value = Settings.InkToShape.LineStraightenSensitivity;
+ // 初始化高精度直线拉直设置
+ ToggleSwitchHighPrecisionLineStraighten.IsOn = Settings.Canvas.HighPrecisionLineStraighten;
// 初始化直线端点吸附相关设置
ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
index e1a386ca..bb67682a 100644
--- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
@@ -687,20 +687,97 @@ namespace Ink_Canvas {
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++;
+ // 检查是否启用了高精度直线拉直
+ bool useHighPrecision = Settings.Canvas.HighPrecisionLineStraighten;
+
+ if (useHighPrecision) {
+ System.Diagnostics.Debug.WriteLine("使用高精度直线拉直模式");
+
+ // 高精度模式:每隔10像素取一个计数点
+ double strokeLength = 0;
+ double sampleInterval = 10.0; // 10像素间隔
+
+ // 计算笔画的总长度,用于后续采样
+ for (int i = 1; i < stroke.StylusPoints.Count; i++) {
+ Point p1 = stroke.StylusPoints[i-1].ToPoint();
+ Point p2 = stroke.StylusPoints[i].ToPoint();
+ strokeLength += GetDistance(p1, p2);
+ }
+
+ // 如果笔画太短,直接使用所有点
+ if (strokeLength < sampleInterval * 5) {
+ foreach (StylusPoint sp in stroke.StylusPoints) {
+ Point p = sp.ToPoint();
+ double deviation = DistanceFromLineToPoint(start, end, p);
+ maxDeviation = Math.Max(maxDeviation, deviation);
+ totalDeviation += deviation;
+ pointCount++;
+ }
+ } else {
+ // 使用等距采样点
+ double currentLength = 0;
+ double nextSampleAt = 0;
+
+ // 总是包含起点
+ Point lastPoint = start;
+ double deviation = DistanceFromLineToPoint(start, end, lastPoint);
+ maxDeviation = Math.Max(maxDeviation, deviation);
+ totalDeviation += deviation;
+ pointCount++;
+
+ // 采样中间点
+ for (int i = 1; i < stroke.StylusPoints.Count; i++) {
+ Point currentPoint = stroke.StylusPoints[i].ToPoint();
+ double segmentLength = GetDistance(lastPoint, currentPoint);
+
+ // 如果这段线段跨越了下一个采样点
+ while (currentLength + segmentLength >= nextSampleAt) {
+ // 计算采样点在线段上的位置
+ double t = (nextSampleAt - currentLength) / segmentLength;
+ Point samplePoint = new Point(
+ lastPoint.X + t * (currentPoint.X - lastPoint.X),
+ lastPoint.Y + t * (currentPoint.Y - lastPoint.Y)
+ );
+
+ // 计算采样点的偏差
+ deviation = DistanceFromLineToPoint(start, end, samplePoint);
+ maxDeviation = Math.Max(maxDeviation, deviation);
+ totalDeviation += deviation;
+ pointCount++;
+
+ // 设置下一个采样点位置
+ nextSampleAt += sampleInterval;
+
+ // 防止无限循环
+ if (nextSampleAt > strokeLength) break;
+ }
+
+ currentLength += segmentLength;
+ lastPoint = currentPoint;
+ }
+
+ // 总是包含终点
+ deviation = DistanceFromLineToPoint(start, end, end);
+ maxDeviation = Math.Max(maxDeviation, deviation);
+ totalDeviation += deviation;
+ pointCount++;
+ }
+ } else {
+ // 原始模式:使用所有点
+ foreach (StylusPoint sp in stroke.StylusPoints) {
+ Point p = sp.ToPoint();
+ double deviation = DistanceFromLineToPoint(start, end, p);
+ maxDeviation = Math.Max(maxDeviation, deviation);
+ totalDeviation += deviation;
+ pointCount++;
+ }
}
// 计算平均偏差
double avgDeviation = totalDeviation / pointCount;
// 更详细的调试信息
- System.Diagnostics.Debug.WriteLine($"Max deviation: {maxDeviation}, Avg: {avgDeviation}, Threshold: {sensitivity * lineLength}");
+ System.Diagnostics.Debug.WriteLine($"Max deviation: {maxDeviation}, Avg: {avgDeviation}, Threshold: {sensitivity * lineLength}, Points: {pointCount}");
// 支持更广泛的灵敏度范围 (0.05-2.0)
@@ -722,11 +799,79 @@ namespace Ink_Canvas {
else {
// 检查点分布的一致性 - 如果有些点偏离很大而其他点很接近直线,表明线条有明显弯曲
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);
+
+ // 使用相同的高精度/原始模式来计算方差
+ if (useHighPrecision) {
+ // 高精度模式:重新采样计算方差
+ double strokeLength = 0;
+ double sampleInterval = 10.0; // 10像素间隔
+
+ // 计算笔画的总长度,用于后续采样
+ for (int i = 1; i < stroke.StylusPoints.Count; i++) {
+ Point p1 = stroke.StylusPoints[i-1].ToPoint();
+ Point p2 = stroke.StylusPoints[i].ToPoint();
+ strokeLength += GetDistance(p1, p2);
+ }
+
+ // 如果笔画太短,直接使用所有点
+ if (strokeLength < sampleInterval * 5) {
+ foreach (StylusPoint sp in stroke.StylusPoints) {
+ Point p = sp.ToPoint();
+ double deviation = DistanceFromLineToPoint(start, end, p);
+ deviationVariance += Math.Pow(deviation - avgDeviation, 2);
+ }
+ } else {
+ // 使用等距采样点
+ double currentLength = 0;
+ double nextSampleAt = 0;
+ Point lastPoint = start;
+
+ // 起点方差
+ double deviation = DistanceFromLineToPoint(start, end, lastPoint);
+ deviationVariance += Math.Pow(deviation - avgDeviation, 2);
+
+ // 采样中间点
+ for (int i = 1; i < stroke.StylusPoints.Count; i++) {
+ Point currentPoint = stroke.StylusPoints[i].ToPoint();
+ double segmentLength = GetDistance(lastPoint, currentPoint);
+
+ // 如果这段线段跨越了下一个采样点
+ while (currentLength + segmentLength >= nextSampleAt) {
+ // 计算采样点在线段上的位置
+ double t = (nextSampleAt - currentLength) / segmentLength;
+ Point samplePoint = new Point(
+ lastPoint.X + t * (currentPoint.X - lastPoint.X),
+ lastPoint.Y + t * (currentPoint.Y - lastPoint.Y)
+ );
+
+ // 计算采样点的方差
+ deviation = DistanceFromLineToPoint(start, end, samplePoint);
+ deviationVariance += Math.Pow(deviation - avgDeviation, 2);
+
+ // 设置下一个采样点位置
+ nextSampleAt += sampleInterval;
+
+ // 防止无限循环
+ if (nextSampleAt > strokeLength) break;
+ }
+
+ currentLength += segmentLength;
+ lastPoint = currentPoint;
+ }
+
+ // 终点方差
+ deviation = DistanceFromLineToPoint(start, end, end);
+ deviationVariance += Math.Pow(deviation - avgDeviation, 2);
+ }
+ } else {
+ // 原始模式:使用所有点计算方差
+ foreach (StylusPoint sp in stroke.StylusPoints) {
+ Point p = sp.ToPoint();
+ double deviation = DistanceFromLineToPoint(start, end, p);
+ deviationVariance += Math.Pow(deviation - avgDeviation, 2);
+ }
}
+
deviationVariance /= pointCount;
// 输出更多调试信息
diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs
index a5abddbc..9513fe39 100644
--- a/Ink Canvas/Resources/Settings.cs
+++ b/Ink Canvas/Resources/Settings.cs
@@ -56,6 +56,8 @@ namespace Ink_Canvas
public bool AutoStraightenLine { get; set; } = true; // 是否启用直线自动拉直
[JsonProperty("autoStraightenLineThreshold")]
public int AutoStraightenLineThreshold { get; set; } = 30; // 直线自动拉直的长度阈值(像素)
+ [JsonProperty("highPrecisionLineStraighten")]
+ public bool HighPrecisionLineStraighten { get; set; } = true; // 是否启用高精度直线拉直
[JsonProperty("lineEndpointSnapping")]
public bool LineEndpointSnapping { get; set; } = true; // 是否启用直线端点吸附
[JsonProperty("lineEndpointSnappingThreshold")]