Ejemplo n.º 1
0
        private static SKPath GetConcentrated(ComponentLoad load, float ViewHeight)
        {
            SKPath p = new SKPath();

            float ArrawHeight = ViewHeight / 15;
            // Положительная сила направлена слева направо или снизу вверх
            // Положительная сила - тянет. Поэтому её начало - это точка, в которой сила приложена
            // Если сила отрицательная, т. е. она толкает, и приложена в начале координат
            float s = Math.Sign(load.Value);

            if (load.Value < 0)
            {
                p.MoveTo(0, 0);
                p.LineTo(-ArrawHeight / 6, -ArrawHeight / 5);
                p.LineTo(ArrawHeight / 6, -ArrawHeight / 5);
                p.LineTo(0, 0);
                p.MoveTo(0, -ArrawHeight / 5);
                p.LineTo(0, -ArrawHeight);
            }
            else
            {
                p.MoveTo(0, -ArrawHeight);
                p.LineTo(-ArrawHeight / 6, -4 * ArrawHeight / 5);
                p.LineTo(ArrawHeight / 6, -4 * ArrawHeight / 5);
                p.LineTo(0, -ArrawHeight);
                p.MoveTo(0, -4 * ArrawHeight / 5);
                p.LineTo(0, 0);
            }

            p.Transform(SKMatrix.MakeRotation((float)Math.PI / 2));

            return(p);
        }
Ejemplo n.º 2
0
        private static SKPath GetDistibutedArrow(bool reverse)
        {
            SKPath p = new SKPath();

            // Если не reverse - То острие стрелки расположено в точке 0, 0
            // В противном случае эти координаты - у начала стреки
            if (!reverse)
            {
                p.MoveTo(0, 0);
                p.LineTo(-1f / 6f, -1f / 5f);
                p.LineTo(1f / 6f, -1f / 5f);
                p.LineTo(0, 0);
                p.MoveTo(0, -1f / 5f);
                p.LineTo(0, -1);
            }
            else
            {
                p.MoveTo(0, -1);
                p.LineTo(-1f / 6f, -4f / 5f);
                p.LineTo(1f / 6f, -4f / 5f);
                p.LineTo(0, -1);
                p.MoveTo(0, -4f / 5f);
                p.LineTo(0, 0);
            }

            p.Transform(SKMatrix.MakeRotation((float)Math.PI / 2));

            return(p);
        }
Ejemplo n.º 3
0
        public void Rotate(SKPoint point, float radians)
        {
            var currentAngle = GetAngleInRadians();
            var angleDiff    = radians - currentAngle;

            SKMatrix.PreConcat(ref Matrix, SKMatrix.MakeRotation(angleDiff, point.X, point.Y));
        }
Ejemplo n.º 4
0
        private Color WheelPointToColor(SKPoint pointSV, SKPoint pointH)
        {
            if (RotateTriangleByHue)
            {
                SKMatrix rotationHue = SKMatrix.MakeRotation((float)(2D * Math.PI * lastHue + Math.PI / 2D));
                pointSV = rotationHue.MapPoint(pointSV);
            }

            var polarH = ToPolar(pointH);
            var h      = (-polarH.Angle + Math.PI) / (2 * Math.PI);

            pointSV.Y  = -pointSV.Y + triangleVerticalOffset;
            pointSV.X += triangleSide;

            var x1 = triangleSide;
            var y1 = triangleHeight;
            var x2 = x1 * 2;
            var y2 = 0F;

            var vCurrent = ((pointSV.X * (y2 - y1)) - (pointSV.Y * (x2 - x1)) + (x2 * y1) - (y2 * x1)) / Math.Sqrt(Math.Pow(y2 - y1, 2) + Math.Pow(x2 - x1, 2));
            var v        = (y1 - vCurrent) / y1;

            var sMax     = x2 - (vCurrent / Math.Sin(Math.PI / 3));
            var sCurrent = pointSV.Y / Math.Sin(Math.PI / 3);
            var s        = sCurrent / sMax;

            lastHue = h;
            var result = ColorFromHSV(h, s, v, SelectedColor.A);

            return(result);
        }
Ejemplo n.º 5
0
        public static bool Contains(ComponentLinear linear, IssoPoint2D pt, ModelViewSurface surface)
        {
            SKPath pin = new SKPath();
            // Определим начало координат - это всегда точка, расположенная левее
            IssoPoint2D ptstart, ptend;

            if (linear.Start.X < linear.End.X)
            {
                ptstart = linear.Start;
                ptend   = linear.End;
            }
            else
            {
                ptstart = linear.End;
                ptend   = linear.Start;
            }
            double ang = Math.Asin((ptend.Y - ptstart.Y) / linear.Length);
            float  dy  = 7 / surface.scaleFactor;

            pin.MoveTo(ptstart.X, ptstart.Y - dy);
            pin.LineTo(ptstart.X, ptstart.Y + dy);
            pin.LineTo(ptstart.X + linear.Length, ptstart.Y + dy);
            pin.LineTo(ptstart.X + linear.Length, ptstart.Y - dy);
            pin.Close();
            pin.Transform(SKMatrix.MakeRotation((float)ang, ptstart.X, ptstart.Y));
            return(pin.Contains(pt.X, pt.Y));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Finds point cordinates of an entry.
        /// </summary>
        /// <returns>The point.</returns>
        /// <param name="value">The value.</param>
        /// <param name="center">The center.</param>
        /// <param name="angle">The entry angle.</param>
        /// <param name="radius">The radius.</param>
        private SKPoint GetPoint(float value, SKPoint center, float angle, float radius)
        {
            var amount   = Math.Abs(value - AbsoluteMinimum) / ValueRange;
            var point    = new SKPoint(0, radius * amount);
            var rotation = SKMatrix.MakeRotation(angle);

            return(center + rotation.MapPoint(point));
        }
Ejemplo n.º 7
0
        private static float FindRotation(SKPoint[] points1, SKPoint[] points2, SKBitmap secondImage)
        {
            const float FINAL_ROTATION_DELTA = 0.0001f;
            const float ROTATION_INC         = (float)Math.PI / 2f;

            return(BinarySearchFindComponent(points1, points2,
                                             t => SKMatrix.MakeRotation(t, secondImage.Width / 2f, secondImage.Height / 2f), ROTATION_INC,
                                             FINAL_ROTATION_DELTA));
        }
Ejemplo n.º 8
0
 private void AddGradinet()
 {
     _shapePaint.Shader = SKShader.CreateLinearGradient(
         new SKPoint(0, 0),
         new SKPoint(_canvasInfo.ImageInfo.Width, _canvasInfo.ImageInfo.Height),
         new SKColor[] { SKColor.Parse(Gradient.Start.ToHex()), SKColor.Parse(Gradient.End.ToHex()) },
         new float[] { Gradient.StartPosition, Gradient.EndPosition },
         SKShaderTileMode.Clamp,
         SKMatrix.MakeRotation(Gradient.Degrees,
                               _canvasInfo.ImageInfo.Rect.MidX,
                               _canvasInfo.ImageInfo.Rect.MidY));
 }
        protected override void Draw(SKCanvas canvas, int width, int height)
        {
            float time = _frame / (LengthSec * Fps);

            using (var paint = new SKPaint())
            {
                paint.Color       = Foreground.ToSkia();
                paint.StrokeWidth = (float)StrokeWidth;
                paint.IsAntialias = true;
                paint.IsStroke    = true;

                for (int a = 0; a < 3; ++a)
                {
                    var matrix = SKMatrix.MakeRotation(2 * (float)Math.PI * time / 6 + 2 * (float)Math.PI * a / 3);
                    matrix.TransX = width / 2f;
                    matrix.TransY = height / 2f;

                    canvas.SetMatrix(matrix);

                    const int n  = 12;
                    const int sp = 39;

                    for (int i = -n; i <= n; ++i)
                    {
                        float y  = (float)(i * sp * Math.Pow(2, time));
                        float tt = (float)Math.Min(1, Math.Max(0, 1.09 * time - 0.00275 * Math.Abs(y) + 0.075));

                        float x;

                        if (i % 2 == 0)
                        {
                            x = width;
                        }
                        else
                        {
                            x = width * tt;
                        }

                        if (x > 0)
                        {
                            canvas.DrawLine(-x, y, x, y, paint);
                        }
                    }
                }
            }

            ++_frame;
            if (_frame > LengthSec * Fps)
            {
                _frame = 0;
            }
        }
        public SKMatrix OneFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            if (Mode == TouchManipulationMode.None)
            {
                return(SKMatrix.MakeIdentity());
            }

            SKMatrix touchMatrix = SKMatrix.MakeIdentity();
            SKPoint  delta       = newPoint - prevPoint;

            if (Mode == TouchManipulationMode.ScaleDualRotate)  // One-finger rotation
            {
                SKPoint oldVector = prevPoint - pivotPoint;
                SKPoint newVector = newPoint - pivotPoint;

                float scale = Magnitude(newVector) / Magnitude(oldVector);


                // Avoid rotation if fingers are too close to center
                if (Magnitude(newVector) > 30 && Magnitude(oldVector) > 30)
                {
                    float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                    float newAngle  = (float)Math.Atan2(newVector.Y, newVector.X);

                    // Calculate rotation matrix
                    float angle = newAngle - prevAngle;
                    touchMatrix = SKMatrix.MakeRotation(angle, pivotPoint.X, pivotPoint.Y);

                    // Effectively rotate the old vector
                    float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                    oldVector.X = magnitudeRatio * newVector.X;
                    oldVector.Y = magnitudeRatio * newVector.Y;

                    // Recalculate delta
                    delta = newVector - oldVector;
                }

                if (!float.IsNaN(scale) && !float.IsInfinity(scale))
                {
                    SKMatrix.PostConcat(ref touchMatrix,
                                        SKMatrix.MakeScale(scale, scale, pivotPoint.X, pivotPoint.Y));
                }
            }

            // Multiply the rotation matrix by a translation matrix
            SKMatrix.PostConcat(ref touchMatrix, SKMatrix.MakeTranslation(delta.X, delta.Y));

            return(touchMatrix);
        }
