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); }
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); }
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)); }
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); }
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)); }
/// <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)); }
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)); }
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); }
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); }
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); } }
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(); }
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; }
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); }
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); } } }
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); } }
public void Rotate(float theta) { nativeMatrix = SKMatrix.MakeRotation(theta); }
public static SKMatrix Rotate(this SKMatrix m, float angle) { return(m.Concat(SKMatrix.MakeRotation(angle))); }
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); }
public void Rotate(float degrees) { SKMatrix.PreConcat(ref _skMatrix, SKMatrix.MakeRotation(GraphicsProvider.DegreesToRads(degrees))); }
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); } } } } }
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); } } } }
public IMatrix2D GetRotationXform(float degrees) { return(new Matrix2D(SKMatrix.MakeRotation(DegreesToRads(degrees)))); }
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 } }
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(); }
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); }
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))); } }