0

Say, I have an array of float points (function xy). The first image is trying with SkiaSharp, the second is with System.Drawing of .NET Framework.

I understand that I should use a method like CubicTo, but I don't see how to combine it to achieve the expected result.

The example was created in WindowsForms (only uses 2 PictureBox) and SkiaSharp nuget. It is similar with Xamarin, the question is the same.

enter image description here

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

using System.Drawing;
using System.Drawing.Drawing2D;
using SkiaSharp;

namespace SKLab
{
    public partial class BasicTestForm : Form
    {
        float startX = -4, stopX = 4;
        float yi = -4, ye = 4;
        float w = 200, h = 150;
        float stepX = 1;
        float x, px;
        float y, py;
        // pixel to cartesian    
        float pixelFromX(float cartX) => w * (cartX - startX) / (stopX - startX);
        // cartesian to pixel
        float pixelFromY(float cartY) => h * (cartY - yi) / (ye - yi);

        public BasicTestForm()
        {
            InitializeComponent();
            SkiaPlot(pictureBox1);
            DrawingPlot(pictureBox2);
        }

        private void SkiaPlot(PictureBox p)
        {
            p.Size = new Size((int)w, (int)h);

            using (var surface = SKSurface.Create(new SKImageInfo(p.Width, p.Height))) {
                SKCanvas g = surface.Canvas;

                g.Clear(SKColors.White);

                using (var paint = new SKPaint()) {
                    paint.Style = SKPaintStyle.Stroke;
                    paint.IsAntialias = true;
                    paint.Color = SKColors.CornflowerBlue;
                    paint.StrokeWidth = 2;

                    var path = new SKPath();

                    for (x = startX; x <= stopX; x += stepX) {
                        px = pixelFromX(x);
                        py = pixelFromY((float)Math.Sin(x));
                        if (x == startX) {
                            path.MoveTo(px, py);
                        } else {
                            path.LineTo(px, py);
                        }
                    }
                    g.DrawPath(path, paint);
                }

                using (SKImage image = surface.Snapshot())
                using (SKData data = image.Encode(SKEncodedImageFormat.Png, 100))
                using (MemoryStream mStream = new MemoryStream(data.ToArray())) {
                    p.Image = new Bitmap(mStream, false);
                }
            }
        }

        void DrawingPlot(PictureBox p)
        {
            p.Size = new Size((int)w, (int)h); ;

            // Make the Bitmap.
            var canvas = new Bitmap(p.ClientSize.Width, p.ClientSize.Height);
            using (var g = Graphics.FromImage(canvas)) {
                // Clear.
                g.Clear(Color.White);
                // curve
                var points = new List<PointF>();
                for (x = startX; x <= stopX; x += stepX) {
                    points.Add(new PointF
                    {
                        X = pixelFromX(x),
                        Y = pixelFromY((float)Math.Sin(x))
                    });
                }
                g.SmoothingMode = SmoothingMode.AntiAlias;
                using (var pen = new Pen(Color.CornflowerBlue, 2)) {
                    g.DrawCurve(pen, points.ToArray());
                }
            }
            // Display the result.
            p.Image = canvas;
        }
    }
}
Sith2021
  • 3,245
  • 30
  • 22
  • Hi , you can have a try with beziers to draw that in SkiaSharp . https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/curves/beziers#related-links – Junior Jiang Apr 30 '20 at 07:11
  • Misprint. The comment «//pixel to cartesian» should be «//pixel from cartesian» (both cases) – Sith2021 Apr 30 '20 at 07:15
  • TXS Junior Jiang, I studied those examples, none of which coincides precisely with the question presented here. – Sith2021 Apr 30 '20 at 07:21
  • Okey , here is a discussion for reference , maybe helpful . https://stackoverflow.com/questions/41802311/draw-splinesmooth-path-with-skiasharp-lib-on-xamarin-forms – Junior Jiang Apr 30 '20 at 07:42
  • Thanks for your suggestion Junior. Peter Waher gives the solution with CreateSpline() (I test it and works fine). It would be elegant if SkiaSharp developers gave a compact method, like DrawCurve with SmoothingMode.AntiAlias of System.Drawing. – Sith2021 Apr 30 '20 at 16:04
  • Yeah , that's the fact , there is no wrapped method to use to achieve that your wants . – Junior Jiang May 01 '20 at 01:11
  • @Sith2021 Just be careful with Peter Waher's code, if it's from the IoTGateway, you cannot use it for commercial projects unless you purchase a license. – Raid May 19 '23 at 15:31

0 Answers0