Ejemplo n.º 11
0
        public SKMatrix TwoFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            SKMatrix touchMatrix = SKMatrix.MakeIdentity();
            SKPoint  oldVector   = prevPoint - pivotPoint;
            SKPoint  newVector   = newPoint - pivotPoint;

            if (Mode == TouchManipulationMode.ScaleRotate ||
                Mode == TouchManipulationMode.ScaleDualRotate)
            {
                // Find angles from pivot point to touch points
                float oldAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                float newAngle = (float)Math.Atan2(newVector.Y, newVector.X);

                // Calculate rotation matrix
                float angle = newAngle - oldAngle;

                touchMatrix = SKMatrix.MakeRotation(angle, pivotPoint.X, pivotPoint.Y);

                // Effectively rotate the old vector
                float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                oldVector.X = magnitudeRatio * newVector.X;
                oldVector.Y = magnitudeRatio * newVector.Y;
            }

            float scaleX = 1;
            float scaleY = 1;

            if (Mode == TouchManipulationMode.AnisotropicScale)
            {
                scaleX = newVector.X / oldVector.X;
                scaleY = newVector.Y / oldVector.Y;
            }
            else if (Mode == TouchManipulationMode.IsotropicScale ||
                     Mode == TouchManipulationMode.ScaleRotate ||
                     Mode == TouchManipulationMode.ScaleDualRotate)
            {
                scaleX = scaleY = Magnitude(newVector) / Magnitude(oldVector);
            }

            if (!float.IsNaN(scaleX) && !float.IsInfinity(scaleX) &&
                !float.IsNaN(scaleY) && !float.IsInfinity(scaleY))
            {
                SKMatrix.PostConcat(ref touchMatrix,
                                    SKMatrix.MakeScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
            }

            return(touchMatrix);
        }
Ejemplo n.º 12
0
        public override void RotateTransform(float angle, MatrixOrder order)
        {
            if (order == MatrixOrder.Prepend)
            {
                _image.RotateDegrees(angle);
            }

            if (order == MatrixOrder.Append)
            {
                //checkthis
                var old   = _image.TotalMatrix;
                var extra = SKMatrix.MakeRotation(angle);
                SKMatrix.PreConcat(ref old, extra);
                _image.SetMatrix(old);
            }
        }
Ejemplo n.º 13
0
        private void DrawGrid(SKCanvas canvas, double dx, double dy, double zx, double zy)
        {
            float gw = (float)_view.Width;
            float gh = (float)_view.Height;
            float cw = 15.0f;
            float ch = 15.0f;

            canvas.Save();
            canvas.Translate((float)dx, (float)dy);
            canvas.Scale((float)zx, (float)zy);

            var hlattice = SKMatrix.MakeScale(cw, ch);

            SKMatrix.PreConcat(ref hlattice, SKMatrix.MakeRotation((float)(Math.PI * 0.0 / 180.0)));

            var vlattice = SKMatrix.MakeScale(cw, ch);

            SKMatrix.PreConcat(ref vlattice, SKMatrix.MakeRotation((float)(Math.PI * 90.0 / 180.0)));

            using (var heffect = SKPathEffect.Create2DLine((float)(1.0 / zx), hlattice))
                using (var veffect = SKPathEffect.Create2DLine((float)(1.0 / zx), vlattice))
                    using (var hpaint = new SKPaint())
                        using (var vpaint = new SKPaint())
                        {
                            hpaint.IsAntialias = false;
                            hpaint.Color       = SKColors.LightGray;
                            hpaint.PathEffect  = heffect;
                            canvas.DrawRect(SKRect.Create(0.0f, ch, gw, gh - ch), hpaint);
                            vpaint.IsAntialias = false;
                            vpaint.Color       = SKColors.LightGray;
                            vpaint.PathEffect  = veffect;
                            canvas.DrawRect(SKRect.Create(cw, 0.0f, gw - cw, gh), vpaint);
                        }

            using (SKPaint strokePaint = new SKPaint())
            {
                strokePaint.IsAntialias = false;
                strokePaint.StrokeWidth = (float)(1.0 / zx);
                strokePaint.Color       = SKColors.Red;
                strokePaint.Style       = SKPaintStyle.Stroke;
                canvas.DrawRect(SKRect.Create(0.0f, 0.0f, gw, gh), strokePaint);
            }

            canvas.Restore();
        }
