improve:直线拉直灵敏度设置

This commit is contained in:
CJK_mkp
2025-06-18 15:10:33 +08:00
parent 7049c53889
commit 6dafde9735
10 changed files with 3510 additions and 3346 deletions
+11 -1
View File
@@ -940,7 +940,17 @@
<TextBlock Foreground="#fafafa" Text="{Binding ElementName=AutoStraightenLineThresholdSlider, Path=Value, StringFormat={}{0:0}}"
VerticalAlignment="Center" FontSize="14" Margin="16,0,0,0" />
</ui:SimpleStackPanel>
<TextBlock Text="# 开启后,当绘制的直线超过设定长度阈值时,将自动调整为完美直线。" TextWrapping="Wrap" Foreground="#a1a1aa" />
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left"
Visibility="{Binding ElementName=ToggleSwitchAutoStraightenLine, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Foreground="#fafafa" Text="灵敏度" VerticalAlignment="Center"
FontSize="14" Margin="0,0,16,0" />
<Slider Name="LineStraightenSensitivitySlider" Width="150" Minimum="0.05" Maximum="0.75"
Value="0.10" TickFrequency="0.05" IsSnapToTickEnabled="True"
ValueChanged="LineStraightenSensitivitySlider_ValueChanged" />
<TextBlock Foreground="#fafafa" Text="{Binding ElementName=LineStraightenSensitivitySlider, Path=Value, StringFormat={}{0:F2}}"
VerticalAlignment="Center" FontSize="14" Margin="16,0,0,0" />
</ui:SimpleStackPanel>
<TextBlock Text="# 开启后,当绘制的直线超过设定长度阈值时,将自动调整为完美直线。灵敏度范围0.05-0.75,越小要求越严格,弯曲的线条越不容易被拉直;值越大越容易识别为直线。" TextWrapping="Wrap" Foreground="#a1a1aa" />
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
+7
View File
@@ -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
+7
View File
@@ -749,6 +749,13 @@ namespace Ink_Canvas {
Settings.Canvas.LineEndpointSnappingThreshold = (int)e.NewValue;
SaveSettingsToFile();
}
private void LineStraightenSensitivitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
if (!isLoaded) return;
Settings.InkToShape.LineStraightenSensitivity = e.NewValue;
SaveSettingsToFile();
}
#endregion
@@ -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();
}
+23 -1
View File
@@ -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();
}
}
}
}
@@ -14,7 +14,7 @@ namespace Ink_Canvas {
private StrokeCollection newStrokes = new StrokeCollection();
private List<Circle> circles = new List<Circle>();
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
+2
View File
@@ -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 {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff