Пример #1
0
        /// <summary>
        /// Obtain a smoothed path with the specified granularity from the current path using Catmull-Rom spline.
        /// Also outputs a List of the points corresponding to the smoothed path.
        /// </summary>
        /// <remarks>
        /// Implemented using a modified version of the code in the solution at
        /// http://stackoverflow.com/questions/8702696/drawing-smooth-curves-methods-needed
        /// </remarks>
        public static InkStroke SmoothedPathWithGranularity(InkStroke currentPath, int granularity)
        {
            var currentPoints = currentPath.GetPoints().Select(inkPoint => inkPoint.Position).ToList();

            NativePath         smoothedPath;
            List <NativePoint> smoothedPoints;

            SmoothedPathWithGranularity(currentPoints, granularity, out smoothedPath, out smoothedPoints);
            if (smoothedPath == null)
            {
                return(currentPath);
            }

            // create the new path with the old attributes
#if __ANDROID__ || __IOS__ || WINDOWS_PHONE_APP
            return(new InkStroke(smoothedPath, currentPath.GetPoints(), currentPath.Color, currentPath.Width, currentPath.Source, currentPath.Timestamp));
#elif WINDOWS_PHONE
            var da = currentPath.DrawingAttributes;
            smoothedPath.DrawingAttributes = new DrawingAttributes
            {
                Color        = da.Color,
                OutlineColor = da.OutlineColor,
                Width        = da.Width,
                Height       = da.Height,
            };
            return(smoothedPath);
#elif WINDOWS_UWP || WINDOWS_APP
            var da      = currentPath.DrawingAttributes;
            var builder = new InkStrokeBuilder();
            builder.SetDefaultDrawingAttributes(new InkDrawingAttributes
            {
                Color = da.Color,
                Size  = da.Size
            });
            return(builder.CreateStroke(smoothedPath));
#endif
        }
Пример #2
0
        /// <summary>
        /// Obtain a smoothed path with the specified granularity from the current path using Catmull-Rom spline.
        /// Also outputs a List of the points corresponding to the smoothed path.
        /// </summary>
        /// <remarks>
        /// Implemented using a modified version of the code in the solution at
        /// http://stackoverflow.com/questions/8702696/drawing-smooth-curves-methods-needed
        /// </remarks>
        public static InkStroke SmoothedPathWithGranularity(InkStroke currentPath, int granularity)
        {
            var currentPoints = currentPath.GetPoints().ToList();

            // not enough points to smooth effectively, so return the original path and points.
            if (currentPoints.Count < 4)
            {
                return(currentPath);
            }

            // create a new bezier path to hold the smoothed path.
            var smoothedPath   = new NativePath();
            var smoothedPoints = new List <NativePoint> ();

            // duplicate the first and last points as control points.
            currentPoints.Insert(0, currentPoints[0]);
            currentPoints.Add(currentPoints[currentPoints.Count - 1]);

            // add the first point
            smoothedPath.MoveTo(currentPoints[0].X, currentPoints[0].Y);
            smoothedPoints.Add(currentPoints[0]);

            for (var index = 1; index < currentPoints.Count - 2; index++)
            {
                var p0 = currentPoints[index - 1];
                var p1 = currentPoints[index];
                var p2 = currentPoints[index + 1];
                var p3 = currentPoints[index + 2];

                // add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines
                for (var i = 1; i < granularity; i++)
                {
                    var t   = (float)i * (1f / (float)granularity);
                    var tt  = t * t;
                    var ttt = tt * t;

                    // intermediate point
                    var mid = new NativePoint
                    {
                        X = 0.5f * (2f * p1.X + (p2.X - p0.X) * t +
                                    (2f * p0.X - 5f * p1.X + 4f * p2.X - p3.X) * tt +
                                    (3f * p1.X - p0.X - 3f * p2.X + p3.X) * ttt),

                        Y = 0.5f * (2 * p1.Y + (p2.Y - p0.Y) * t +
                                    (2 * p0.Y - 5 * p1.Y + 4 * p2.Y - p3.Y) * tt +
                                    (3 * p1.Y - p0.Y - 3 * p2.Y + p3.Y) * ttt)
                    };
                    smoothedPath.LineTo(mid.X, mid.Y);
                    smoothedPoints.Add(mid);
                }

                // add p2
                smoothedPath.LineTo(p2.X, p2.Y);
                smoothedPoints.Add(p2);
            }

            // add the last point
            var last = currentPoints[currentPoints.Count - 1];

            smoothedPath.LineTo(last.X, last.Y);
            smoothedPoints.Add(last);

            // create the new path with the old attributes
#if __ANDROID__ || __IOS__
            return(new InkStroke(smoothedPath, smoothedPoints.ToList(), currentPath.Color, currentPath.Width));
#elif WINDOWS_PHONE
            var da = currentPath.DrawingAttributes;
            smoothedPath.DrawingAttributes = new DrawingAttributes
            {
                Color        = da.Color,
                OutlineColor = da.OutlineColor,
                Width        = da.Width,
                Height       = da.Height,
            };
            return(smoothedPath);
#elif WINDOWS_UWP
            var da      = currentPath.DrawingAttributes;
            var builder = new InkStrokeBuilder();
            builder.SetDefaultDrawingAttributes(new InkDrawingAttributes
            {
                Color = da.Color,
                Size  = da.Size
            });
            return(builder.CreateStroke(smoothedPath));
#endif
        }