Ejemplo n.º 14
0
        private void UpdateLocations(Color color, float canvasRadius)
        {
            ColorToHSV(color, out _, out double saturation, out double value);

            var luminosityX = -(float)((2 * triangleSide * saturation) - (triangleSide));
            var luminosityY = triangleHeight;
            var tmp         = ToPolar(new SKPoint(luminosityX, luminosityY));

            tmp.Radius   *= (float)value;
            locationSV    = FromPolar(tmp);
            locationSV.X  = -locationSV.X;
            locationSV.Y -= 1;
            locationSV.X *= WheelSVRadius(canvasRadius);
            locationSV.Y *= WheelSVRadius(canvasRadius);

            var tmp4 = ToPolar(new SKPoint(locationSV.X, locationSV.Y));

            tmp4.Angle -= (float)(2 * Math.PI / 3);
            locationSV  = FromPolar(tmp4);

            locationSV.X += canvasRadius;
            locationSV.Y += canvasRadius;

            if (RotateTriangleByHue)
            {
                SKMatrix rotationHue = SKMatrix.MakeRotation(-(float)((2D * Math.PI * lastHue) + (Math.PI / 2D)), canvasRadius, canvasRadius);
                locationSV = rotationHue.MapPoint(locationSV);
            }

            var angleH = lastHue * Math.PI * 2;

            locationMiddleH    = FromPolar(new PolarPoint(WheelHRadius(canvasRadius), (float)(Math.PI - angleH)));
            locationMiddleH.X += canvasRadius;
            locationMiddleH.Y += canvasRadius;

            locationH1    = FromPolar(new PolarPoint(WheelHRadius(canvasRadius) + GetPickerRadiusPixels(), (float)(Math.PI - angleH)));
            locationH1.X += canvasRadius;
            locationH1.Y += canvasRadius;

            locationH2    = FromPolar(new PolarPoint(WheelHRadius(canvasRadius) - GetPickerRadiusPixels(), (float)(Math.PI - angleH)));
            locationH2.X += canvasRadius;
            locationH2.Y += canvasRadius;
        }
Ejemplo n.º 15
0
        private static void DrawCard(float xOffset, float yOffset, SKCanvas canvas)
        {
            SKPaint paintCard = new SKPaint
            {
                Style       = SKPaintStyle.Stroke,
                Color       = Color.Black.ToSKColor(),
                StrokeWidth = 2,
            };
            var path = new SKPath();

            var cardWith   = 120.0f;
            var cardHeight = 180.0f;

            path.MoveTo(0.0f, 0.0f);
            path.LineTo(0.0f, 1.0f);
            path.LineTo(0.7f, 1.0f);
            path.LineTo(0.7f, 0.0f);
            path.Close();
            path.Transform(SKMatrix.MakeRotation((float)(45.0f * Math.PI / 180), 0.7f, 1.0f));
            path.Transform(SKMatrix.MakeScale(cardWith, cardHeight));
            path.Offset(xOffset, yOffset);

            canvas.DrawPath(path, paintCard);


            var pathHeart = new SKPath();

            pathHeart.MoveTo(0.5f, 1.0f);
            pathHeart.LineTo(0.0f, 0.4f);
            pathHeart.CubicTo(0.0f, 0.0f,
                              0.5f, 0.0f,
                              0.5f, 0.4f);
            pathHeart.CubicTo(0.5f, 0.0f,
                              1.0f, 0.0f,
                              1.0f, 0.4f);
            pathHeart.LineTo(0.5f, 1.0f);
            pathHeart.Close();
            pathHeart.Transform(SKMatrix.MakeScale(cardWith, cardHeight));
            pathHeart.Offset(xOffset, yOffset);

            canvas.DrawPath(pathHeart, paintCard);
        }
Ejemplo n.º 16
0
        private static SKPath GetEquallyDistributed(ComponentLoad load, float scaleFactor, IssoPoint2D origin, float ViewHeight)
        {
            SKPath p      = new SKPath();
            float  Angle  = load.Direction * (float)Math.PI / 180f;
            float  length = IssoDist.PointDst(load.AppNodes[0].Location, load.AppNodes[1].Location);
            float  dx     = (load.AppNodes[1].Location.X - load.AppNodes[0].Location.X) * scaleFactor;
            float  dy     = -(load.AppNodes[1].Location.Y - load.AppNodes[0].Location.Y) * scaleFactor;

            float ArrawHeight = ViewHeight / 30;
            float step        = ViewHeight / 70;

            int     stepcnt = Math.Max((int)Math.Round(length * scaleFactor / step, 0), 1);
            SKPoint start   = IssoConvert.IssoPoint2DToSkPoint(load.AppNodes[0].Location, scaleFactor, origin, ViewHeight);

            dx = dx / stepcnt;
            dy = dy / stepcnt;

            SKMatrix rotate = SKMatrix.MakeRotation(-Angle);

            for (int i = 0; i < stepcnt + 1; i++)
            {
                SKPath arrow = GetDistibutedArrow((load.Value > 0) || (load.isOrthogonal && load.isReverse));

                arrow.Transform(SKMatrix.MakeScale(ArrawHeight, ArrawHeight));
                arrow.Transform(rotate);

                p.AddPath(arrow, start.X, start.Y);

                start.X += dx;
                start.Y += dy;
            }
            start = IssoConvert.IssoPoint2DToSkPoint(load.AppNodes[0].Location, scaleFactor, origin, ViewHeight);
            SKPoint end = IssoConvert.IssoPoint2DToSkPoint(load.AppNodes[1].Location, scaleFactor, origin, ViewHeight);

            p.MoveTo(start.X + ArrawHeight * (float)Math.Cos(Angle),
                     start.Y - ArrawHeight * (float)Math.Sin(Angle));
            p.LineTo(end.X + ArrawHeight * (float)Math.Cos(Angle),
                     end.Y - ArrawHeight * (float)Math.Sin(Angle));

            return(p);
        }
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            // load the image from the embedded resource stream
            using (var stream = new SKManagedStream(SampleMedia.Images.ColorWheel))
                using (var source = SKBitmap.Decode(stream))
                {
                    var matrix = SKMatrix.MakeRotation(30.0f);

                    // create the shader and paint
                    using (var shader = SKShader.CreateBitmap(source, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, matrix))
                        using (var paint = new SKPaint())
                        {
                            paint.IsAntialias = true;
                            paint.Shader      = shader;

                            // tile the bitmap
                            canvas.Clear(SKColors.White);
                            canvas.DrawPaint(paint);
                        }
                }
        }
