I am using NGraphics to draw continued strokes on a custom view. This is my resulting image when the stroke drawn on it. The red circle is a indication of the the unsmooth edges. The second image showing the small red rectangle of the control points I received when mouse move event got called. If the control points were closed enough, the curve looks better.
I have looked inside the NGraphics code, it looks like the curves does draw as a Bezier path.
public Point GetPoint (Point prevPoint, double t)
{
var u = 1 - t;
return
u * u * u * prevPoint +
3 * u * u * t * Control1 +
3 * u * t * t * Control2 +
t * t * t * Point;
}
public override EdgeSamples[] GetEdgeSamples (Point startPoint, Point prevPoint, double tolerance, int minSamples, int maxSamples)
{
var n = (3*prevPoint.DistanceTo (Point)) / tolerance;
if (n < minSamples)
n = minSamples;
if (n > maxSamples)
n = maxSamples;
var r = new List<Point> ();
var dt = 1.0 / (n - 1);
for (var i = 0; i < n; i++) {
var t = i * dt;
var p = GetPoint (prevPoint, t);
r.Add (p);
}
return new[]{ new EdgeSamples { Points = r.ToArray () } };
}
The touch event which I used curveTo and continueCurveTo:
#region Drawing Event
private bool DrawingBegan(TouchData touchData)
{
var stroke = new StrokeModel();
stroke.Points = new ObservableCollection<PointModel>();
stroke.Pointer = touchData.PointerId;
stroke.Path = new Path();
stroke.PenColor = Pen.Color;
stroke.PenWidth = Pen.Width;
stroke.DeviceOrientation = DeviceInfo.DeviceOrientation;
_localStroke.Add(stroke);
return base.TouchesBegan(touchData);
}
private bool DrawingMove(TouchData touchData)
{
foreach (var stroke in _localStroke)
{
if (stroke.Pointer == touchData.PointerId)
{
var length = stroke.Points.Count - 1;
if (stroke.Points.Count == 2)
{
var p1 = ConvertGlobalToLocal(new Point(stroke.Points[length - 1].X, stroke.Points[length - 1].Y));
var p2 = ConvertGlobalToLocal(new Point(stroke.Points[length].X, stroke.Points[length].Y));
var p3 = touchData.Point;
stroke.Path.MoveTo(p1);
stroke.Path.CurveTo(p1, p2, p3);
}
else if (stroke.Points.Count > 2)
{
var p2 = ConvertGlobalToLocal(new Point(stroke.Points[length].X, stroke.Points[length].Y));
var p3 = touchData.Point;
stroke.Path.LineTo(p2);
stroke.Path.ContinueCurveTo(p2, p3);
}
var newPoint = ConvertLocalToGlobal(touchData.Point);
var point = new PointModel();
point.X = newPoint.X;
point.Y = newPoint.Y;
stroke.Points.Add(point);
break;
}
}
return base.TouchesMoved(touchData);
}
Will it because not enough sample size?
I have fixed the problem by using HistoricalX and HistoricalY... if not use, some touch data will be missed.