2025-10-31 14:44:59 +08:00
|
|
|
using Ink_Canvas.Helpers;
|
2025-08-31 11:43:52 +08:00
|
|
|
using iNKORE.UI.WPF.Modern.Controls;
|
|
|
|
|
using System;
|
2025-05-25 09:29:48 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows;
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
using System.Windows.Ink;
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
using System.Windows.Media.Animation;
|
2025-09-20 12:35:30 +08:00
|
|
|
using System.Windows.Threading;
|
2025-09-13 12:22:08 +08:00
|
|
|
using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox;
|
2025-05-25 09:29:48 +08:00
|
|
|
using Point = System.Windows.Point;
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
namespace Ink_Canvas
|
|
|
|
|
{
|
|
|
|
|
public partial class MainWindow : Window
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
#region Floating Bar Control
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private void ImageDrawShape_MouseUp(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
|
|
|
|
|
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
|
|
|
|
|
((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent);
|
|
|
|
|
if (sender == ShapeDrawFloatingBarBtn && lastBorderMouseDownObject != ShapeDrawFloatingBarBtn) return;
|
|
|
|
|
|
|
|
|
|
// FloatingBarIcons_MouseUp_New(sender);
|
2025-08-03 16:46:33 +08:00
|
|
|
if (BorderDrawShape.Visibility == Visibility.Visible)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
AnimationsHelper.HideWithSlideAndFade(EraserSizePanel);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(PenPalette);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardPenPalette);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BorderDrawShape);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderDrawShape);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
AnimationsHelper.HideWithSlideAndFade(EraserSizePanel);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(PenPalette);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardPenPalette);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder);
|
|
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder);
|
2025-08-13 12:16:55 +08:00
|
|
|
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
2025-05-25 09:29:48 +08:00
|
|
|
AnimationsHelper.ShowWithSlideFromBottomAndFade(BorderDrawShape);
|
|
|
|
|
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderDrawShape);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion Floating Bar Control
|
|
|
|
|
|
2025-07-28 14:40:44 +08:00
|
|
|
private int drawingShapeMode;
|
|
|
|
|
private bool isLongPressSelected; // 用于存是否是"选中"状态,便于后期抬笔后不做切换到笔的处理
|
2025-05-25 09:29:48 +08:00
|
|
|
|
|
|
|
|
#region Buttons
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private void SymbolIconPinBorderDrawShape_MouseUp(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
|
|
|
|
ToggleSwitchDrawShapeBorderAutoHide.IsOn = !ToggleSwitchDrawShapeBorderAutoHide.IsOn;
|
|
|
|
|
|
|
|
|
|
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn)
|
2025-09-22 13:09:43 +08:00
|
|
|
((SymbolIcon)sender).Symbol = Symbol.Pin;
|
2025-05-25 09:29:48 +08:00
|
|
|
else
|
2025-09-22 13:09:43 +08:00
|
|
|
((SymbolIcon)sender).Symbol = Symbol.UnPin;
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
|
|
|
|
|
2025-07-28 14:40:44 +08:00
|
|
|
private object lastMouseDownSender;
|
2025-05-25 09:29:48 +08:00
|
|
|
private DateTime lastMouseDownTime = DateTime.MinValue;
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private async void Image_MouseDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
lastMouseDownSender = sender;
|
|
|
|
|
lastMouseDownTime = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
await Task.Delay(500);
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
if (lastMouseDownSender == sender)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
lastMouseDownSender = null;
|
|
|
|
|
var dA = new DoubleAnimation(1, 0.3, new Duration(TimeSpan.FromMilliseconds(100)));
|
|
|
|
|
((UIElement)sender).BeginAnimation(OpacityProperty, dA);
|
|
|
|
|
|
|
|
|
|
forceEraser = true;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
|
|
|
|
if (sender == ImageDrawLine || sender == BoardImageDrawLine)
|
|
|
|
|
drawingShapeMode = 1;
|
|
|
|
|
else if (sender == ImageDrawDashedLine || sender == BoardImageDrawDashedLine)
|
|
|
|
|
drawingShapeMode = 8;
|
|
|
|
|
else if (sender == ImageDrawDotLine || sender == BoardImageDrawDotLine)
|
|
|
|
|
drawingShapeMode = 18;
|
|
|
|
|
else if (sender == ImageDrawArrow || sender == BoardImageDrawArrow)
|
|
|
|
|
drawingShapeMode = 2;
|
|
|
|
|
else if (sender == ImageDrawParallelLine || sender == BoardImageDrawParallelLine) drawingShapeMode = 15;
|
2025-09-07 13:30:46 +08:00
|
|
|
|
2025-09-06 17:12:25 +08:00
|
|
|
// 更新模式缓存
|
|
|
|
|
UpdateCurrentToolMode("shape");
|
2025-09-07 13:30:46 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
isLongPressSelected = true;
|
|
|
|
|
if (isSingleFingerDragMode) BtnFingerDragMode_Click(BtnFingerDragMode, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private void BtnPen_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
forceEraser = false;
|
|
|
|
|
drawingShapeMode = 0;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
|
|
|
|
CancelSingleFingerDragMode();
|
|
|
|
|
isLongPressSelected = false;
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private Task<bool> CheckIsDrawingShapesInMultiTouchMode()
|
|
|
|
|
{
|
|
|
|
|
if (isInMultiTouchMode)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
ToggleSwitchEnableMultiTouchMode.IsOn = false;
|
2025-05-25 09:29:48 +08:00
|
|
|
lastIsInMultiTouchMode = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Task.FromResult(true);
|
|
|
|
|
}
|
2025-08-23 21:39:00 +08:00
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
public async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastMouseDownSender == sender)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 1;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-12-20 13:56:46 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
}
|
2025-10-31 14:44:59 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastMouseDownSender = null;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (isLongPressSelected)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
|
2025-12-20 17:30:18 +08:00
|
|
|
if (sender is UIElement ui)
|
|
|
|
|
{
|
|
|
|
|
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
|
|
|
|
|
ui.BeginAnimation(OpacityProperty, dA);
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-11-30 11:51:19 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawDashedLine_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastMouseDownSender == sender)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 8;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-12-20 13:56:46 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
}
|
2025-10-31 14:44:59 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastMouseDownSender = null;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (isLongPressSelected)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
|
2025-12-20 17:30:18 +08:00
|
|
|
if (sender is UIElement ui)
|
|
|
|
|
{
|
|
|
|
|
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
|
|
|
|
|
ui.BeginAnimation(OpacityProperty, dA);
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-11-30 11:51:19 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawDotLine_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastMouseDownSender == sender)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 18;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-12-20 13:56:46 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastMouseDownSender = null;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (isLongPressSelected)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
|
2025-12-20 17:30:18 +08:00
|
|
|
if (sender is UIElement ui)
|
|
|
|
|
{
|
|
|
|
|
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
|
|
|
|
|
ui.BeginAnimation(OpacityProperty, dA);
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-11-30 11:51:19 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawArrow_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastMouseDownSender == sender)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 2;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-12-20 13:56:46 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastMouseDownSender = null;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (isLongPressSelected)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
|
2025-12-20 17:30:18 +08:00
|
|
|
if (sender is UIElement ui)
|
|
|
|
|
{
|
|
|
|
|
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
|
|
|
|
|
ui.BeginAnimation(OpacityProperty, dA);
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-11-30 11:51:19 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawParallelLine_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastMouseDownSender == sender)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 15;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-12-20 13:56:46 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastMouseDownSender = null;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (isLongPressSelected)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
|
2025-12-20 17:30:18 +08:00
|
|
|
if (sender is UIElement ui)
|
|
|
|
|
{
|
|
|
|
|
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
|
|
|
|
|
ui.BeginAnimation(OpacityProperty, dA);
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-11-30 11:51:19 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCoordinate1_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 11;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCoordinate2_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 12;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCoordinate3_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 13;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCoordinate4_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 14;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCoordinate5_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 17;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawRectangle_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 3;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawRectangleCenter_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 19;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawEllipse_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 4;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCircle_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 5;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCenterEllipse_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 16;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCenterEllipseWithFocalPoint_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 23;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawDashedCircle_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 10;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawHyperbola_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 24;
|
2025-05-25 09:29:48 +08:00
|
|
|
drawMultiStepShapeCurrentStep = 0;
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawHyperbolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 25;
|
2025-05-25 09:29:48 +08:00
|
|
|
drawMultiStepShapeCurrentStep = 0;
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawParabola1_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 20;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawParabolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 22;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawParabola2_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 21;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCylinder_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 6;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCone_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 7;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private async void BtnDrawCuboid_Click(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
await CheckIsDrawingShapesInMultiTouchMode();
|
2025-11-30 11:51:19 +08:00
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 9;
|
2025-05-25 09:29:48 +08:00
|
|
|
isFirstTouchCuboid = true;
|
|
|
|
|
CuboidFrontRectIniP = new Point();
|
|
|
|
|
CuboidFrontRectEndP = new Point();
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = true;
|
2025-10-31 14:44:59 +08:00
|
|
|
CancelSingleFingerDragMode();
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawShapePromptToPen();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private void inkCanvas_TouchMove(object sender, TouchEventArgs e)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
if (isSingleFingerDragMode) return;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawingShapeMode != 0)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
//EraserContainer.Background = null;
|
|
|
|
|
//ImageEraser.Visibility = Visibility.Visible;
|
|
|
|
|
if (isWaitUntilNextTouchDown) return;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (dec.Count > 1)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
isWaitUntilNextTouchDown = true;
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-08-31 09:54:13 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-08-31 09:54:13 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-09-30 19:15:03 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
return;
|
2025-08-10 12:20:51 +08:00
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
if (inkCanvas.EditingMode != InkCanvasEditingMode.None)
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
2025-06-17 18:45:55 +08:00
|
|
|
}
|
2025-09-30 19:15:03 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
MouseTouchMove(e.GetTouchPoint(inkCanvas).Position);
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
|
|
|
|
|
2025-07-28 14:40:44 +08:00
|
|
|
private int drawMultiStepShapeCurrentStep; //多笔完成的图形 当前所处在的笔画
|
2025-05-25 09:29:48 +08:00
|
|
|
|
|
|
|
|
private StrokeCollection drawMultiStepShapeSpecialStrokeCollection = new StrokeCollection(); //多笔完成的图形 当前所处在的笔画
|
|
|
|
|
|
|
|
|
|
//double drawMultiStepShapeSpecialParameter1 = 0.0; //多笔完成的图形 特殊参数 通常用于表示a
|
|
|
|
|
//double drawMultiStepShapeSpecialParameter2 = 0.0; //多笔完成的图形 特殊参数 通常用于表示b
|
2025-07-28 14:40:44 +08:00
|
|
|
private double drawMultiStepShapeSpecialParameter3; //多笔完成的图形 特殊参数 通常用于表示k
|
2025-05-25 09:29:48 +08:00
|
|
|
|
|
|
|
|
#region 形状绘制主函数
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
private void MouseTouchMove(Point endP)
|
|
|
|
|
{
|
2025-07-20 15:21:59 +08:00
|
|
|
// 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑
|
2025-07-28 14:40:44 +08:00
|
|
|
if (Settings.Canvas.FitToCurve) drawingAttributes.FitToCurve = false;
|
2025-08-30 18:10:55 +08:00
|
|
|
// 在绘制过程中禁用浮动栏交互,避免干扰绘制
|
2025-05-25 09:29:48 +08:00
|
|
|
ViewboxFloatingBar.IsHitTestVisible = false;
|
|
|
|
|
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
|
|
|
|
List<Point> pointList;
|
|
|
|
|
StylusPointCollection point;
|
|
|
|
|
Stroke stroke;
|
|
|
|
|
var strokes = new StrokeCollection();
|
|
|
|
|
var newIniP = iniP;
|
2025-08-03 16:46:33 +08:00
|
|
|
switch (drawingShapeMode)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
case 1:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(iniP.X, iniP.Y),
|
|
|
|
|
new Point(endP.X, endP.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
2025-05-25 09:29:48 +08:00
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
strokes.Add(GenerateDashedLineStrokeCollection(iniP, endP));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
2025-05-25 09:29:48 +08:00
|
|
|
break;
|
|
|
|
|
case 18:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
strokes.Add(GenerateDotLineStrokeCollection(iniP, endP));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
2025-05-25 09:29:48 +08:00
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
double w = 15, h = 10;
|
|
|
|
|
var theta = Math.Atan2(iniP.Y - endP.Y, iniP.X - endP.X);
|
|
|
|
|
var sint = Math.Sin(theta);
|
|
|
|
|
var cost = Math.Cos(theta);
|
|
|
|
|
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(iniP.X, iniP.Y),
|
|
|
|
|
new Point(endP.X, endP.Y),
|
|
|
|
|
new Point(endP.X + (w * cost - h * sint), endP.Y + (w * sint + h * cost)),
|
|
|
|
|
new Point(endP.X, endP.Y),
|
|
|
|
|
new Point(endP.X + (w * cost + h * sint), endP.Y - (h * cost - w * sint))
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
2025-05-25 09:29:48 +08:00
|
|
|
break;
|
|
|
|
|
case 15:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
var d = GetDistance(iniP, endP);
|
|
|
|
|
if (d == 0) return;
|
|
|
|
|
var sinTheta = (iniP.Y - endP.Y) / d;
|
|
|
|
|
var cosTheta = (endP.X - iniP.X) / d;
|
|
|
|
|
var tanTheta = Math.Abs(sinTheta / cosTheta);
|
|
|
|
|
double x = 25;
|
2025-08-03 16:46:33 +08:00
|
|
|
if (Math.Abs(tanTheta) < 1.0 / 12)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
sinTheta = 0;
|
|
|
|
|
cosTheta = 1;
|
|
|
|
|
endP.Y = iniP.Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tanTheta < 0.63 && tanTheta > 0.52) //30
|
|
|
|
|
{
|
|
|
|
|
sinTheta = sinTheta / Math.Abs(sinTheta) * 0.5;
|
|
|
|
|
cosTheta = cosTheta / Math.Abs(cosTheta) * 0.866;
|
|
|
|
|
endP.Y = iniP.Y - d * sinTheta;
|
|
|
|
|
endP.X = iniP.X + d * cosTheta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tanTheta < 1.08 && tanTheta > 0.92) //45
|
|
|
|
|
{
|
|
|
|
|
sinTheta = sinTheta / Math.Abs(sinTheta) * 0.707;
|
|
|
|
|
cosTheta = cosTheta / Math.Abs(cosTheta) * 0.707;
|
|
|
|
|
endP.Y = iniP.Y - d * sinTheta;
|
|
|
|
|
endP.X = iniP.X + d * cosTheta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tanTheta < 1.95 && tanTheta > 1.63) //60
|
|
|
|
|
{
|
|
|
|
|
sinTheta = sinTheta / Math.Abs(sinTheta) * 0.866;
|
|
|
|
|
cosTheta = cosTheta / Math.Abs(cosTheta) * 0.5;
|
|
|
|
|
endP.Y = iniP.Y - d * sinTheta;
|
|
|
|
|
endP.X = iniP.X + d * cosTheta;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
if (Math.Abs(cosTheta / sinTheta) < 1.0 / 12)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
endP.X = iniP.X;
|
|
|
|
|
sinTheta = 1;
|
|
|
|
|
cosTheta = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X - 3 * x * sinTheta, iniP.Y - 3 * x * cosTheta),
|
|
|
|
|
new Point(endP.X - 3 * x * sinTheta, endP.Y - 3 * x * cosTheta)));
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X - x * sinTheta, iniP.Y - x * cosTheta),
|
|
|
|
|
new Point(endP.X - x * sinTheta, endP.Y - x * cosTheta)));
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X + x * sinTheta, iniP.Y + x * cosTheta),
|
|
|
|
|
new Point(endP.X + x * sinTheta, endP.Y + x * cosTheta)));
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X + 3 * x * sinTheta, iniP.Y + 3 * x * cosTheta),
|
|
|
|
|
new Point(endP.X + 3 * x * sinTheta, endP.Y + 3 * x * cosTheta)));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 11:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(2 * iniP.X - (endP.X - 20), iniP.Y),
|
|
|
|
|
new Point(endP.X, iniP.Y)));
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, 2 * iniP.Y - (endP.Y + 20)),
|
|
|
|
|
new Point(iniP.X, endP.Y)));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 12:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
if (Math.Abs(iniP.X - endP.X) < 0.01) return;
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(
|
|
|
|
|
new Point(iniP.X + (iniP.X - endP.X) / Math.Abs(iniP.X - endP.X) * 25, iniP.Y),
|
|
|
|
|
new Point(endP.X, iniP.Y)));
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, 2 * iniP.Y - (endP.Y + 20)),
|
|
|
|
|
new Point(iniP.X, endP.Y)));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 13:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
if (Math.Abs(iniP.Y - endP.Y) < 0.01) return;
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(2 * iniP.X - (endP.X - 20), iniP.Y),
|
|
|
|
|
new Point(endP.X, iniP.Y)));
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(
|
|
|
|
|
new Point(iniP.X, iniP.Y + (iniP.Y - endP.Y) / Math.Abs(iniP.Y - endP.Y) * 25),
|
|
|
|
|
new Point(iniP.X, endP.Y)));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 14:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
if (Math.Abs(iniP.X - endP.X) < 0.01 || Math.Abs(iniP.Y - endP.Y) < 0.01) return;
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(
|
|
|
|
|
new Point(iniP.X + (iniP.X - endP.X) / Math.Abs(iniP.X - endP.X) * 25, iniP.Y),
|
|
|
|
|
new Point(endP.X, iniP.Y)));
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(
|
|
|
|
|
new Point(iniP.X, iniP.Y + (iniP.Y - endP.Y) / Math.Abs(iniP.Y - endP.Y) * 25),
|
|
|
|
|
new Point(iniP.X, endP.Y)));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 17:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, iniP.Y),
|
|
|
|
|
new Point(iniP.X + Math.Abs(endP.X - iniP.X), iniP.Y)));
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, iniP.Y),
|
|
|
|
|
new Point(iniP.X, iniP.Y - Math.Abs(endP.Y - iniP.Y))));
|
|
|
|
|
d = (Math.Abs(iniP.X - endP.X) + Math.Abs(iniP.Y - endP.Y)) / 2;
|
|
|
|
|
strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, iniP.Y),
|
|
|
|
|
new Point(iniP.X - d / 1.76, iniP.Y + d / 1.76)));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(iniP.X, iniP.Y),
|
|
|
|
|
new Point(iniP.X, endP.Y),
|
|
|
|
|
new Point(endP.X, endP.Y),
|
|
|
|
|
new Point(endP.X, iniP.Y),
|
|
|
|
|
new Point(iniP.X, iniP.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
break;
|
|
|
|
|
case 19:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
var a = iniP.X - endP.X;
|
|
|
|
|
var b = iniP.Y - endP.Y;
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(iniP.X - a, iniP.Y - b),
|
|
|
|
|
new Point(iniP.X - a, iniP.Y + b),
|
|
|
|
|
new Point(iniP.X + a, iniP.Y + b),
|
|
|
|
|
new Point(iniP.X + a, iniP.Y - b),
|
|
|
|
|
new Point(iniP.X - a, iniP.Y - b)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
pointList = GenerateEllipseGeometry(iniP, endP);
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
var R = GetDistance(iniP, endP);
|
|
|
|
|
pointList = GenerateEllipseGeometry(new Point(iniP.X - R, iniP.Y - R),
|
|
|
|
|
new Point(iniP.X + R, iniP.Y + R));
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-08-12 15:45:33 +08:00
|
|
|
// 如果启用了圆心标记功能,则绘制圆心
|
2025-12-20 13:56:46 +08:00
|
|
|
if (Settings.Canvas.ShowCircleCenter)
|
|
|
|
|
{
|
2025-08-12 15:45:33 +08:00
|
|
|
DrawCircleCenter(iniP);
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
break;
|
|
|
|
|
case 16:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
var halfA = endP.X - iniP.X;
|
|
|
|
|
var halfB = endP.Y - iniP.Y;
|
|
|
|
|
pointList = GenerateEllipseGeometry(new Point(iniP.X - halfA, iniP.Y - halfB),
|
|
|
|
|
new Point(iniP.X + halfA, iniP.Y + halfB));
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
lastTempStroke = stroke;
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
break;
|
|
|
|
|
case 23:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
a = Math.Abs(endP.X - iniP.X);
|
|
|
|
|
b = Math.Abs(endP.Y - iniP.Y);
|
|
|
|
|
pointList = GenerateEllipseGeometry(new Point(iniP.X - a, iniP.Y - b),
|
|
|
|
|
new Point(iniP.X + a, iniP.Y + b));
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke);
|
|
|
|
|
var c = Math.Sqrt(Math.Abs(a * a - b * b));
|
|
|
|
|
StylusPoint stylusPoint;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (a > b)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
stylusPoint = new StylusPoint(iniP.X + c, iniP.Y, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
stylusPoint = new StylusPoint(iniP.X - c, iniP.Y, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
else if (a < b)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
stylusPoint = new StylusPoint(iniP.X, iniP.Y - c, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
stylusPoint = new StylusPoint(iniP.X, iniP.Y + c, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
2025-12-20 13:56:46 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 10:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
R = GetDistance(iniP, endP);
|
|
|
|
|
strokes = GenerateDashedLineEllipseStrokeCollection(new Point(iniP.X - R, iniP.Y - R),
|
|
|
|
|
new Point(iniP.X + R, iniP.Y + R));
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 24:
|
|
|
|
|
case 25:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
//双曲线 x^2/a^2 - y^2/b^2 = 1
|
|
|
|
|
if (Math.Abs(iniP.X - endP.X) < 0.01 || Math.Abs(iniP.Y - endP.Y) < 0.01) return;
|
|
|
|
|
var pointList2 = new List<Point>();
|
|
|
|
|
var pointList3 = new List<Point>();
|
|
|
|
|
var pointList4 = new List<Point>();
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawMultiStepShapeCurrentStep == 0)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
//第一笔:画渐近线
|
|
|
|
|
var k = Math.Abs((endP.Y - iniP.Y) / (endP.X - iniP.X));
|
|
|
|
|
strokes.Add(
|
|
|
|
|
GenerateDashedLineStrokeCollection(new Point(2 * iniP.X - endP.X, 2 * iniP.Y - endP.Y),
|
|
|
|
|
endP));
|
|
|
|
|
strokes.Add(GenerateDashedLineStrokeCollection(new Point(2 * iniP.X - endP.X, endP.Y),
|
2025-08-10 12:20:51 +08:00
|
|
|
new Point(endP.X, 2 * iniP.Y - endP.Y)));
|
2025-05-25 09:29:48 +08:00
|
|
|
drawMultiStepShapeSpecialParameter3 = k;
|
|
|
|
|
drawMultiStepShapeSpecialStrokeCollection = strokes;
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
//第二笔:画双曲线
|
2025-11-30 11:51:19 +08:00
|
|
|
// 先将第一笔的渐近线添加到strokes中
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawMultiStepShapeSpecialStrokeCollection != null && drawMultiStepShapeSpecialStrokeCollection.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var asymptoteStroke in drawMultiStepShapeSpecialStrokeCollection)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
strokes.Add(asymptoteStroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
var k = drawMultiStepShapeSpecialParameter3;
|
|
|
|
|
var isHyperbolaFocalPointOnXAxis = Math.Abs((endP.Y - iniP.Y) / (endP.X - iniP.X)) < k;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (isHyperbolaFocalPointOnXAxis)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
// 焦点在 x 轴上
|
|
|
|
|
a = Math.Sqrt(Math.Abs((endP.X - iniP.X) * (endP.X - iniP.X) -
|
|
|
|
|
(endP.Y - iniP.Y) * (endP.Y - iniP.Y) / (k * k)));
|
|
|
|
|
b = a * k;
|
|
|
|
|
pointList = new List<Point>();
|
2025-12-20 13:56:46 +08:00
|
|
|
for (var i = a; i <= Math.Abs(endP.X - iniP.X); i += 0.5)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var rY = Math.Sqrt(Math.Abs(k * k * i * i - b * b));
|
|
|
|
|
pointList.Add(new Point(iniP.X + i, iniP.Y - rY));
|
|
|
|
|
pointList2.Add(new Point(iniP.X + i, iniP.Y + rY));
|
|
|
|
|
pointList3.Add(new Point(iniP.X - i, iniP.Y - rY));
|
|
|
|
|
pointList4.Add(new Point(iniP.X - i, iniP.Y + rY));
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
// 焦点在 y 轴上
|
|
|
|
|
a = Math.Sqrt(Math.Abs((endP.Y - iniP.Y) * (endP.Y - iniP.Y) -
|
|
|
|
|
(endP.X - iniP.X) * (endP.X - iniP.X) * (k * k)));
|
|
|
|
|
b = a / k;
|
|
|
|
|
pointList = new List<Point>();
|
2025-12-20 13:56:46 +08:00
|
|
|
for (var i = a; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var rX = Math.Sqrt(Math.Abs(i * i / k / k - b * b));
|
|
|
|
|
pointList.Add(new Point(iniP.X - rX, iniP.Y + i));
|
|
|
|
|
pointList2.Add(new Point(iniP.X + rX, iniP.Y + i));
|
|
|
|
|
pointList3.Add(new Point(iniP.X - rX, iniP.Y - i));
|
|
|
|
|
pointList4.Add(new Point(iniP.X + rX, iniP.Y - i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
point = new StylusPointCollection(pointList);
|
|
|
|
|
stroke = new Stroke(point)
|
2025-08-03 16:46:33 +08:00
|
|
|
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
2025-05-25 09:29:48 +08:00
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
point = new StylusPointCollection(pointList2);
|
|
|
|
|
stroke = new Stroke(point)
|
2025-08-03 16:46:33 +08:00
|
|
|
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
2025-05-25 09:29:48 +08:00
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
point = new StylusPointCollection(pointList3);
|
|
|
|
|
stroke = new Stroke(point)
|
2025-08-03 16:46:33 +08:00
|
|
|
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
2025-05-25 09:29:48 +08:00
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
point = new StylusPointCollection(pointList4);
|
|
|
|
|
stroke = new Stroke(point)
|
2025-08-03 16:46:33 +08:00
|
|
|
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
2025-05-25 09:29:48 +08:00
|
|
|
strokes.Add(stroke.Clone());
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawingShapeMode == 25)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
//画焦点
|
|
|
|
|
c = Math.Sqrt(a * a + b * b);
|
|
|
|
|
stylusPoint = isHyperbolaFocalPointOnXAxis
|
|
|
|
|
? new StylusPoint(iniP.X + c, iniP.Y, (float)1.0)
|
|
|
|
|
: new StylusPoint(iniP.X, iniP.Y + c, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
|
|
|
|
stroke = new Stroke(point)
|
2025-12-20 13:56:46 +08:00
|
|
|
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
2025-05-25 09:29:48 +08:00
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
stylusPoint = isHyperbolaFocalPointOnXAxis
|
|
|
|
|
? new StylusPoint(iniP.X - c, iniP.Y, (float)1.0)
|
|
|
|
|
: new StylusPoint(iniP.X, iniP.Y - c, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
|
|
|
|
stroke = new Stroke(point)
|
2025-12-20 13:56:46 +08:00
|
|
|
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
2025-05-25 09:29:48 +08:00
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
2025-05-25 09:29:48 +08:00
|
|
|
break;
|
|
|
|
|
case 20:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
//抛物线 y=ax^2
|
|
|
|
|
if (Math.Abs(iniP.X - endP.X) < 0.01 || Math.Abs(iniP.Y - endP.Y) < 0.01) return;
|
|
|
|
|
a = (iniP.Y - endP.Y) / ((iniP.X - endP.X) * (iniP.X - endP.X));
|
|
|
|
|
pointList = new List<Point>();
|
|
|
|
|
pointList2 = new List<Point>();
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 0.0; i <= Math.Abs(endP.X - iniP.X); i += 0.5)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
pointList.Add(new Point(iniP.X + i, iniP.Y - a * i * i));
|
|
|
|
|
pointList2.Add(new Point(iniP.X - i, iniP.Y - a * i * i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
point = new StylusPointCollection(pointList2);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 21:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
//抛物线 y^2=ax
|
|
|
|
|
if (Math.Abs(iniP.X - endP.X) < 0.01 || Math.Abs(iniP.Y - endP.Y) < 0.01) return;
|
|
|
|
|
a = (iniP.X - endP.X) / ((iniP.Y - endP.Y) * (iniP.Y - endP.Y));
|
|
|
|
|
pointList = new List<Point>();
|
|
|
|
|
pointList2 = new List<Point>();
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 0.0; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
pointList.Add(new Point(iniP.X - a * i * i, iniP.Y + i));
|
|
|
|
|
pointList2.Add(new Point(iniP.X - a * i * i, iniP.Y - i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
point = new StylusPointCollection(pointList2);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 22:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
//抛物线 y^2=ax, 含焦点
|
|
|
|
|
if (Math.Abs(iniP.X - endP.X) < 0.01 || Math.Abs(iniP.Y - endP.Y) < 0.01) return;
|
|
|
|
|
var p = (iniP.Y - endP.Y) * (iniP.Y - endP.Y) / (2 * (iniP.X - endP.X));
|
|
|
|
|
a = 0.5 / p;
|
|
|
|
|
pointList = new List<Point>();
|
|
|
|
|
pointList2 = new List<Point>();
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 0.0; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
pointList.Add(new Point(iniP.X - a * i * i, iniP.Y + i));
|
|
|
|
|
pointList2.Add(new Point(iniP.X - a * i * i, iniP.Y - i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
point = new StylusPointCollection(pointList2);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
stylusPoint = new StylusPoint(iniP.X - p / 2, iniP.Y, (float)1.0);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
|
|
|
|
newIniP = iniP;
|
2025-08-03 16:46:33 +08:00
|
|
|
if (iniP.Y > endP.Y)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
newIniP = new Point(iniP.X, endP.Y);
|
|
|
|
|
endP = new Point(endP.X, iniP.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var topA = Math.Abs(newIniP.X - endP.X);
|
|
|
|
|
var topB = topA / 2.646;
|
|
|
|
|
//顶部椭圆
|
|
|
|
|
pointList = GenerateEllipseGeometry(new Point(newIniP.X, newIniP.Y - topB / 2),
|
|
|
|
|
new Point(endP.X, newIniP.Y + topB / 2));
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//底部椭圆
|
|
|
|
|
pointList = GenerateEllipseGeometry(new Point(newIniP.X, endP.Y - topB / 2),
|
2025-07-28 14:40:44 +08:00
|
|
|
new Point(endP.X, endP.Y + topB / 2), false);
|
2025-05-25 09:29:48 +08:00
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
strokes.Add(GenerateDashedLineEllipseStrokeCollection(new Point(newIniP.X, endP.Y - topB / 2),
|
|
|
|
|
new Point(endP.X, endP.Y + topB / 2), true, false));
|
|
|
|
|
//左侧
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(newIniP.X, newIniP.Y),
|
|
|
|
|
new Point(newIniP.X, endP.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//右侧
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(endP.X, newIniP.Y),
|
|
|
|
|
new Point(endP.X, endP.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
2025-08-03 16:46:33 +08:00
|
|
|
if (iniP.Y > endP.Y)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
newIniP = new Point(iniP.X, endP.Y);
|
|
|
|
|
endP = new Point(endP.X, iniP.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bottomA = Math.Abs(newIniP.X - endP.X);
|
|
|
|
|
var bottomB = bottomA / 2.646;
|
|
|
|
|
//底部椭圆
|
|
|
|
|
pointList = GenerateEllipseGeometry(new Point(newIniP.X, endP.Y - bottomB / 2),
|
2025-07-28 14:40:44 +08:00
|
|
|
new Point(endP.X, endP.Y + bottomB / 2), false);
|
2025-05-25 09:29:48 +08:00
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
strokes.Add(GenerateDashedLineEllipseStrokeCollection(new Point(newIniP.X, endP.Y - bottomB / 2),
|
|
|
|
|
new Point(endP.X, endP.Y + bottomB / 2), true, false));
|
|
|
|
|
//左侧
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point((newIniP.X + endP.X) / 2, newIniP.Y),
|
|
|
|
|
new Point(newIniP.X, endP.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//右侧
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point((newIniP.X + endP.X) / 2, newIniP.Y),
|
|
|
|
|
new Point(endP.X, endP.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
// 画长方体
|
|
|
|
|
_currentCommitType = CommitReason.ShapeDrawing;
|
2025-08-03 16:46:33 +08:00
|
|
|
if (isFirstTouchCuboid)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
//分开画线条方便后期单独擦除某一条棱
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X, iniP.Y), new Point(iniP.X, endP.Y)));
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X, endP.Y), new Point(endP.X, endP.Y)));
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(endP.X, endP.Y), new Point(endP.X, iniP.Y)));
|
|
|
|
|
strokes.Add(GenerateLineStroke(new Point(iniP.X, iniP.Y), new Point(endP.X, iniP.Y)));
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
CuboidFrontRectIniP = iniP;
|
|
|
|
|
CuboidFrontRectEndP = endP;
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
d = CuboidFrontRectIniP.Y - endP.Y;
|
|
|
|
|
if (d < 0) d = -d; //就是懒不想做反向的,不要让我去做,想做自己做好之后 Pull Request
|
|
|
|
|
a = CuboidFrontRectEndP.X - CuboidFrontRectIniP.X; //正面矩形长
|
|
|
|
|
b = CuboidFrontRectEndP.Y - CuboidFrontRectIniP.Y; //正面矩形宽
|
|
|
|
|
|
|
|
|
|
//横上
|
|
|
|
|
var newLineIniP = new Point(CuboidFrontRectIniP.X + d, CuboidFrontRectIniP.Y - d);
|
|
|
|
|
var newLineEndP = new Point(CuboidFrontRectEndP.X + d, CuboidFrontRectIniP.Y - d);
|
|
|
|
|
pointList = new List<Point> { newLineIniP, newLineEndP };
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
|
|
|
|
stroke = new Stroke(point) { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//横下 (虚线)
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectIniP.X + d, CuboidFrontRectEndP.Y - d);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectEndP.X + d, CuboidFrontRectEndP.Y - d);
|
|
|
|
|
strokes.Add(GenerateDashedLineStrokeCollection(newLineIniP, newLineEndP));
|
|
|
|
|
//斜左上
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectIniP.X, CuboidFrontRectIniP.Y);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectIniP.X + d, CuboidFrontRectIniP.Y - d);
|
|
|
|
|
pointList = new List<Point> { newLineIniP, newLineEndP };
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
|
|
|
|
stroke = new Stroke(point) { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//斜右上
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectEndP.X, CuboidFrontRectIniP.Y);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectEndP.X + d, CuboidFrontRectIniP.Y - d);
|
|
|
|
|
pointList = new List<Point> { newLineIniP, newLineEndP };
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
|
|
|
|
stroke = new Stroke(point) { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//斜左下 (虚线)
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectIniP.X, CuboidFrontRectEndP.Y);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectIniP.X + d, CuboidFrontRectEndP.Y - d);
|
|
|
|
|
strokes.Add(GenerateDashedLineStrokeCollection(newLineIniP, newLineEndP));
|
|
|
|
|
//斜右下
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectEndP.X, CuboidFrontRectEndP.Y);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectEndP.X + d, CuboidFrontRectEndP.Y - d);
|
|
|
|
|
pointList = new List<Point> { newLineIniP, newLineEndP };
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
|
|
|
|
stroke = new Stroke(point) { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
//竖左 (虚线)
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectIniP.X + d, CuboidFrontRectIniP.Y - d);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectIniP.X + d, CuboidFrontRectEndP.Y - d);
|
|
|
|
|
strokes.Add(GenerateDashedLineStrokeCollection(newLineIniP, newLineEndP));
|
|
|
|
|
//竖右
|
|
|
|
|
newLineIniP = new Point(CuboidFrontRectEndP.X + d, CuboidFrontRectIniP.Y - d);
|
|
|
|
|
newLineEndP = new Point(CuboidFrontRectEndP.X + d, CuboidFrontRectEndP.Y - d);
|
|
|
|
|
pointList = new List<Point> { newLineIniP, newLineEndP };
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
|
|
|
|
stroke = new Stroke(point) { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStrokeCollection = strokes;
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
private bool isFirstTouchCuboid = true;
|
2025-07-28 14:40:44 +08:00
|
|
|
private Point CuboidFrontRectIniP;
|
|
|
|
|
private Point CuboidFrontRectEndP;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
2025-07-28 14:40:44 +08:00
|
|
|
private Stroke lastTempStroke;
|
2025-05-25 09:29:48 +08:00
|
|
|
private StrokeCollection lastTempStrokeCollection = new StrokeCollection();
|
|
|
|
|
|
2025-07-28 14:40:44 +08:00
|
|
|
private bool isWaitUntilNextTouchDown;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
2025-09-20 12:35:30 +08:00
|
|
|
// 添加节流机制,减少更新频率
|
|
|
|
|
private DateTime lastUpdateTime = DateTime.MinValue;
|
|
|
|
|
private const int UpdateThrottleMs = 16; // 约60fps的更新频率
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 安全地更新临时笔画,减少预览闪烁
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="newStroke">新的临时笔画</param>
|
|
|
|
|
private void UpdateTempStrokeSafely(Stroke newStroke)
|
|
|
|
|
{
|
|
|
|
|
// 节流机制:限制更新频率
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
if ((now - lastUpdateTime).TotalMilliseconds < UpdateThrottleMs)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
lastUpdateTime = now;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 使用Dispatcher.BeginInvoke确保UI更新在UI线程上执行
|
|
|
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 先添加新笔画,再删除旧笔画,减少视觉闪烁
|
|
|
|
|
inkCanvas.Strokes.Add(newStroke);
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-09-20 12:35:30 +08:00
|
|
|
if (lastTempStroke != null && inkCanvas.Strokes.Contains(lastTempStroke))
|
|
|
|
|
{
|
|
|
|
|
inkCanvas.Strokes.Remove(lastTempStroke);
|
|
|
|
|
}
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-09-20 12:35:30 +08:00
|
|
|
lastTempStroke = newStroke;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine($"UpdateTempStrokeSafely 失败: {ex.Message}");
|
|
|
|
|
// 如果更新失败,确保清理状态
|
|
|
|
|
if (lastTempStroke != null && inkCanvas.Strokes.Contains(lastTempStroke))
|
|
|
|
|
{
|
|
|
|
|
try { inkCanvas.Strokes.Remove(lastTempStroke); } catch { }
|
|
|
|
|
}
|
|
|
|
|
lastTempStroke = newStroke;
|
|
|
|
|
try { inkCanvas.Strokes.Add(newStroke); } catch { }
|
|
|
|
|
}
|
|
|
|
|
}), DispatcherPriority.Render);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine($"UpdateTempStrokeSafely Dispatcher 失败: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 安全地更新临时笔画集合,减少预览闪烁
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="newStrokeCollection">新的临时笔画集合</param>
|
|
|
|
|
private void UpdateTempStrokeCollectionSafely(StrokeCollection newStrokeCollection)
|
|
|
|
|
{
|
|
|
|
|
// 节流机制:限制更新频率
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
if ((now - lastUpdateTime).TotalMilliseconds < UpdateThrottleMs)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
lastUpdateTime = now;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 使用Dispatcher.BeginInvoke确保UI更新在UI线程上执行
|
|
|
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 先添加新笔画集合,再删除旧笔画集合,减少视觉闪烁
|
|
|
|
|
inkCanvas.Strokes.Add(newStrokeCollection);
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-09-20 12:35:30 +08:00
|
|
|
if (lastTempStrokeCollection != null && lastTempStrokeCollection.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var stroke in lastTempStrokeCollection)
|
|
|
|
|
{
|
|
|
|
|
if (inkCanvas.Strokes.Contains(stroke))
|
|
|
|
|
{
|
|
|
|
|
inkCanvas.Strokes.Remove(stroke);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-03 17:08:46 +08:00
|
|
|
|
2025-09-20 12:35:30 +08:00
|
|
|
lastTempStrokeCollection = newStrokeCollection;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine($"UpdateTempStrokeCollectionSafely 失败: {ex.Message}");
|
|
|
|
|
// 如果更新失败,确保清理状态
|
|
|
|
|
if (lastTempStrokeCollection != null && lastTempStrokeCollection.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var stroke in lastTempStrokeCollection)
|
|
|
|
|
{
|
|
|
|
|
try { inkCanvas.Strokes.Remove(stroke); } catch { }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lastTempStrokeCollection = newStrokeCollection;
|
|
|
|
|
try { inkCanvas.Strokes.Add(newStrokeCollection); } catch { }
|
|
|
|
|
}
|
|
|
|
|
}), DispatcherPriority.Render);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine($"UpdateTempStrokeCollectionSafely Dispatcher 失败: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
private List<Point> GenerateEllipseGeometry(Point st, Point ed, bool isDrawTop = true,
|
2025-08-03 16:46:33 +08:00
|
|
|
bool isDrawBottom = true)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var a = 0.5 * (ed.X - st.X);
|
|
|
|
|
var b = 0.5 * (ed.Y - st.Y);
|
|
|
|
|
var pointList = new List<Point>();
|
2025-08-03 16:46:33 +08:00
|
|
|
if (isDrawTop && isDrawBottom)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
for (double r = 0; r <= 2 * Math.PI; r = r + 0.01)
|
|
|
|
|
pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r),
|
|
|
|
|
0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
|
|
|
|
|
}
|
2025-08-03 16:46:33 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (isDrawBottom)
|
|
|
|
|
for (double r = 0; r <= Math.PI; r = r + 0.01)
|
|
|
|
|
pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r),
|
|
|
|
|
0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
|
|
|
|
|
if (isDrawTop)
|
|
|
|
|
for (var r = Math.PI; r <= 2 * Math.PI; r = r + 0.01)
|
|
|
|
|
pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r),
|
|
|
|
|
0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pointList;
|
|
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
private StrokeCollection GenerateDashedLineEllipseStrokeCollection(Point st, Point ed, bool isDrawTop = true,
|
2025-08-03 16:46:33 +08:00
|
|
|
bool isDrawBottom = true)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var a = 0.5 * (ed.X - st.X);
|
|
|
|
|
var b = 0.5 * (ed.Y - st.Y);
|
|
|
|
|
var step = 0.05;
|
|
|
|
|
var pointList = new List<Point>();
|
|
|
|
|
StylusPointCollection point;
|
|
|
|
|
Stroke stroke;
|
|
|
|
|
var strokes = new StrokeCollection();
|
|
|
|
|
if (isDrawBottom)
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 0.0; i < 1.0; i += step * 1.66)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
pointList = new List<Point>();
|
|
|
|
|
for (var r = Math.PI * i; r <= Math.PI * (i + step); r = r + 0.01)
|
|
|
|
|
pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r),
|
|
|
|
|
0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isDrawTop)
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 1.0; i < 2.0; i += step * 1.66)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
pointList = new List<Point>();
|
|
|
|
|
for (var r = Math.PI * i; r <= Math.PI * (i + step); r = r + 0.01)
|
|
|
|
|
pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r),
|
|
|
|
|
0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return strokes;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private Stroke GenerateLineStroke(Point st, Point ed)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var pointList = new List<Point>();
|
|
|
|
|
StylusPointCollection point;
|
|
|
|
|
Stroke stroke;
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(st.X, st.Y),
|
|
|
|
|
new Point(ed.X, ed.Y)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
return stroke;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private Stroke GenerateArrowLineStroke(Point st, Point ed)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var pointList = new List<Point>();
|
|
|
|
|
StylusPointCollection point;
|
|
|
|
|
Stroke stroke;
|
|
|
|
|
|
|
|
|
|
double w = 20, h = 7;
|
|
|
|
|
var theta = Math.Atan2(st.Y - ed.Y, st.X - ed.X);
|
|
|
|
|
var sint = Math.Sin(theta);
|
|
|
|
|
var cost = Math.Cos(theta);
|
|
|
|
|
|
|
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(st.X, st.Y),
|
|
|
|
|
new Point(ed.X, ed.Y),
|
|
|
|
|
new Point(ed.X + (w * cost - h * sint), ed.Y + (w * sint + h * cost)),
|
|
|
|
|
new Point(ed.X, ed.Y),
|
|
|
|
|
new Point(ed.X + (w * cost + h * sint), ed.Y - (h * cost - w * sint))
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
return stroke;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private StrokeCollection GenerateDashedLineStrokeCollection(Point st, Point ed)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
double step = 5;
|
|
|
|
|
var pointList = new List<Point>();
|
|
|
|
|
StylusPointCollection point;
|
|
|
|
|
Stroke stroke;
|
|
|
|
|
var strokes = new StrokeCollection();
|
|
|
|
|
var d = GetDistance(st, ed);
|
|
|
|
|
var sinTheta = (ed.Y - st.Y) / d;
|
|
|
|
|
var cosTheta = (ed.X - st.X) / d;
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 0.0; i < d; i += step * 2.76)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
pointList = new List<Point> {
|
|
|
|
|
new Point(st.X + i * cosTheta, st.Y + i * sinTheta),
|
|
|
|
|
new Point(st.X + Math.Min(i + step, d) * cosTheta, st.Y + Math.Min(i + step, d) * sinTheta)
|
|
|
|
|
};
|
|
|
|
|
point = new StylusPointCollection(pointList);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return strokes;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private StrokeCollection GenerateDotLineStrokeCollection(Point st, Point ed)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
double step = 3;
|
|
|
|
|
var pointList = new List<Point>();
|
|
|
|
|
StylusPointCollection point;
|
|
|
|
|
Stroke stroke;
|
|
|
|
|
var strokes = new StrokeCollection();
|
|
|
|
|
var d = GetDistance(st, ed);
|
|
|
|
|
var sinTheta = (ed.Y - st.Y) / d;
|
|
|
|
|
var cosTheta = (ed.X - st.X) / d;
|
2025-08-03 16:46:33 +08:00
|
|
|
for (var i = 0.0; i < d; i += step * 2.76)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var stylusPoint = new StylusPoint(st.X + i * cosTheta, st.Y + i * sinTheta, (float)0.8);
|
|
|
|
|
point = new StylusPointCollection();
|
|
|
|
|
point.Add(stylusPoint);
|
2025-08-03 16:46:33 +08:00
|
|
|
stroke = new Stroke(point)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
strokes.Add(stroke.Clone());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return strokes;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-28 14:40:44 +08:00
|
|
|
private bool isMouseDown;
|
2025-10-01 13:03:11 +08:00
|
|
|
private bool isTouchDown;
|
2025-05-25 09:29:48 +08:00
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private void inkCanvas_MouseDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-08-30 18:10:55 +08:00
|
|
|
// 检查鼠标点击是否发生在浮动栏区域,如果是则允许事件传播到浮动栏按钮
|
|
|
|
|
var mousePoint = e.GetPosition(this);
|
|
|
|
|
var floatingBarBounds = ViewboxFloatingBar.TransformToAncestor(this).TransformBounds(
|
|
|
|
|
new Rect(0, 0, ViewboxFloatingBar.ActualWidth, ViewboxFloatingBar.ActualHeight));
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-08-30 18:10:55 +08:00
|
|
|
// 如果鼠标点击发生在浮动栏区域,不阻止事件传播,让浮动栏按钮能够接收鼠标事件
|
|
|
|
|
if (floatingBarBounds.Contains(mousePoint))
|
|
|
|
|
{
|
|
|
|
|
// 不设置 ViewboxFloatingBar.IsHitTestVisible = false,让浮动栏按钮能够接收鼠标事件
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.CaptureMouse();
|
|
|
|
|
ViewboxFloatingBar.IsHitTestVisible = false;
|
|
|
|
|
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
|
|
|
|
|
|
|
|
|
|
isMouseDown = true;
|
|
|
|
|
if (NeedUpdateIniP()) iniP = e.GetPosition(inkCanvas);
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private void inkCanvas_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (isMouseDown) MouseTouchMove(e.GetPosition(inkCanvas));
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private void inkCanvas_MouseUp(object sender, MouseButtonEventArgs e)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
inkCanvas.ReleaseMouseCapture();
|
|
|
|
|
ViewboxFloatingBar.IsHitTestVisible = true;
|
|
|
|
|
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawingShapeMode == 5)
|
|
|
|
|
{
|
|
|
|
|
if (lastTempStroke != null)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var circle = new Circle(new Point(), 0, lastTempStroke);
|
|
|
|
|
circle.R = GetDistance(circle.Stroke.StylusPoints[0].ToPoint(),
|
|
|
|
|
circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].ToPoint()) / 2;
|
|
|
|
|
circle.Centroid = new Point(
|
|
|
|
|
(circle.Stroke.StylusPoints[0].X +
|
|
|
|
|
circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].X) / 2,
|
|
|
|
|
(circle.Stroke.StylusPoints[0].Y +
|
|
|
|
|
circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].Y) / 2);
|
|
|
|
|
circles.Add(circle);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastIsInMultiTouchMode)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
ToggleSwitchEnableMultiTouchMode.IsOn = true;
|
2025-05-25 09:29:48 +08:00
|
|
|
lastIsInMultiTouchMode = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawingShapeMode != 9 && drawingShapeMode != 0 && drawingShapeMode != 24 && drawingShapeMode != 25)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
if (isLongPressSelected) { }
|
2025-12-20 13:56:46 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
BtnPen_Click(null, null); //画完一次还原到笔模式
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastIsInMultiTouchMode)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
ToggleSwitchEnableMultiTouchMode.IsOn = true;
|
2025-05-25 09:29:48 +08:00
|
|
|
lastIsInMultiTouchMode = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawingShapeMode == 9)
|
|
|
|
|
{
|
|
|
|
|
if (isFirstTouchCuboid)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (CuboidStrokeCollection == null) CuboidStrokeCollection = new StrokeCollection();
|
|
|
|
|
isFirstTouchCuboid = false;
|
|
|
|
|
var newIniP = new Point(Math.Min(CuboidFrontRectIniP.X, CuboidFrontRectEndP.X),
|
|
|
|
|
Math.Min(CuboidFrontRectIniP.Y, CuboidFrontRectEndP.Y));
|
|
|
|
|
var newEndP = new Point(Math.Max(CuboidFrontRectIniP.X, CuboidFrontRectEndP.X),
|
|
|
|
|
Math.Max(CuboidFrontRectIniP.Y, CuboidFrontRectEndP.Y));
|
|
|
|
|
CuboidFrontRectIniP = newIniP;
|
|
|
|
|
CuboidFrontRectEndP = newEndP;
|
2025-12-20 13:56:46 +08:00
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
CuboidStrokeCollection.Add(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
BtnPen_Click(null, null); //画完还原到笔模式
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastIsInMultiTouchMode)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
ToggleSwitchEnableMultiTouchMode.IsOn = true;
|
2025-05-25 09:29:48 +08:00
|
|
|
lastIsInMultiTouchMode = false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
if (_currentCommitType == CommitReason.ShapeDrawing)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
CuboidStrokeCollection.Add(lastTempStrokeCollection);
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
catch
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
timeMachine.CommitStrokeUserInputHistory(CuboidStrokeCollection);
|
|
|
|
|
CuboidStrokeCollection = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawingShapeMode == 24 || drawingShapeMode == 25)
|
|
|
|
|
{
|
|
|
|
|
if (drawMultiStepShapeCurrentStep == 0)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
drawMultiStepShapeCurrentStep = 1;
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
else
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
drawMultiStepShapeCurrentStep = 0;
|
2025-12-20 13:56:46 +08:00
|
|
|
if (drawMultiStepShapeSpecialStrokeCollection != null)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
var opFlag = false;
|
2025-12-20 13:56:46 +08:00
|
|
|
switch (Settings.Canvas.HyperbolaAsymptoteOption)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
case OptionalOperation.Yes:
|
|
|
|
|
opFlag = true;
|
|
|
|
|
break;
|
|
|
|
|
case OptionalOperation.No:
|
|
|
|
|
opFlag = false;
|
|
|
|
|
break;
|
|
|
|
|
case OptionalOperation.Ask:
|
|
|
|
|
opFlag = MessageBox.Show("是否移除渐近线?", "Ink Canvas", MessageBoxButton.YesNo) !=
|
|
|
|
|
MessageBoxResult.Yes;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
if (!opFlag) inkCanvas.Strokes.Remove(drawMultiStepShapeSpecialStrokeCollection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BtnPen_Click(null, null); //画完还原到笔模式
|
2025-12-20 13:56:46 +08:00
|
|
|
if (lastIsInMultiTouchMode)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
ToggleSwitchEnableMultiTouchMode.IsOn = true;
|
2025-05-25 09:29:48 +08:00
|
|
|
lastIsInMultiTouchMode = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isMouseDown = false;
|
2025-08-03 16:46:33 +08:00
|
|
|
if (ReplacedStroke != null || AddedStroke != null)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
timeMachine.CommitStrokeEraseHistory(ReplacedStroke, AddedStroke);
|
|
|
|
|
AddedStroke = null;
|
|
|
|
|
ReplacedStroke = null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
if (_currentCommitType == CommitReason.ShapeDrawing && drawingShapeMode != 9)
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
StrokeCollection collection = null;
|
|
|
|
|
if (lastTempStrokeCollection != null && lastTempStrokeCollection.Count > 0)
|
|
|
|
|
collection = lastTempStrokeCollection;
|
2025-07-28 14:40:44 +08:00
|
|
|
else if (lastTempStroke != null) collection = new StrokeCollection { lastTempStroke };
|
2025-05-25 09:29:48 +08:00
|
|
|
if (collection != null) timeMachine.CommitStrokeUserInputHistory(collection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastTempStroke = null;
|
|
|
|
|
lastTempStrokeCollection = null;
|
|
|
|
|
|
|
|
|
|
if (StrokeManipulationHistory?.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
timeMachine.CommitStrokeManipulationHistory(StrokeManipulationHistory);
|
|
|
|
|
foreach (var item in StrokeManipulationHistory)
|
|
|
|
|
{
|
|
|
|
|
StrokeInitialHistory[item.Key] = item.Value.Item2;
|
|
|
|
|
}
|
|
|
|
|
StrokeManipulationHistory = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-30 11:51:19 +08:00
|
|
|
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = true;
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
|
|
|
|
|
2025-08-03 16:46:33 +08:00
|
|
|
private bool NeedUpdateIniP()
|
|
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (drawingShapeMode == 24 || drawingShapeMode == 25)
|
2025-08-10 12:20:51 +08:00
|
|
|
{
|
2025-05-25 09:29:48 +08:00
|
|
|
if (drawMultiStepShapeCurrentStep == 1)
|
2025-08-10 12:20:51 +08:00
|
|
|
return false; // 第二笔不更新起点
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
return true;
|
|
|
|
|
}
|
2025-08-12 15:45:33 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 绘制圆心标记
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="centerPoint">圆心位置</param>
|
|
|
|
|
private void DrawCircleCenter(Point centerPoint)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 创建一个点作为圆心标记
|
|
|
|
|
var centerSize = 0.5; // 圆心标记的大小
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-08-12 15:45:33 +08:00
|
|
|
// 创建一个小圆作为圆心标记
|
|
|
|
|
var circlePoints = new List<Point>();
|
|
|
|
|
for (double angle = 0; angle <= 2 * Math.PI; angle += 0.1)
|
|
|
|
|
{
|
|
|
|
|
circlePoints.Add(new Point(
|
|
|
|
|
centerPoint.X + centerSize * Math.Cos(angle),
|
|
|
|
|
centerPoint.Y + centerSize * Math.Sin(angle)
|
|
|
|
|
));
|
|
|
|
|
}
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-08-12 15:45:33 +08:00
|
|
|
// 绘制圆心点
|
|
|
|
|
var point = new StylusPointCollection(circlePoints);
|
|
|
|
|
var stroke = new Stroke(point)
|
|
|
|
|
{
|
|
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-08-12 15:45:33 +08:00
|
|
|
// 设置圆心点的样式
|
|
|
|
|
stroke.DrawingAttributes.Width = 2.0;
|
|
|
|
|
stroke.DrawingAttributes.Height = 2.0;
|
2025-08-31 11:43:52 +08:00
|
|
|
|
2025-08-12 15:45:33 +08:00
|
|
|
// 添加到画布
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine($"绘制圆心标记失败: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-20 13:56:46 +08:00
|
|
|
private void MainWindow_OnMouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.StylusDevice == null)
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
System.Windows.Forms.Cursor.Show();
|
2025-12-20 13:56:46 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-11-30 11:51:19 +08:00
|
|
|
System.Windows.Forms.Cursor.Hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-25 09:29:48 +08:00
|
|
|
}
|
2025-10-31 12:18:45 +08:00
|
|
|
}
|