Ejemplo n.º 18
0
        public void DrawCoordinationSystem(ModelViewSurface surface, SKCanvas canvas)
        {
            float h = surface.ViewHeight / 20;
            float w = h / 5;

            SKPath arrow = new SKPath();

            arrow.MoveTo(-w, -2 * w);
            arrow.LineTo(-w, 4 * w);
            arrow.LineTo(-2 * w, 4 * w);
            arrow.LineTo(0, 6 * w);
            arrow.LineTo(2 * w, 4 * w);
            arrow.LineTo(w, 4 * w);
            arrow.LineTo(w, -2 * w);
            arrow.Close();

            SKPaint arrowPaint = new SKPaint()
            {
                Style       = SKPaintStyle.StrokeAndFill,
                Color       = Color.FromRgb(30, 30, 40).ToSKColor(),
                IsAntialias = true,
                BlendMode   = SKBlendMode.Lighten,
                StrokeWidth = 1,
                TextAlign   = SKTextAlign.Center,
                TextSize    = 2 * w
            };

            float px = 3 * w;
            float py = surface.ViewHeight - 3 * w;

            arrow.Transform(SKMatrix.MakeTranslation(px, py));
            arrow.Transform(SKMatrix.MakeRotation((float)Math.PI, px, py));
            canvas.DrawPath(arrow, arrowPaint);
            arrow.Transform(SKMatrix.MakeRotation((float)Math.PI / 2, px, py));
            canvas.DrawPath(arrow, arrowPaint);

            arrowPaint.Color = Color.White.ToSKColor();
            canvas.DrawText("Y", px, py - 8 * w, arrowPaint);
            canvas.DrawText("X", px + 8 * w, py + w / 2, arrowPaint);
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            using (SKPaint paint = new SKPaint())
            {
                paint.Shader = SKShader.CreateLinearGradient(
                    new SKPoint(0, 0),
                    info.Width < info.Height ? new SKPoint(info.Width, 0) :
                    new SKPoint(0, info.Height),
                    new SKColor[] { SKColors.White, SKColors.Black },
                    null,
                    SKShaderTileMode.Mirror,
                    SKMatrix.MakeRotation((float)angle, info.Rect.MidX, info.Rect.MidY));

                canvas.DrawRect(info.Rect, paint);
            }
        }
Ejemplo n.º 20
0
 public void Rotate(float theta)
 {
     nativeMatrix = SKMatrix.MakeRotation(theta);
 }
Ejemplo n.º 21
0
 public static SKMatrix Rotate(this SKMatrix m, float angle)
 {
     return(m.Concat(SKMatrix.MakeRotation(angle)));
 }
Ejemplo n.º 22
0
        public static SKPath CreateSectorPath(float start, float end, float outerRadius, float innerRadius = 0.0f, float margin = 0.0f, float explodeDistance = 0.0f, SKPathDirection direction = SKPathDirection.Clockwise)
        {
            var path = new SKPath();

            // if the sector has no size, then it has no path
            if (start == end)
            {
                return(path);
            }

            // the the sector is a full circle, then do that
            if (end - start == 1.0f)
            {
                path.AddCircle(0, 0, outerRadius, direction);
                path.AddCircle(0, 0, innerRadius, direction);
                path.FillType = SKPathFillType.EvenOdd;
                return(path);
            }

            // calculate the angles
            var startAngle        = TotalAngle * start - UprightAngle;
            var endAngle          = TotalAngle * end - UprightAngle;
            var large             = endAngle - startAngle > PI ? SKPathArcSize.Large : SKPathArcSize.Small;
            var sectorCenterAngle = (endAngle - startAngle) / 2f + startAngle;

            // get the radius bits
            var cectorCenterRadius = (outerRadius - innerRadius) / 2f + innerRadius;

            // move explosion around 90 degrees, since matrix use down as 0
            var explosionMatrix = SKMatrix.MakeRotation(sectorCenterAngle - (PI / 2f));
            var offset          = explosionMatrix.MapPoint(new SKPoint(0, explodeDistance));

            // calculate the angle for the margins
            margin = direction == SKPathDirection.Clockwise ? margin : -margin;
            var offsetR = outerRadius == 0 ? 0 : ((margin / (TotalAngle * outerRadius)) * TotalAngle);
            var offsetr = innerRadius == 0 ? 0 : ((margin / (TotalAngle * innerRadius)) * TotalAngle);

            // get the points
            var a = GetCirclePoint(outerRadius, startAngle + offsetR) + offset;
            var b = GetCirclePoint(outerRadius, endAngle - offsetR) + offset;
            var c = GetCirclePoint(innerRadius, endAngle - offsetr) + offset;
            var d = GetCirclePoint(innerRadius, startAngle + offsetr) + offset;

            // add the points to the path
            path.MoveTo(a);
            path.ArcTo(outerRadius, outerRadius, 0, large, direction, b.X, b.Y);
            path.LineTo(c);
            if (innerRadius == 0.0f)
            {
                // take a short cut
                path.LineTo(d);
            }
            else
            {
                var reverseDirection = direction == SKPathDirection.Clockwise ? SKPathDirection.CounterClockwise : SKPathDirection.Clockwise;
                path.ArcTo(innerRadius, innerRadius, 0, large, reverseDirection, d.X, d.Y);
            }
            path.Close();

            return(path);
        }
Ejemplo n.º 23
0
 public void Rotate(float degrees)
 {
     SKMatrix.PreConcat(ref _skMatrix, SKMatrix.MakeRotation(GraphicsProvider.DegreesToRads(degrees)));
 }
