SkiaSharp Shapes: Eliptic circles

SkiaSharp Shapes: Eliptic circles

A journey into shapes and animations.

I have decided to adopt SkiaSharp for related functions in my Xamarin Form projects henceforth so I'll be posting samples of the controls I create more stories periodically.

The first group of shapes I want to show here is the Eliptic circles.

Screenshot_20210308-140156.png

Just as some planets have ringed moons, we'll draw some circles around a circular path.

So let's start. We decide the number is circles we want on our path using var eliptic_circle_iterator = 8; . The distances will be consistent.

        private void OnCanvasViewPaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info = args.Info;
            SKSurface surface = args.Surface;
            SKCanvas canvas = surface.Canvas;
            canvas.Clear();
            SKPoint center = new SKPoint(info.Width / 2, info.Height / 2);
            float radius = Math.Min(info.Width / 2, info.Height / 2) - 2 * explodeOffset;

            //draw the eliptic circle
            using (SKPaint fillMarkDotCirclePaint = new SKPaint())
            {
                var eliptic_circle_test_angle = 360 / eliptic_circle_iterator / 2 + _degrees;
                if (_shouldRotate)
                {
                    eliptic_circle_test_angle += _degrees;
                }

                fillMarkDotCirclePaint.Style = SKPaintStyle.Fill;
                for (int ii = 0; ii < eliptic_circle_iterator; ii++)
                {
                     Math.DivRem(ii, General.Colors.Count, out int colorIndex);
                    fillMarkDotCirclePaint.Color = Color.FromHex(General.Colors[colorIndex]).ToSKColor();
                    //calculate the  point on the circle

                    General.PointOnCircle(radius, eliptic_circle_test_angle, center.X, center.Y, out float circle_x, out float circle_y);

                    surface.Canvas.DrawCircle(circle_x, circle_y, ball_size, fillMarkDotCirclePaint);

                    eliptic_circle_test_angle += 360 / eliptic_circle_iterator;
                    if (eliptic_circle_test_angle > 360)
                        eliptic_circle_test_angle -= 360;
                }
            }

            if (_shouldRotate)
                IncrementDegrees();
        }

Here is the code for deriving the angle to place the circle:

public static void PointOnCircle(float radius, float angleInDegrees, float originx, float originy, out float x, out float y)
        {
            // Convert from degrees to radians via multiplication by PI/180        
            x = (float)(radius * Math.Cos(angleInDegrees * Math.PI / 180F)) + originx;
            y = (float)(radius * Math.Sin(angleInDegrees * Math.PI / 180F)) + originy;

        }

What it does basically is to convert degree to radian using PI/180.

Then what happens when we want a change of angle?

 private void IncrementDegrees()
        {
            if (_degrees >= 360)
                _degrees = _degrees - 360;

            if (_reverseSpinning)
                _degrees -= 3.6f;
            else
                _degrees += 3.6f;
        }

Moreover, the circles can rotate both in clockwise or anticlockwise directions. We'll also control the speed from runtime with more controls.

rota1.gif

rota2.gif

Here is the full source code: github.com/fzany/SkiaSharpMakes Have a great day.