2024-05-01 18:23:32 +08:00
|
|
|
|
using Ink_Canvas.Helpers;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Windows;
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
using System.Windows.Ink;
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
using Point = System.Windows.Point;
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
namespace Ink_Canvas
|
|
|
|
|
{
|
|
|
|
|
public partial class MainWindow : Window
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
StrokeCollection newStrokes = new StrokeCollection();
|
|
|
|
|
List<Circle> circles = new List<Circle>();
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (Settings.Canvas.FitToCurve == true)
|
2024-05-04 01:01:16 +08:00
|
|
|
|
{
|
|
|
|
|
drawingAttributes.FitToCurve = false;
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
inkCanvas.Opacity = 1;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess)
|
|
|
|
|
{
|
|
|
|
|
void InkToShapeProcess()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
newStrokes.Add(e.Stroke);
|
|
|
|
|
if (newStrokes.Count > 4) newStrokes.RemoveAt(0);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
for (int i = 0; i < newStrokes.Count; i++)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
if (!inkCanvas.Strokes.Contains(newStrokes[i])) newStrokes.RemoveAt(i--);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < circles.Count; i++)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
if (!inkCanvas.Strokes.Contains(circles[i].Stroke)) circles.RemoveAt(i);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var strokeReco = new StrokeCollection();
|
|
|
|
|
var result = InkRecognizeHelper.RecognizeShape(newStrokes);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
for (int i = newStrokes.Count - 1; i >= 0; i--)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
strokeReco.Add(newStrokes[i]);
|
|
|
|
|
var newResult = InkRecognizeHelper.RecognizeShape(strokeReco);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (newResult.InkDrawingNode.GetShapeName() == "Circle" ||
|
|
|
|
|
newResult.InkDrawingNode.GetShapeName() == "Ellipse")
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
result = newResult;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//Label.Visibility = Visibility.Visible;
|
|
|
|
|
//Label.Content = circles.Count.ToString() + "\n" + newResult.InkDrawingNode.GetShapeName();
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
|
|
|
|
if (result.InkDrawingNode.GetShapeName() == "Circle" &&
|
|
|
|
|
Settings.InkToShape.IsInkToShapeRounded == true)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var shape = result.InkDrawingNode.GetShape();
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (shape.Width > 75)
|
|
|
|
|
{
|
|
|
|
|
foreach (Circle circle in circles)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//判断是否画同心圆
|
|
|
|
|
if (Math.Abs(result.Centroid.X - circle.Centroid.X) / shape.Width < 0.12 &&
|
2024-05-23 02:38:44 +08:00
|
|
|
|
Math.Abs(result.Centroid.Y - circle.Centroid.Y) / shape.Width < 0.12)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
result.Centroid = circle.Centroid;
|
|
|
|
|
break;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
double d = (result.Centroid.X - circle.Centroid.X) *
|
|
|
|
|
(result.Centroid.X - circle.Centroid.X) +
|
|
|
|
|
(result.Centroid.Y - circle.Centroid.Y) *
|
|
|
|
|
(result.Centroid.Y - circle.Centroid.Y);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
d = Math.Sqrt(d);
|
|
|
|
|
//判断是否画外切圆
|
|
|
|
|
double x = shape.Width / 2.0 + circle.R - d;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (Math.Abs(x) / shape.Width < 0.1)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
double sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d;
|
|
|
|
|
double cosTheta = (result.Centroid.X - circle.Centroid.X) / d;
|
|
|
|
|
double newX = result.Centroid.X + x * cosTheta;
|
|
|
|
|
double newY = result.Centroid.Y + x * sinTheta;
|
|
|
|
|
result.Centroid = new Point(newX, newY);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//判断是否画外切圆
|
|
|
|
|
x = Math.Abs(circle.R - shape.Width / 2.0) - d;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (Math.Abs(x) / shape.Width < 0.1)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
double sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d;
|
|
|
|
|
double cosTheta = (result.Centroid.X - circle.Centroid.X) / d;
|
|
|
|
|
double newX = result.Centroid.X + x * cosTheta;
|
|
|
|
|
double newY = result.Centroid.Y + x * sinTheta;
|
|
|
|
|
result.Centroid = new Point(newX, newY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
Point iniP = new Point(result.Centroid.X - shape.Width / 2,
|
|
|
|
|
result.Centroid.Y - shape.Height / 2);
|
|
|
|
|
Point endP = new Point(result.Centroid.X + shape.Width / 2,
|
|
|
|
|
result.Centroid.Y + shape.Height / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var pointList = GenerateEllipseGeometry(iniP, endP);
|
|
|
|
|
var point = new StylusPointCollection(pointList);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
var stroke = new Stroke(point)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
circles.Add(new Circle(result.Centroid, shape.Width / 2.0, stroke));
|
|
|
|
|
SetNewBackupOfStroke();
|
|
|
|
|
_currentCommitType = CommitReason.ShapeRecognition;
|
|
|
|
|
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
newStrokes = new StrokeCollection();
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if (result.InkDrawingNode.GetShapeName().Contains("Ellipse") &&
|
|
|
|
|
Settings.InkToShape.IsInkToShapeRounded == true)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var shape = result.InkDrawingNode.GetShape();
|
|
|
|
|
//var shape1 = result.InkDrawingNode.GetShape();
|
|
|
|
|
//shape1.Fill = Brushes.Gray;
|
|
|
|
|
//Canvas.Children.Add(shape1);
|
|
|
|
|
var p = result.InkDrawingNode.HotPoints;
|
|
|
|
|
double a = GetDistance(p[0], p[2]) / 2; //长半轴
|
|
|
|
|
double b = GetDistance(p[1], p[3]) / 2; //短半轴
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (a < b)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
double t = a;
|
|
|
|
|
a = b;
|
|
|
|
|
b = t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.Centroid = new Point((p[0].X + p[2].X) / 2, (p[0].Y + p[2].Y) / 2);
|
|
|
|
|
bool needRotation = true;
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (shape.Width > 75 || shape.Height > 75 && p.Count == 4)
|
|
|
|
|
{
|
|
|
|
|
Point iniP = new Point(result.Centroid.X - shape.Width / 2,
|
|
|
|
|
result.Centroid.Y - shape.Height / 2);
|
|
|
|
|
Point endP = new Point(result.Centroid.X + shape.Width / 2,
|
|
|
|
|
result.Centroid.Y + shape.Height / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
foreach (Circle circle in circles)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//判断是否画同心椭圆
|
|
|
|
|
if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2 &&
|
2024-05-23 02:38:44 +08:00
|
|
|
|
Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
result.Centroid = circle.Centroid;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
iniP = new Point(result.Centroid.X - shape.Width / 2,
|
|
|
|
|
result.Centroid.Y - shape.Height / 2);
|
|
|
|
|
endP = new Point(result.Centroid.X + shape.Width / 2,
|
|
|
|
|
result.Centroid.Y + shape.Height / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
//再判断是否与圆相切
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (Math.Abs(a - circle.R) / a < 0.2)
|
|
|
|
|
{
|
|
|
|
|
if (shape.Width >= shape.Height)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
iniP.X = result.Centroid.X - circle.R;
|
|
|
|
|
endP.X = result.Centroid.X + circle.R;
|
|
|
|
|
iniP.Y = result.Centroid.Y - b;
|
|
|
|
|
endP.Y = result.Centroid.Y + b;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
iniP.Y = result.Centroid.Y - circle.R;
|
|
|
|
|
endP.Y = result.Centroid.Y + circle.R;
|
|
|
|
|
iniP.X = result.Centroid.X - a;
|
|
|
|
|
endP.X = result.Centroid.X + a;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
break;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2)
|
|
|
|
|
{
|
|
|
|
|
double sinTheta = Math.Abs(circle.Centroid.Y - result.Centroid.Y) /
|
|
|
|
|
circle.R;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
double cosTheta = Math.Sqrt(1 - sinTheta * sinTheta);
|
|
|
|
|
double newA = circle.R * cosTheta;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 &&
|
|
|
|
|
Math.Abs(newA - a) / newA < 0.3)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
iniP.X = circle.Centroid.X - newA;
|
|
|
|
|
endP.X = circle.Centroid.X + newA;
|
|
|
|
|
iniP.Y = result.Centroid.Y - newA / 5;
|
|
|
|
|
endP.Y = result.Centroid.Y + newA / 5;
|
|
|
|
|
|
|
|
|
|
double topB = endP.Y - iniP.Y;
|
|
|
|
|
|
|
|
|
|
SetNewBackupOfStroke();
|
|
|
|
|
_currentCommitType = CommitReason.ShapeRecognition;
|
|
|
|
|
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
|
|
|
|
|
newStrokes = new StrokeCollection();
|
|
|
|
|
|
|
|
|
|
var _pointList = GenerateEllipseGeometry(iniP, endP, false, true);
|
|
|
|
|
var _point = new StylusPointCollection(_pointList);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
var _stroke = new Stroke(_point)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
2024-05-23 02:38:44 +08:00
|
|
|
|
var _dashedLineStroke =
|
|
|
|
|
GenerateDashedLineEllipseStrokeCollection(iniP, endP, true, false);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
StrokeCollection strokes = new StrokeCollection()
|
|
|
|
|
{
|
|
|
|
|
_stroke,
|
|
|
|
|
_dashedLineStroke
|
|
|
|
|
};
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if (Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2)
|
|
|
|
|
{
|
|
|
|
|
double cosTheta = Math.Abs(circle.Centroid.X - result.Centroid.X) /
|
|
|
|
|
circle.R;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
double sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);
|
|
|
|
|
double newA = circle.R * sinTheta;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 &&
|
|
|
|
|
Math.Abs(newA - a) / newA < 0.3)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
iniP.X = result.Centroid.X - newA / 5;
|
|
|
|
|
endP.X = result.Centroid.X + newA / 5;
|
|
|
|
|
iniP.Y = circle.Centroid.Y - newA;
|
|
|
|
|
endP.Y = circle.Centroid.Y + newA;
|
|
|
|
|
needRotation = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//纠正垂直与水平关系
|
|
|
|
|
var newPoints = FixPointsDirection(p[0], p[2]);
|
|
|
|
|
p[0] = newPoints[0];
|
|
|
|
|
p[2] = newPoints[1];
|
|
|
|
|
newPoints = FixPointsDirection(p[1], p[3]);
|
|
|
|
|
p[1] = newPoints[0];
|
|
|
|
|
p[3] = newPoints[1];
|
|
|
|
|
|
|
|
|
|
var pointList = GenerateEllipseGeometry(iniP, endP);
|
|
|
|
|
var point = new StylusPointCollection(pointList);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
var stroke = new Stroke(point)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (needRotation)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
Matrix m = new Matrix();
|
|
|
|
|
FrameworkElement fe = e.Source as FrameworkElement;
|
|
|
|
|
double tanTheta = (p[2].Y - p[0].Y) / (p[2].X - p[0].X);
|
|
|
|
|
double theta = Math.Atan(tanTheta);
|
|
|
|
|
m.RotateAt(theta * 180.0 / Math.PI, result.Centroid.X, result.Centroid.Y);
|
|
|
|
|
stroke.Transform(m, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetNewBackupOfStroke();
|
|
|
|
|
_currentCommitType = CommitReason.ShapeRecognition;
|
|
|
|
|
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
|
|
|
|
|
newStrokes = new StrokeCollection();
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if (result.InkDrawingNode.GetShapeName().Contains("Triangle") &&
|
|
|
|
|
Settings.InkToShape.IsInkToShapeTriangle == true)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var shape = result.InkDrawingNode.GetShape();
|
|
|
|
|
var p = result.InkDrawingNode.HotPoints;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if ((Math.Max(Math.Max(p[0].X, p[1].X), p[2].X) -
|
|
|
|
|
Math.Min(Math.Min(p[0].X, p[1].X), p[2].X) >= 100 ||
|
|
|
|
|
Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y) -
|
|
|
|
|
Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y) >= 100) &&
|
|
|
|
|
result.InkDrawingNode.HotPoints.Count == 3)
|
2024-05-11 20:57:09 +08:00
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//纠正垂直与水平关系
|
|
|
|
|
var newPoints = FixPointsDirection(p[0], p[1]);
|
|
|
|
|
p[0] = newPoints[0];
|
|
|
|
|
p[1] = newPoints[1];
|
|
|
|
|
newPoints = FixPointsDirection(p[0], p[2]);
|
|
|
|
|
p[0] = newPoints[0];
|
|
|
|
|
p[2] = newPoints[1];
|
|
|
|
|
newPoints = FixPointsDirection(p[1], p[2]);
|
|
|
|
|
p[1] = newPoints[0];
|
|
|
|
|
p[2] = newPoints[1];
|
|
|
|
|
|
|
|
|
|
var pointList = p.ToList();
|
|
|
|
|
//pointList.Add(p[0]);
|
|
|
|
|
var point = new StylusPointCollection(pointList);
|
2024-05-11 20:57:09 +08:00
|
|
|
|
var stroke = new Stroke(GenerateFakePressureTriangle(point))
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
SetNewBackupOfStroke();
|
|
|
|
|
_currentCommitType = CommitReason.ShapeRecognition;
|
|
|
|
|
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
|
|
|
|
|
newStrokes = new StrokeCollection();
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if ((result.InkDrawingNode.GetShapeName().Contains("Rectangle") ||
|
|
|
|
|
result.InkDrawingNode.GetShapeName().Contains("Diamond") ||
|
|
|
|
|
result.InkDrawingNode.GetShapeName().Contains("Parallelogram") ||
|
2024-06-04 21:21:08 +08:00
|
|
|
|
result.InkDrawingNode.GetShapeName().Contains("Square") ||
|
|
|
|
|
result.InkDrawingNode.GetShapeName().Contains("Trapezoid")) &&
|
2024-05-23 02:38:44 +08:00
|
|
|
|
Settings.InkToShape.IsInkToShapeRectangle == true)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var shape = result.InkDrawingNode.GetShape();
|
|
|
|
|
var p = result.InkDrawingNode.HotPoints;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if ((Math.Max(Math.Max(Math.Max(p[0].X, p[1].X), p[2].X), p[3].X) -
|
|
|
|
|
Math.Min(Math.Min(Math.Min(p[0].X, p[1].X), p[2].X), p[3].X) >= 100 ||
|
|
|
|
|
Math.Max(Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y), p[3].Y) -
|
|
|
|
|
Math.Min(Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y), p[3].Y) >= 100) &&
|
|
|
|
|
result.InkDrawingNode.HotPoints.Count == 4)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//纠正垂直与水平关系
|
|
|
|
|
var newPoints = FixPointsDirection(p[0], p[1]);
|
|
|
|
|
p[0] = newPoints[0];
|
|
|
|
|
p[1] = newPoints[1];
|
|
|
|
|
newPoints = FixPointsDirection(p[1], p[2]);
|
|
|
|
|
p[1] = newPoints[0];
|
|
|
|
|
p[2] = newPoints[1];
|
|
|
|
|
newPoints = FixPointsDirection(p[2], p[3]);
|
|
|
|
|
p[2] = newPoints[0];
|
|
|
|
|
p[3] = newPoints[1];
|
|
|
|
|
newPoints = FixPointsDirection(p[3], p[0]);
|
|
|
|
|
p[3] = newPoints[0];
|
|
|
|
|
p[0] = newPoints[1];
|
|
|
|
|
|
|
|
|
|
var pointList = p.ToList();
|
|
|
|
|
pointList.Add(p[0]);
|
|
|
|
|
var point = new StylusPointCollection(pointList);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
var stroke = new Stroke(GenerateFakePressureRectangle(point))
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
|
|
|
|
|
};
|
|
|
|
|
SetNewBackupOfStroke();
|
|
|
|
|
_currentCommitType = CommitReason.ShapeRecognition;
|
|
|
|
|
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
|
|
|
|
|
inkCanvas.Strokes.Add(stroke);
|
|
|
|
|
_currentCommitType = CommitReason.UserInput;
|
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
|
|
|
|
|
newStrokes = new StrokeCollection();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
InkToShapeProcess();
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
foreach (StylusPoint stylusPoint in e.Stroke.StylusPoints)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//LogHelper.WriteLogToFile(stylusPoint.PressureFactor.ToString(), LogHelper.LogType.Info);
|
|
|
|
|
// 检查是否是压感笔书写
|
|
|
|
|
//if (stylusPoint.PressureFactor != 0.5 && stylusPoint.PressureFactor != 0)
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if ((stylusPoint.PressureFactor > 0.501 || stylusPoint.PressureFactor < 0.5) &&
|
|
|
|
|
stylusPoint.PressureFactor != 0)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (e.Stroke.StylusPoints.Count > 3)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
Random random = new Random();
|
2024-05-23 02:38:44 +08:00
|
|
|
|
double _speed = GetPointSpeed(
|
|
|
|
|
e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(),
|
|
|
|
|
e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(),
|
|
|
|
|
e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint());
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
RandWindow.randSeed = (int)(_speed * 100000 * 1000);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
switch (Settings.Canvas.InkStyle)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
case 1:
|
2024-05-12 14:23:50 +08:00
|
|
|
|
if (penType == 0)
|
|
|
|
|
{
|
2024-05-23 02:38:44 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
StylusPointCollection stylusPoints = new StylusPointCollection();
|
|
|
|
|
int n = e.Stroke.StylusPoints.Count - 1;
|
|
|
|
|
string s = "";
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
for (int i = 0; i <= n; i++)
|
|
|
|
|
{
|
|
|
|
|
double speed = GetPointSpeed(e.Stroke.StylusPoints[Math.Max(i - 1, 0)].ToPoint(),
|
|
|
|
|
e.Stroke.StylusPoints[i].ToPoint(),
|
|
|
|
|
e.Stroke.StylusPoints[Math.Min(i + 1, n)].ToPoint());
|
2024-05-12 14:23:50 +08:00
|
|
|
|
s += speed.ToString() + "\t";
|
2024-05-01 18:23:32 +08:00
|
|
|
|
StylusPoint point = new StylusPoint();
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (speed >= 0.25)
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
point.PressureFactor = (float)(0.5 - 0.3 * (Math.Min(speed, 1.5) - 0.3) / 1.2);
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if (speed >= 0.05)
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
point.PressureFactor = (float)0.5;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
point.PressureFactor = (float)(0.5 + 0.4 * (0.05 - speed) / 0.05);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
point.X = e.Stroke.StylusPoints[i].X;
|
|
|
|
|
point.Y = e.Stroke.StylusPoints[i].Y;
|
|
|
|
|
stylusPoints.Add(point);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
e.Stroke.StylusPoints = stylusPoints;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-12 14:23:50 +08:00
|
|
|
|
break;
|
|
|
|
|
case 0:
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (penType == 0)
|
2024-05-12 14:23:50 +08:00
|
|
|
|
{
|
2024-05-23 02:38:44 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
StylusPointCollection stylusPoints = new StylusPointCollection();
|
|
|
|
|
int n = e.Stroke.StylusPoints.Count - 1;
|
|
|
|
|
double pressure = 0.1;
|
|
|
|
|
int x = 10;
|
|
|
|
|
if (n == 1) return;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (n >= x)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < n - x; i++)
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
StylusPoint point = new StylusPoint();
|
|
|
|
|
|
|
|
|
|
point.PressureFactor = (float)0.5;
|
|
|
|
|
point.X = e.Stroke.StylusPoints[i].X;
|
|
|
|
|
point.Y = e.Stroke.StylusPoints[i].Y;
|
|
|
|
|
stylusPoints.Add(point);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
|
|
|
|
for (int i = n - x; i <= n; i++)
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
StylusPoint point = new StylusPoint();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-05-12 14:23:50 +08:00
|
|
|
|
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
|
|
|
|
|
point.X = e.Stroke.StylusPoints[i].X;
|
|
|
|
|
point.Y = e.Stroke.StylusPoints[i].Y;
|
|
|
|
|
stylusPoints.Add(point);
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i <= n; i++)
|
|
|
|
|
{
|
2024-05-12 14:23:50 +08:00
|
|
|
|
StylusPoint point = new StylusPoint();
|
|
|
|
|
|
|
|
|
|
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
|
|
|
|
|
point.X = e.Stroke.StylusPoints[i].X;
|
|
|
|
|
point.Y = e.Stroke.StylusPoints[i].Y;
|
|
|
|
|
stylusPoints.Add(point);
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
e.Stroke.StylusPoints = stylusPoints;
|
2024-05-12 14:23:50 +08:00
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
catch
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Settings.Canvas.FitToCurve == true)
|
2024-05-04 01:01:16 +08:00
|
|
|
|
{
|
|
|
|
|
drawingAttributes.FitToCurve = true;
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
private void SetNewBackupOfStroke()
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone();
|
|
|
|
|
int whiteboardIndex = CurrentWhiteboardIndex;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (currentMode == 0)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
whiteboardIndex = 0;
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public double GetDistance(Point point1, Point point2)
|
|
|
|
|
{
|
|
|
|
|
return Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) +
|
|
|
|
|
(point1.Y - point2.Y) * (point1.Y - point2.Y));
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public double GetPointSpeed(Point point1, Point point2, Point point3)
|
|
|
|
|
{
|
|
|
|
|
return (Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) +
|
|
|
|
|
(point1.Y - point2.Y) * (point1.Y - point2.Y))
|
|
|
|
|
+ Math.Sqrt((point3.X - point2.X) * (point3.X - point2.X) +
|
|
|
|
|
(point3.Y - point2.Y) * (point3.Y - point2.Y)))
|
|
|
|
|
/ 20;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public Point[] FixPointsDirection(Point p1, Point p2)
|
|
|
|
|
{
|
|
|
|
|
if (Math.Abs(p1.X - p2.X) / Math.Abs(p1.Y - p2.Y) > 8)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//水平
|
|
|
|
|
double x = Math.Abs(p1.Y - p2.Y) / 2;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (p1.Y > p2.Y)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
p1.Y -= x;
|
|
|
|
|
p2.Y += x;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
p1.Y += x;
|
|
|
|
|
p2.Y -= x;
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else if (Math.Abs(p1.Y - p2.Y) / Math.Abs(p1.X - p2.X) > 8)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
//垂直
|
|
|
|
|
double x = Math.Abs(p1.X - p2.X) / 2;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
if (p1.X > p2.X)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
p1.X -= x;
|
|
|
|
|
p2.X += x;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
p1.X += x;
|
|
|
|
|
p2.X -= x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Point[2] { p1, p2 };
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public StylusPointCollection GenerateFakePressureTriangle(StylusPointCollection points)
|
|
|
|
|
{
|
|
|
|
|
if (Settings.InkToShape.IsInkToShapeNoFakePressureTriangle == true || penType == 1)
|
2024-05-11 20:57:09 +08:00
|
|
|
|
{
|
|
|
|
|
var newPoint = new StylusPointCollection();
|
|
|
|
|
newPoint.Add(new StylusPoint(points[0].X, points[0].Y));
|
|
|
|
|
var cPoint = GetCenterPoint(points[0], points[1]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[1].X, points[1].Y));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[1].X, points[1].Y));
|
|
|
|
|
cPoint = GetCenterPoint(points[1], points[2]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[2].X, points[2].Y));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[2].X, points[2].Y));
|
|
|
|
|
cPoint = GetCenterPoint(points[2], points[0]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[0].X, points[0].Y));
|
|
|
|
|
return newPoint;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
2024-05-11 20:57:09 +08:00
|
|
|
|
{
|
|
|
|
|
var newPoint = new StylusPointCollection();
|
|
|
|
|
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
|
|
|
|
|
var cPoint = GetCenterPoint(points[0], points[1]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
|
|
|
|
|
cPoint = GetCenterPoint(points[1], points[2]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
|
|
|
|
|
cPoint = GetCenterPoint(points[2], points[0]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
|
|
|
|
|
return newPoint;
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public StylusPointCollection GenerateFakePressureRectangle(StylusPointCollection points)
|
|
|
|
|
{
|
|
|
|
|
if (Settings.InkToShape.IsInkToShapeNoFakePressureRectangle == true || penType == 1)
|
|
|
|
|
{
|
2024-05-11 20:57:09 +08:00
|
|
|
|
return points;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
2024-05-11 20:57:09 +08:00
|
|
|
|
{
|
|
|
|
|
var newPoint = new StylusPointCollection();
|
|
|
|
|
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
|
|
|
|
|
var cPoint = GetCenterPoint(points[0], points[1]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
|
|
|
|
|
cPoint = GetCenterPoint(points[1], points[2]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
|
|
|
|
|
cPoint = GetCenterPoint(points[2], points[3]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[3].X, points[3].Y, (float)0.4));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[3].X, points[3].Y, (float)0.4));
|
|
|
|
|
cPoint = GetCenterPoint(points[3], points[0]);
|
|
|
|
|
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
|
|
|
|
|
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
|
|
|
|
|
return newPoint;
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public Point GetCenterPoint(Point point1, Point point2)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
return new Point((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:38:44 +08:00
|
|
|
|
public StylusPoint GetCenterPoint(StylusPoint point1, StylusPoint point2)
|
|
|
|
|
{
|
2024-05-01 18:23:32 +08:00
|
|
|
|
return new StylusPoint((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-23 02:38:44 +08:00
|
|
|
|
}
|