Ejemplo n.º 24
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IStyle style, IFeature feature, IGeometry geometry,
                                float opacity, SymbolCache symbolCache = null)
        {
            if (style is LabelStyle labelStyle)
            {
                var worldCenter = geometry.BoundingBox.Centroid;
                var center      = viewport.WorldToScreen(worldCenter);
                LabelRenderer.Draw(canvas, labelStyle, feature, (float)center.X, (float)center.Y, opacity);
            }
            else if (style is StyleCollection styleCollection)
            {
                foreach (var s in styleCollection)
                {
                    Draw(canvas, viewport, s, feature, geometry, opacity, symbolCache);
                }
            }
            else if (style is VectorStyle vectorStyle)
            {
                var polygon = (Polygon)geometry;

                float   lineWidth        = 1;
                var     lineColor        = Color.Black;       // default
                var     fillColor        = Color.Gray;        // default
                var     strokeCap        = PenStrokeCap.Butt; // default
                var     strokeJoin       = StrokeJoin.Miter;  // default
                var     strokeMiterLimit = 4f;                // default
                var     strokeStyle      = PenStyle.Solid;    // default
                float[] dashArray        = null;              // default

                if (vectorStyle.Outline != null)
                {
                    lineWidth        = (float)vectorStyle.Outline.Width;
                    lineColor        = vectorStyle.Outline.Color;
                    strokeCap        = vectorStyle.Outline.PenStrokeCap;
                    strokeJoin       = vectorStyle.Outline.StrokeJoin;
                    strokeMiterLimit = vectorStyle.Outline.StrokeMiterLimit;
                    strokeStyle      = vectorStyle.Outline.PenStyle;
                    dashArray        = vectorStyle.Outline.DashArray;
                }

                if (vectorStyle.Fill != null)
                {
                    fillColor = vectorStyle.Fill?.Color;
                }

                using (var path = polygon.ToSkiaPath(viewport, canvas.LocalClipBounds, lineWidth))
                    using (var paintFill = new SKPaint {
                        IsAntialias = true
                    })
                    {
                        // Is there a FillStyle?
                        if (vectorStyle.Fill?.FillStyle == FillStyle.Solid)
                        {
                            paintFill.StrokeWidth = 0;
                            paintFill.Style       = SKPaintStyle.Fill;
                            paintFill.PathEffect  = null;
                            paintFill.Shader      = null;
                            paintFill.Color       = fillColor.ToSkia(opacity);
                            canvas.DrawPath(path, paintFill);
                        }
                        else
                        {
                            paintFill.StrokeWidth = 1;
                            paintFill.Style       = SKPaintStyle.Stroke;
                            paintFill.Shader      = null;
                            paintFill.Color       = fillColor.ToSkia(opacity);
                            var scale    = 10.0f;
                            var fillPath = new SKPath();
                            var matrix   = SKMatrix.MakeScale(scale, scale);

                            switch (vectorStyle.Fill?.FillStyle)
                            {
                            case FillStyle.Cross:
                                fillPath.MoveTo(scale * 0.8f, scale * 0.8f);
                                fillPath.LineTo(0, 0);
                                fillPath.MoveTo(0, scale * 0.8f);
                                fillPath.LineTo(scale * 0.8f, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.DiagonalCross:
                                fillPath.MoveTo(scale, scale);
                                fillPath.LineTo(0, 0);
                                fillPath.MoveTo(0, scale);
                                fillPath.LineTo(scale, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.BackwardDiagonal:
                                fillPath.MoveTo(0, scale);
                                fillPath.LineTo(scale, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.ForwardDiagonal:
                                fillPath.MoveTo(scale, scale);
                                fillPath.LineTo(0, 0);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Dotted:
                                paintFill.Style = SKPaintStyle.StrokeAndFill;
                                fillPath.AddCircle(scale * 0.5f, scale * 0.5f, scale * 0.35f);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Horizontal:
                                fillPath.MoveTo(0, scale * 0.5f);
                                fillPath.LineTo(scale, scale * 0.5f);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Vertical:
                                fillPath.MoveTo(scale * 0.5f, 0);
                                fillPath.LineTo(scale * 0.5f, scale);
                                paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                                break;

                            case FillStyle.Bitmap:
                                paintFill.Style = SKPaintStyle.Fill;
                                var image = GetImage(symbolCache, vectorStyle.Fill.BitmapId);
                                if (image != null)
                                {
                                    paintFill.Shader = image.ToShader(SKShaderTileMode.Repeat, SKShaderTileMode.Repeat);
                                }
                                break;

                            case FillStyle.BitmapRotated:
                                paintFill.Style = SKPaintStyle.Fill;
                                image           = GetImage(symbolCache, vectorStyle.Fill.BitmapId);
                                if (image != null)
                                {
                                    paintFill.Shader = image.ToShader(SKShaderTileMode.Repeat,
                                                                      SKShaderTileMode.Repeat,
                                                                      SKMatrix.MakeRotation((float)(viewport.Rotation * System.Math.PI / 180.0f), image.Width >> 1, image.Height >> 1));
                                }
                                break;

                            default:
                                paintFill.PathEffect = null;
                                break;
                            }

                            // Do this, because if not, path isn't filled complete
                            using (new SKAutoCanvasRestore(canvas))
                            {
                                canvas.ClipPath(path);
                                var bounds = path.Bounds;
                                // Make sure, that the brush starts with the correct position
                                var inflate = ((int)path.Bounds.Width * 0.3f / scale) * scale;
                                bounds.Inflate(inflate, inflate);
                                // Draw rect with bigger size, which is clipped by path
                                canvas.DrawRect(bounds, paintFill);
                            }
                        }

                        if (vectorStyle.Outline != null)
                        {
                            using (var paintStroke = new SKPaint {
                                IsAntialias = true
                            })
                            {
                                paintStroke.Style       = SKPaintStyle.Stroke;
                                paintStroke.StrokeWidth = lineWidth;
                                paintStroke.Color       = lineColor.ToSkia(opacity);
                                paintStroke.StrokeCap   = strokeCap.ToSkia();
                                paintStroke.StrokeJoin  = strokeJoin.ToSkia();
                                paintStroke.StrokeMiter = strokeMiterLimit;
                                if (strokeStyle != PenStyle.Solid)
                                {
                                    paintStroke.PathEffect = strokeStyle.ToSkia(lineWidth, dashArray);
                                }
                                else
                                {
                                    paintStroke.PathEffect = null;
                                }
                                canvas.DrawPath(path, paintStroke);
                            }
                        }
                    }
            }
        }
Ejemplo n.º 25
0
        public override void DrawContent(SKCanvas canvas, int width, int height)
        {
            var total = this.Entries?.Count() ?? 0;

            if (total > 0)
            {
                var captionHeight = this.Entries.Max(x =>
                {
                    var result = 0.0f;

                    var hasLabel      = !string.IsNullOrEmpty(x.Label);
                    var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel);
                    if (hasLabel || hasValueLabel)
                    {
                        var hasOffset     = hasLabel && hasValueLabel;
                        var captionMargin = this.LabelTextSize * 0.60f;
                        var space         = hasOffset ? captionMargin : 0;

                        if (hasLabel)
                        {
                            result += this.LabelTextSize;
                        }

                        if (hasValueLabel)
                        {
                            result += this.LabelTextSize;
                        }
                    }

                    return(result);
                });

                var center     = new SKPoint(width / 2, height / 2);
                var radius     = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight;
                var rangeAngle = (float)((Math.PI * 2) / total);
                var startAngle = (float)Math.PI;

                var nextEntry = this.Entries.First();
                var nextAngle = startAngle;
                var nextPoint = this.GetPoint(nextEntry.Value * this.AnimationProgress, center, nextAngle, radius);

                this.DrawBorder(canvas, center, radius);

                using (var clip = new SKPath())
                {
                    clip.AddCircle(center.X, center.Y, radius);

                    for (int i = 0; i < total; i++)
                    {
                        var angle = nextAngle;
                        var entry = nextEntry;
                        var point = nextPoint;

                        var nextIndex = (i + 1) % total;
                        nextAngle = startAngle + (rangeAngle * nextIndex);
                        nextEntry = this.Entries.ElementAt(nextIndex);
                        nextPoint = this.GetPoint(nextEntry.Value * this.AnimationProgress, center, nextAngle, radius);

                        canvas.Save();
                        canvas.ClipPath(clip);

                        // Border center bars
                        using (var paint = new SKPaint()
                        {
                            Style = SKPaintStyle.Stroke,
                            StrokeWidth = this.BorderLineSize,
                            Color = this.BorderLineColor,
                            IsAntialias = true,
                        })
                        {
                            var borderPoint = this.GetPoint(this.MaxValue, center, angle, radius);
                            canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint);
                        }

                        // Values points and lines
                        using (var paint = new SKPaint()
                        {
                            Style = SKPaintStyle.Stroke,
                            StrokeWidth = this.BorderLineSize,
                            Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f * this.AnimationProgress)),
                            PathEffect = SKPathEffect.CreateDash(new[] { this.BorderLineSize, this.BorderLineSize * 2 }, 0),
                            IsAntialias = true,
                        })
                        {
                            var amount = Math.Abs(entry.Value - this.AbsoluteMinimum) / this.ValueRange;
                            canvas.DrawCircle(center.X, center.Y, radius * amount, paint);
                        }

                        canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), this.LineSize);
                        canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, this.LineSize);
                        canvas.DrawPoint(point, entry.Color, this.PointSize, this.PointMode);

                        canvas.Restore();

                        // Labels
                        var labelPoint = new SKPoint(0, radius + this.LabelTextSize + (this.PointSize / 2));
                        var rotation   = SKMatrix.MakeRotation(angle);
                        labelPoint = center + rotation.MapPoint(labelPoint);
                        var alignment = SKTextAlign.Left;

                        if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon))
                        {
                            alignment = SKTextAlign.Center;
                        }
                        else if (angle > (float)(startAngle + Math.PI))
                        {
                            alignment = SKTextAlign.Right;
                        }

                        canvas.DrawCaptionLabels(entry.Label, entry.TextColor, entry.ValueLabel, entry.Color.WithAlpha((byte)(255 * this.AnimationProgress)), this.LabelTextSize, labelPoint, alignment, base.Typeface);
                    }
                }
            }
        }
