Xamarin: NGraphics libary. How to properly doing bezier curve using Path.CurveTo.

SimonLamSimonLam USMember ✭✭

I have created a question on Stack Overflow : stackoverflow.com/questions/39338873/xamarin-ngraphics-using-path-curveto-and-path-continecurveto-doesnt-have-a-smo. No one seems to reply to me yet. I should try on this forum.

I am using NGraphics library to do some drawing. The problem I am facing is to draw a stroke to the canvas when user touches the screen. I decided to use bezier curve to have smooth curve. In the Path class in the package, I am trying to use curveTo and continueCurveTo but the result not a smooth curves.

In the NGraphics library, I think it does use the bezier curve:

`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 () } };
    }`

This is my touch event code to handle the touches:

` #region Drawing Event
private bool DrawingBegan(TouchData touchData)
{
var stroke = new StrokeModel();
stroke.Points = new ObservableCollection();
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);
    }
Sign In or Register to comment.