diff --git a/Ink Canvas/AssemblyInfo.cs b/Ink Canvas/AssemblyInfo.cs index cfc6a3d3..c52e2153 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.0.0")] -[assembly: AssemblyFileVersion("1.7.0.0")] +[assembly: AssemblyVersion("1.7.0.1")] +[assembly: AssemblyFileVersion("1.7.0.1")] diff --git a/Ink Canvas/Helpers/AutoUpdateHelper.cs b/Ink Canvas/Helpers/AutoUpdateHelper.cs index 201cab11..3058aa97 100644 --- a/Ink Canvas/Helpers/AutoUpdateHelper.cs +++ b/Ink Canvas/Helpers/AutoUpdateHelper.cs @@ -807,17 +807,48 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel"); - // 获取当前通道的最新版本 - string latestVersion = await CheckForUpdates(null, channel); + // 获取远程版本号,而不是检查更新 + string remoteVersion = null; + string proxy = null; - if (string.IsNullOrEmpty(latestVersion)) + // 根据通道选择URL + string primaryUrl, fallbackUrl; + + if (channel == UpdateChannel.Release) { - LogHelper.WriteLogToFile("AutoUpdate | No newer version found for fixing", LogHelper.LogType.Warning); + // Release通道版本信息地址 + primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/AutomaticUpdateVersionControl.txt"; + fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt"; + } + else + { + // Beta通道版本信息地址 + primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt"; + fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt"; + } + + LogHelper.WriteLogToFile($"AutoUpdate | Retrieving remote version from {channel} channel"); + + // 先尝试主地址 + remoteVersion = await GetRemoteVersion(primaryUrl); + + // 如果主地址失败,尝试备用地址 + if (remoteVersion == null) + { + LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed, trying fallback URL"); + remoteVersion = await GetRemoteVersion(fallbackUrl); + } + + if (string.IsNullOrEmpty(remoteVersion)) + { + LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve remote version for fixing", LogHelper.LogType.Error); return false; } - // 下载最新版本 - bool downloadResult = await DownloadSetupFileAndSaveStatus(latestVersion, "", channel); + LogHelper.WriteLogToFile($"AutoUpdate | Remote version for fixing: {remoteVersion}"); + + // 无论版本是否为最新,都下载远程版本 + bool downloadResult = await DownloadSetupFileAndSaveStatus(remoteVersion, "", channel); if (!downloadResult) { @@ -826,7 +857,7 @@ namespace Ink_Canvas.Helpers } // 执行安装,非静默模式 - InstallNewVersionApp(latestVersion, false); + InstallNewVersionApp(remoteVersion, false); // 设置为用户主动退出,避免被看门狗判定为崩溃 App.IsAppExitByUser = true; diff --git a/Ink Canvas/Helpers/LogHelper.cs b/Ink Canvas/Helpers/LogHelper.cs index a2c6ce66..b365636b 100644 --- a/Ink Canvas/Helpers/LogHelper.cs +++ b/Ink Canvas/Helpers/LogHelper.cs @@ -8,6 +8,9 @@ namespace Ink_Canvas.Helpers class LogHelper { public static string LogFile = "Log.txt"; + private static string LogsFolder = "Logs"; + private static string AppStartTime = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); + private static readonly long MaxLogsFolderSizeBytes = 5 * 1024 * 1024; // 5MB public static void NewLog(string str) { @@ -28,14 +31,40 @@ namespace Ink_Canvas.Helpers public static void WriteLogToFile(string str, LogType logType = LogType.Info) { + // 检查日志是否启用 + if (MainWindow.Settings != null && MainWindow.Settings.Advanced != null && !MainWindow.Settings.Advanced.IsLogEnabled) return; + string strLogType = logType.ToString(); try { - var file = App.RootPath + LogFile; + string file; + + // 检查是否启用了日期保存功能 + if (MainWindow.Settings != null && MainWindow.Settings.Advanced != null && MainWindow.Settings.Advanced.IsSaveLogByDate) + { + // 确保Logs文件夹存在 + string logsPath = Path.Combine(App.RootPath, LogsFolder); + if (!Directory.Exists(logsPath)) + { + Directory.CreateDirectory(logsPath); + } + + // 检查Logs文件夹大小,如果超过5MB则清空 + CheckAndCleanLogsFolder(logsPath); + + // 使用软件启动时间作为日志文件名 + file = Path.Combine(logsPath, $"Log_{AppStartTime}.txt"); + } + else + { + file = App.RootPath + LogFile; + } + if (!Directory.Exists(App.RootPath)) { Directory.CreateDirectory(App.RootPath); } + var threadId = Thread.CurrentThread.ManagedThreadId; var callingMethod = new StackTrace(2, true).GetFrame(0); string callerInfo = ""; @@ -57,6 +86,45 @@ namespace Ink_Canvas.Helpers catch { } } + private static void CheckAndCleanLogsFolder(string logsPath) + { + try + { + long totalSize = 0; + DirectoryInfo dirInfo = new DirectoryInfo(logsPath); + + // 如果目录不存在,直接返回 + if (!dirInfo.Exists) return; + + // 计算文件夹大小 + foreach (FileInfo file in dirInfo.GetFiles()) + { + totalSize += file.Length; + } + + // 如果超过5MB,清空文件夹 + if (totalSize > MaxLogsFolderSizeBytes) + { + foreach (FileInfo file in dirInfo.GetFiles()) + { + try + { + file.Delete(); + } + catch { } + } + + // 记录清理操作 + string cleanupMessage = $"Logs folder exceeded size limit ({totalSize / 1024.0 / 1024.0:F2} MB > {MaxLogsFolderSizeBytes / 1024.0 / 1024.0:F2} MB). Folder cleaned."; + using (StreamWriter sw = new StreamWriter(Path.Combine(logsPath, $"Log_{AppStartTime}.txt"), true)) + { + sw.WriteLine($"{DateTime.Now:O} [Cleanup] {cleanupMessage}"); + } + } + } + catch { } + } + internal static void WriteLogToFile(string v, object warning) { WriteLogToFile($"[Warning] {v}", LogType.Warning); diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 437ab176..546a061f 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -970,7 +970,15 @@ - + + + + + @@ -1693,7 +1701,14 @@ IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold" Toggled="ToggleSwitchIsLogEnabled_Toggled" /> - + + + + + @@ -2411,6 +2426,15 @@ FontWeight="Bold" Toggled="ToggleSwitchShowRandomAndSingleDraw_Toggled" /> + + + + @@ -3641,7 +3665,7 @@ TickFrequency="1" TickPlacement="None" ValueChanged="HighlighterWidthSlider_ValueChanged" /> 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_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index e74d36a6..03ee2b5e 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -23,6 +23,7 @@ using System.Text; using System.Globalization; using System.Windows.Data; using System.Xml.Linq; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; namespace Ink_Canvas { public partial class MainWindow : Window { @@ -825,7 +826,24 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); - new RandWindow(Settings, true).ShowDialog(); + // 检查是否启用了直接调用ClassIsland点名功能 + if (Settings.RandSettings.DirectCallCiRand) { + try { + System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { + FileName = "classisland://plugins/IslandCaller/Run", + UseShellExecute = true + }); + } + catch (Exception ex) { + MessageBox.Show("无法调用ClassIsland点名:" + ex.Message); + + // 调用失败时回退到默认的随机点名窗口 + new RandWindow(Settings, true).ShowDialog(); + } + } else { + // 使用默认的随机点名窗口 + new RandWindow(Settings, true).ShowDialog(); + } } private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) { diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index e19807b1..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 @@ -1724,6 +1732,12 @@ namespace Ink_Canvas { Settings.Advanced.IsLogEnabled = ToggleSwitchIsLogEnabled.IsOn; SaveSettingsToFile(); } + + private void ToggleSwitchIsSaveLogByDate_Toggled(object sender, RoutedEventArgs e) { + if (!isLoaded) return; + Settings.Advanced.IsSaveLogByDate = ToggleSwitchIsSaveLogByDate.IsOn; + SaveSettingsToFile(); + } private void ToggleSwitchIsSecondConfimeWhenShutdownApp_Toggled(object sender, RoutedEventArgs e) { if (!isLoaded) return; @@ -1769,6 +1783,16 @@ namespace Ink_Canvas { // 保存设置到文件 SaveSettingsToFile(); } + + private void ToggleSwitchDirectCallCiRand_Toggled(object sender, RoutedEventArgs e) { + if (!isLoaded) return; + + // 获取开关状态并保存到设置中 + Settings.RandSettings.DirectCallCiRand = ToggleSwitchDirectCallCiRand.IsOn; + + // 保存设置到文件 + SaveSettingsToFile(); + } #endregion diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index 338888d2..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; @@ -547,41 +549,30 @@ namespace Ink_Canvas { FingerModeBoundsWidthSlider.Value = Settings.Advanced.FingerModeBoundsWidth; NibModeBoundsWidthSlider.Value = Settings.Advanced.NibModeBoundsWidth; ToggleSwitchIsLogEnabled.IsOn = Settings.Advanced.IsLogEnabled; - + ToggleSwitchIsSaveLogByDate.IsOn = Settings.Advanced.IsSaveLogByDate; ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn = Settings.Advanced.IsSecondConfirmWhenShutdownApp; - - ToggleSwitchEraserBindTouchMultiplier.IsOn = Settings.Advanced.EraserBindTouchMultiplier; - ToggleSwitchIsSpecialScreen.IsOn = Settings.Advanced.IsSpecialScreen; - - TouchMultiplierSlider.Visibility = - ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed; - ToggleSwitchIsQuadIR.IsOn = Settings.Advanced.IsQuadIR; - + ToggleSwitchEraserBindTouchMultiplier.IsOn = Settings.Advanced.EraserBindTouchMultiplier; ToggleSwitchIsEnableFullScreenHelper.IsOn = Settings.Advanced.IsEnableFullScreenHelper; + ToggleSwitchIsEnableEdgeGestureUtil.IsOn = Settings.Advanced.IsEnableEdgeGestureUtil; + ToggleSwitchIsEnableForceFullScreen.IsOn = Settings.Advanced.IsEnableForceFullScreen; + ToggleSwitchIsEnableResolutionChangeDetection.IsOn = Settings.Advanced.IsEnableResolutionChangeDetection; + ToggleSwitchIsEnableDPIChangeDetection.IsOn = Settings.Advanced.IsEnableDPIChangeDetection; + ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn = Settings.Advanced.IsEnableAvoidFullScreenHelper; if (Settings.Advanced.IsEnableFullScreenHelper) { FullScreenHelper.MarkFullscreenWindowTaskbarList(new WindowInteropHelper(this).Handle, true); } - - ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn = Settings.Advanced.IsEnableAvoidFullScreenHelper; if (Settings.Advanced.IsEnableAvoidFullScreenHelper) { AvoidFullScreenHelper.StartAvoidFullScreen(this); } - - ToggleSwitchIsEnableEdgeGestureUtil.IsOn = Settings.Advanced.IsEnableEdgeGestureUtil; if (Settings.Advanced.IsEnableEdgeGestureUtil) { if (OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10) EdgeGestureUtil.DisableEdgeGestures(new WindowInteropHelper(this).Handle, true); } - - ToggleSwitchIsEnableForceFullScreen.IsOn = Settings.Advanced.IsEnableForceFullScreen; - - ToggleSwitchIsEnableDPIChangeDetection.IsOn = Settings.Advanced.IsEnableDPIChangeDetection; - - ToggleSwitchIsEnableResolutionChangeDetection.IsOn = - Settings.Advanced.IsEnableResolutionChangeDetection; + TouchMultiplierSlider.Visibility = + ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed; } else { Settings.Advanced = new Advanced(); } @@ -613,6 +604,7 @@ namespace Ink_Canvas { RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency; RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents; ToggleSwitchShowRandomAndSingleDraw.IsOn = Settings.RandSettings.ShowRandomAndSingleDraw; + ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand; RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed; SingleDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed; } else { @@ -620,6 +612,7 @@ namespace Ink_Canvas { ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn; RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency; RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents; + ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand; } // Automation 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/Properties/AssemblyInfo.cs b/Ink Canvas/Properties/AssemblyInfo.cs index ed7a4d2a..2f1690a3 100644 --- a/Ink Canvas/Properties/AssemblyInfo.cs +++ b/Ink Canvas/Properties/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.0.0")] -[assembly: AssemblyFileVersion("1.7.0.0")] +[assembly: AssemblyVersion("1.7.0.1")] +[assembly: AssemblyFileVersion("1.7.0.1")] diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs index 51ebfcd0..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")] @@ -381,6 +383,9 @@ namespace Ink_Canvas [JsonProperty("isLogEnabled")] public bool IsLogEnabled { get; set; } = true; + + [JsonProperty("isSaveLogByDate")] + public bool IsSaveLogByDate { get; set; } = true; [JsonProperty("isEnableFullScreenHelper")] public bool IsEnableFullScreenHelper { get; set; } = false; @@ -434,5 +439,7 @@ namespace Ink_Canvas public int RandWindowOnceMaxStudents { get; set; } = 10; [JsonProperty("showRandomAndSingleDraw")] public bool ShowRandomAndSingleDraw { get; set; } = true; + [JsonProperty("directCallCiRand")] + public bool DirectCallCiRand { get; set; } = false; } } \ No newline at end of file diff --git a/Ink Canvas/Resources/new-icons/gesture-enabled.png b/Ink Canvas/Resources/new-icons/gesture-enabled.png index afbf60d6..fe0b9b37 100644 Binary files a/Ink Canvas/Resources/new-icons/gesture-enabled.png and b/Ink Canvas/Resources/new-icons/gesture-enabled.png differ diff --git a/Ink Canvas/Resources/new-icons/gesture.png b/Ink Canvas/Resources/new-icons/gesture.png index c0b72600..8e7c6401 100644 Binary files a/Ink Canvas/Resources/new-icons/gesture.png and b/Ink Canvas/Resources/new-icons/gesture.png differ