Ejemplo n.º 26
0
 public IMatrix2D GetRotationXform(float degrees)
 {
     return(new Matrix2D(SKMatrix.MakeRotation(DegreesToRads(degrees))));
 }
Ejemplo n.º 27
0
        public override void BuildContent(ICanvas canvas, int width, int height)
        {
            var total = Entries?.Count() ?? 0;

            if (total > 0)
            {
                var captionHeight = Entries.Max(x =>
                {
                    var result = 0.0;

                    var hasLabel      = !string.IsNullOrEmpty(x.Label);
                    var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel);
                    if (hasLabel || hasValueLabel)
                    {
                        var hasOffset     = hasLabel && hasValueLabel;
                        var captionMargin = LabelTextSize * 0.60f;
                        var space         = hasOffset ? captionMargin : 0;

                        if (hasLabel)
                        {
                            result += LabelTextSize;
                        }

                        if (hasValueLabel)
                        {
                            result += LabelTextSize;
                        }
                    }

                    return(result);
                });

                var center     = new Point(width / 2, height / 2);
                var radius     = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight;
                var rangeAngle = (float)((Math.PI * 2) / total);
                var startAngle = (float)Math.PI;

                var nextEntry = Entries.First();
                var nextAngle = startAngle;
                var nextPoint = GetPoint(nextEntry.Value * AnimationProgress, center, nextAngle, radius);

                DrawBorder(canvas, center, radius);
#if LATER
                clip.AddCircle(center.X, center.Y, radius);
#endif

                for (int i = 0; i < total; i++)
                {
                    var angle = nextAngle;
                    var entry = nextEntry;
                    var point = nextPoint;

                    var nextIndex = (i + 1) % total;
                    nextAngle = startAngle + (rangeAngle * nextIndex);
                    nextEntry = Entries.ElementAt(nextIndex);
                    nextPoint = GetPoint(nextEntry.Value * AnimationProgress, center, nextAngle, radius);

#if LATER
                    canvas.Save();
                    canvas.ClipPath(clip);
#endif

                    // Border center bars
                    var borderPoint = GetPoint(MaxValue, center, angle, radius);
                    var line        = Line().X1(point.X).Y1(point.Y).X2(borderPoint.X).Y2(borderPoint.Y).Stroke(SolidColorBrush().Color(BorderLineColor)).StrokeThickness(BorderLineSize);
                    canvas.Add(0, 0, line);

                    // Values points and lines
                    //PathEffect = SKPathEffect.CreateDash(new[] { BorderLineSize, BorderLineSize * 2 }, 0),

                    var amount      = Math.Abs(entry.Value - AbsoluteMinimum) / ValueRange;
                    var diameter    = radius * amount * 2;
                    var circleColor = entry.Color.WithA((byte)(entry.Color.A * 0.75f * AnimationProgress));
                    var circle      = Ellipse().Width(diameter).Height(diameter).Stroke(SolidColorBrush().Color(circleColor)).StrokeThickness(BorderLineSize);
                    canvas.Add(center.X - diameter / 2, center.Y - diameter / 2, circle);

                    canvas.DrawGradientLine(center, entry.Color.WithA(0), point, entry.Color.WithA((byte)(entry.Color.A * 0.75f)), LineSize);
                    canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, LineSize);
                    canvas.DrawPoint(point, entry.Color, (float)PointSize, PointMode);
                }

#if LATER
                canvas.Restore();
#endif

#if LATER
                // Labels
                var labelPoint = new Point(0, radius + LabelTextSize + (PointSize / 2));
                var rotation   = SKMatrix.MakeRotation(angle);
                labelPoint = center + rotation.MapPoint(labelPoint);
                var alignment = SKTextAlign.Left;

                if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon))
                {
                    alignment = SKTextAlign.Center;
                }
                else if (angle > (float)(startAngle + Math.PI))
                {
                    alignment = SKTextAlign.Right;
                }

                canvas.DrawCaptionLabels(entry.Label, entry.TextColor, UnicodeMode, UnicodeLanguage, entry.ValueLabel, entry.Color.WithA((byte)(255 * AnimationProgress)), LabelTextSize, labelPoint, alignment, base.Typeface, out var _);
#endif
            }
        }
Ejemplo n.º 28
0
        private void PaintSVTriangle(SKCanvas canvas, float canvasRadius)
        {
            canvas.Save();

            SKMatrix rotationHue = SKMatrix.MakeRotation(-(float)((2D * Math.PI * lastHue) + (Math.PI / 2D))
                                                         , canvasRadius, canvasRadius);

            if (RotateTriangleByHue)
            {
                canvas.SetMatrix(rotationHue);
            }

            var point1 = new SKPoint(canvasRadius, canvasRadius - WheelSVRadius(canvasRadius));
            var point2 = new SKPoint(canvasRadius + (triangleSide * WheelSVRadius(canvasRadius))
                                     , canvasRadius + (triangleVerticalOffset * WheelSVRadius(canvasRadius)));
            var point3 = new SKPoint(canvasRadius - (triangleSide * WheelSVRadius(canvasRadius))
                                     , canvasRadius + (triangleVerticalOffset * WheelSVRadius(canvasRadius)));

            using (SKPath pathTriangle = new SKPath())
            {
                pathTriangle.MoveTo(point1);
                pathTriangle.LineTo(point2);
                pathTriangle.LineTo(point3);
                canvas.ClipPath(pathTriangle, SKClipOperation.Intersect, true);
            }

            SKMatrix matrix = SKMatrix.MakeRotation(-(float)Math.PI / 3F, point3.X, point3.Y);

            if (RotateTriangleByHue)
            {
                SKMatrix.Concat(ref matrix, rotationHue, matrix);
            }

            var shader = SKShader.CreateSweepGradient(point3, new SKColor[] { Color.FromHsla(lastHue, 1, 0.5).ToSKColor()
                                                                              , Color.White.ToSKColor(), Color.FromHsla(lastHue, 1, 0.5).ToSKColor() }
                                                      , new float[] { 0F, 0.16666666666666F, 1F });

            var paint = new SKPaint
            {
                IsAntialias = true,
                Shader      = shader,
                Style       = SKPaintStyle.Fill
            };

            canvas.SetMatrix(matrix);
            canvas.DrawCircle(point3, WheelSVRadius(canvasRadius) * 2, paint);

            if (RotateTriangleByHue)
            {
                canvas.SetMatrix(rotationHue);
            }
            else
            {
                canvas.ResetMatrix();
            }

            var colors = new SKColor[] {
                SKColors.Black,
                SKColors.Transparent
            };

            PaintGradient(canvas, canvasRadius, colors, point3);

            canvas.ResetMatrix();
            canvas.Restore();
        }
Ejemplo n.º 29
0
        public AlignedResult CreateAlignedSecondImageKeypoints(SKBitmap firstImage, SKBitmap secondImage,
                                                               bool discardTransX, AlignmentSettings settings, bool keystoneRightOnFirst)
        {
#if __NO_EMGU__
            return(null);
#endif
            var result = new AlignedResult();

            var detector = new ORBDetector();
            const ImreadModes READ_MODE = ImreadModes.Color;

            var mat1                = new Mat();
            var descriptors1        = new Mat();
            var allKeyPointsVector1 = new VectorOfKeyPoint();
            CvInvoke.Imdecode(GetBytes(firstImage, 1), READ_MODE, mat1);
            detector.DetectAndCompute(mat1, null, allKeyPointsVector1, descriptors1, false);

            var mat2                = new Mat();
            var descriptors2        = new Mat();
            var allKeyPointsVector2 = new VectorOfKeyPoint();
            CvInvoke.Imdecode(GetBytes(secondImage, 1), READ_MODE, mat2);
            detector.DetectAndCompute(mat2, null, allKeyPointsVector2, descriptors2, false);

            const double THRESHOLD_PROPORTION = 1 / 4d;
            var          thresholdDistance    = Math.Sqrt(Math.Pow(firstImage.Width, 2) + Math.Pow(firstImage.Height, 2)) * THRESHOLD_PROPORTION;

            var distanceThresholdMask = new Mat(allKeyPointsVector2.Size, allKeyPointsVector1.Size, DepthType.Cv8U, 1);
            if (!settings.UseCrossCheck)
            {
                unsafe
                {
                    var maskPtr = (byte *)distanceThresholdMask.DataPointer.ToPointer();
                    for (var i = 0; i < allKeyPointsVector2.Size; i++)
                    {
                        var keyPoint2 = allKeyPointsVector2[i];
                        for (var j = 0; j < allKeyPointsVector1.Size; j++)
                        {
                            var keyPoint1        = allKeyPointsVector1[j];
                            var physicalDistance = CalculatePhysicalDistanceBetweenPoints(keyPoint2.Point, keyPoint1.Point);
                            if (physicalDistance < thresholdDistance)
                            {
                                *maskPtr = 255;
                            }
                            else
                            {
                                *maskPtr = 0;
                            }

                            maskPtr++;
                        }
                    }
                }
            }

            var vectorOfMatches = new VectorOfVectorOfDMatch();
            var matcher         = new BFMatcher(DistanceType.Hamming, settings.UseCrossCheck);
            matcher.Add(descriptors1);
            matcher.KnnMatch(descriptors2, vectorOfMatches, settings.UseCrossCheck ? 1 : 2, settings.UseCrossCheck ? new VectorOfMat() : new VectorOfMat(distanceThresholdMask));

            var goodMatches = new List <MDMatch>();
            for (var i = 0; i < vectorOfMatches.Size; i++)
            {
                if (vectorOfMatches[i].Size == 0)
                {
                    continue;
                }

                if (vectorOfMatches[i].Size == 1 ||
                    (vectorOfMatches[i][0].Distance < 0.75 * vectorOfMatches[i][1].Distance)) //make sure matches are unique
                {
                    goodMatches.Add(vectorOfMatches[i][0]);
                }
            }

            if (goodMatches.Count < settings.MinimumKeypoints)
            {
                return(null);
            }

            var pairedPoints = new List <PointForCleaning>();
            for (var ii = 0; ii < goodMatches.Count; ii++)
            {
                var keyPoint1 = allKeyPointsVector1[goodMatches[ii].TrainIdx];
                var keyPoint2 = allKeyPointsVector2[goodMatches[ii].QueryIdx];
                pairedPoints.Add(new PointForCleaning
                {
                    KeyPoint1 = keyPoint1,
                    KeyPoint2 = keyPoint2,
                    Data      = new KeyPointOutlierDetectorData
                    {
                        Distance = (float)CalculatePhysicalDistanceBetweenPoints(keyPoint1.Point, keyPoint2.Point),
                        Slope    = (keyPoint2.Point.Y - keyPoint1.Point.Y) / (keyPoint2.Point.X - keyPoint1.Point.X)
                    },
                    Match = new MDMatch
                    {
                        Distance = goodMatches[ii].Distance,
                        ImgIdx   = goodMatches[ii].ImgIdx,
                        QueryIdx = ii,
                        TrainIdx = ii
                    }
                });
            }

            if (settings.DrawKeypointMatches)
            {
                result.DirtyMatchesCount = pairedPoints.Count;
                result.DrawnDirtyMatches = DrawMatches(firstImage, secondImage, pairedPoints);
            }

            if (settings.DiscardOutliersByDistance || settings.DiscardOutliersBySlope)
            {
                //Debug.WriteLine("DIRTY POINTS START (ham,dist,slope,ydiff), count: " + pairedPoints.Count);
                //foreach (var pointForCleaning in pairedPoints)
                //{
                //    Debug.WriteLine(pointForCleaning.Match.Distance  + "," + pointForCleaning.Data.Distance + "," + pointForCleaning.Data.Slope + "," + Math.Abs(pointForCleaning.KeyPoint1.Point.Y - pointForCleaning.KeyPoint2.Point.Y));
                //}

                //Debug.WriteLine("DIRTY PAIRS:");
                //PrintPairs(pairedPoints);

                if (settings.DiscardOutliersByDistance)
                {
                    // reject distances and slopes more than some number of standard deviations from the median
                    var medianDistance = pairedPoints.OrderBy(p => p.Data.Distance).ElementAt(pairedPoints.Count / 2).Data.Distance;
                    var distanceStdDev = CalcStandardDeviation(pairedPoints.Select(p => p.Data.Distance).ToArray());
                    pairedPoints = pairedPoints.Where(p => Math.Abs(p.Data.Distance - medianDistance) < Math.Abs(distanceStdDev * (settings.KeypointOutlierThresholdTenths / 10d))).ToList();
                    //Debug.WriteLine("Median Distance: " + medianDistance);
                    //Debug.WriteLine("Distance Cleaned Points count: " + pairedPoints.Count);
                }

                if (settings.DiscardOutliersBySlope)
                {
                    var validSlopes = pairedPoints.Where(p => !float.IsNaN(p.Data.Slope) && float.IsFinite(p.Data.Slope)).ToArray();
                    var medianSlope = validSlopes.OrderBy(p => p.Data.Slope).ElementAt(validSlopes.Length / 2).Data.Slope;
                    var slopeStdDev = CalcStandardDeviation(validSlopes.Select(p => p.Data.Slope).ToArray());
                    pairedPoints = validSlopes.Where(p => Math.Abs(p.Data.Slope - medianSlope) < Math.Abs(slopeStdDev * (settings.KeypointOutlierThresholdTenths / 10d))).ToList();
                    //Debug.WriteLine("Median Slope: " + medianSlope);
                    //Debug.WriteLine("Slope Cleaned Points count: " + pairedPoints.Count);
                }

                //Debug.WriteLine("CLEAN POINTS START (ham,dist,slope,ydiff), count: " + pairedPoints.Count);
                //foreach (var pointForCleaning in pairedPoints)
                //{
                //    Debug.WriteLine(pointForCleaning.Match.Distance + "," + pointForCleaning.Data.Distance + "," + pointForCleaning.Data.Slope + "," + Math.Abs(pointForCleaning.KeyPoint1.Point.Y - pointForCleaning.KeyPoint2.Point.Y));
                //}

                //Debug.WriteLine("CLEANED PAIRS:");
                //PrintPairs(pairedPoints);

                for (var ii = 0; ii < pairedPoints.Count; ii++)
                {
                    var oldMatch = pairedPoints[ii].Match;
                    pairedPoints[ii].Match = new MDMatch
                    {
                        Distance = oldMatch.Distance,
                        ImgIdx   = oldMatch.ImgIdx,
                        QueryIdx = ii,
                        TrainIdx = ii
                    };
                }

                if (settings.DrawKeypointMatches)
                {
                    result.CleanMatchesCount = pairedPoints.Count;
                    result.DrawnCleanMatches = DrawMatches(firstImage, secondImage, pairedPoints);
                }
            }

            var points1 = pairedPoints.Select(p => new SKPoint(p.KeyPoint1.Point.X, p.KeyPoint1.Point.Y)).ToArray();
            var points2 = pairedPoints.Select(p => new SKPoint(p.KeyPoint2.Point.X, p.KeyPoint2.Point.Y)).ToArray();


            var translation1 = FindVerticalTranslation(points1, points2, secondImage);
            var translated1  = SKMatrix.MakeTranslation(0, translation1);
            points2 = translated1.MapPoints(points2);

            var rotation1 = FindRotation(points1, points2, secondImage);
            var rotated1  = SKMatrix.MakeRotation(rotation1, secondImage.Width / 2f, secondImage.Height / 2f);
            points2 = rotated1.MapPoints(points2);

            var zoom1   = FindZoom(points1, points2, secondImage);
            var zoomed1 = SKMatrix.MakeScale(zoom1, zoom1, secondImage.Width / 2f, secondImage.Height / 2f);
            points2 = zoomed1.MapPoints(points2);



            var translation2 = FindVerticalTranslation(points1, points2, secondImage);
            var translated2  = SKMatrix.MakeTranslation(0, translation2);
            points2 = translated2.MapPoints(points2);

            var rotation2 = FindRotation(points1, points2, secondImage);
            var rotated2  = SKMatrix.MakeRotation(rotation2, secondImage.Width / 2f, secondImage.Height / 2f);
            points2 = rotated2.MapPoints(points2);

            var zoom2   = FindZoom(points1, points2, secondImage);
            var zoomed2 = SKMatrix.MakeScale(zoom2, zoom2, secondImage.Width / 2f, secondImage.Height / 2f);
            points2 = zoomed2.MapPoints(points2);



            var translation3 = FindVerticalTranslation(points1, points2, secondImage);
            var translated3  = SKMatrix.MakeTranslation(0, translation3);
            points2 = translated3.MapPoints(points2);

            var rotation3 = FindRotation(points1, points2, secondImage);
            var rotated3  = SKMatrix.MakeRotation(rotation3, secondImage.Width / 2f, secondImage.Height / 2f);
            points2 = rotated3.MapPoints(points2);

            var zoom3   = FindZoom(points1, points2, secondImage);
            var zoomed3 = SKMatrix.MakeScale(zoom3, zoom3, secondImage.Width / 2f, secondImage.Height / 2f);
            points2 = zoomed3.MapPoints(points2);


            var keystoned1 = SKMatrix.MakeIdentity();
            var keystoned2 = SKMatrix.MakeIdentity();
            if (settings.DoKeystoneCorrection)
            {
                keystoned1 = FindTaper(points2, points1, secondImage, keystoneRightOnFirst);
                points1    = keystoned1.MapPoints(points1);
                keystoned2 = FindTaper(points1, points2, secondImage, !keystoneRightOnFirst);
                points2    = keystoned2.MapPoints(points2);
            }


            var horizontaled = SKMatrix.MakeIdentity();
            if (!discardTransX)
            {
                var horizontalAdj = FindHorizontalTranslation(points1, points2, secondImage);
                horizontaled = SKMatrix.MakeTranslation(horizontalAdj, 0);
                points2      = horizontaled.MapPoints(points2);
            }



            var tempMatrix1 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix1, translated1, rotated1);
            var tempMatrix2 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix2, tempMatrix1, zoomed1);

            var tempMatrix3 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix3, tempMatrix2, translated2);
            var tempMatrix4 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix4, tempMatrix3, rotated2);
            var tempMatrix5 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix5, tempMatrix4, zoomed2);

            var tempMatrix6 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix6, tempMatrix5, translated3);
            var tempMatrix7 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix7, tempMatrix6, rotated3);
            var tempMatrix8 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix8, tempMatrix7, zoomed3);


            var tempMatrix9 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix9, tempMatrix8, keystoned2);

            var tempMatrix10 = new SKMatrix();
            SKMatrix.Concat(ref tempMatrix10, tempMatrix9, horizontaled);

            var finalMatrix = tempMatrix10;
            result.TransformMatrix2 = finalMatrix;
            var alignedImage2 = new SKBitmap(secondImage.Width, secondImage.Height);
            using (var canvas = new SKCanvas(alignedImage2))
            {
                canvas.SetMatrix(finalMatrix);
                canvas.DrawBitmap(secondImage, 0, 0);
            }
            result.AlignedBitmap2 = alignedImage2;


            result.TransformMatrix1 = keystoned1;
            var alignedImage1 = new SKBitmap(firstImage.Width, firstImage.Height);
            using (var canvas = new SKCanvas(alignedImage1))
            {
                canvas.SetMatrix(keystoned1);
                canvas.DrawBitmap(firstImage, 0, 0);
            }
            result.AlignedBitmap1 = alignedImage1;


            return(result);
        }
Ejemplo n.º 30
0
        public static SKShader Line(SKColor color)
        {
            using (var bitmap = new SKBitmap(15, 15, true))
            {
                using (var canvas = new SKCanvas(bitmap))
                {
                    canvas.Clear(SKColors.Transparent);
                    using (var paint = new SKPaint())
                    {
                        paint.Color       = color;
                        paint.IsStroke    = true;
                        paint.IsAntialias = true;
                        paint.StrokeWidth = 4;
                        canvas.DrawLine(0, 0, bitmap.Width, 0, paint);
                    }
                }

                // Close enough to 2*PI/8
                return(SKShader.CreateBitmap(bitmap, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.MakeRotation(0.8f)));
            }
        }