private Path CreateFishPath(float fishCenterX, float fishCenterY) { Path path = new Path(); float fishHeadX = fishCenterX; float fishHeadY = fishCenterY - mFishHeight / 2.0f; //the head of the fish path.MoveTo(fishHeadX, fishHeadY); //the left body of the fish path.QuadTo(fishHeadX - mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.222f, fishHeadX - mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.444f); path.LineTo(fishHeadX - mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.666f); path.LineTo(fishHeadX - mFishWidth * 0.5f, fishHeadY + mFishHeight * 0.8f); path.LineTo(fishHeadX - mFishWidth * 0.5f, fishHeadY + mFishHeight); //the tail of the fish path.LineTo(fishHeadX, fishHeadY + mFishHeight * 0.9f); //the right body of the fish path.LineTo(fishHeadX + mFishWidth * 0.5f, fishHeadY + mFishHeight); path.LineTo(fishHeadX + mFishWidth * 0.5f, fishHeadY + mFishHeight * 0.8f); path.LineTo(fishHeadX + mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.666f); path.LineTo(fishHeadX + mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.444f); path.QuadTo(fishHeadX + mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.222f, fishHeadX, fishHeadY); path.Close(); return(path); }
private Path CreateWaterPath(RectF waterRect, float progress) { Path path = new Path(); path.MoveTo(waterRect.Left, waterRect.Top); //Similar to the way draw the bottle's Bottom sides float radius = (waterRect.Width() - mStrokeWidth) / 2.0f; float CenterY = waterRect.Bottom - 0.86f * radius; float bottleBottomWidth = waterRect.Width() / 2.0f; RectF bodyRect = new RectF(waterRect.Left, CenterY - radius, waterRect.Right, CenterY + radius); path.AddArc(bodyRect, 187.5f, -67.5f); path.LineTo(waterRect.CenterX() - bottleBottomWidth / 2.0f, waterRect.Bottom); path.LineTo(waterRect.CenterX() + bottleBottomWidth / 2.0f, waterRect.Bottom); path.AddArc(bodyRect, 60, -67.5f); //draw the water waves float cubicXChangeSize = waterRect.Width() * 0.35f * progress; float cubicYChangeSize = waterRect.Height() * 1.2f * progress; path.CubicTo(waterRect.Left + waterRect.Width() * 0.80f - cubicXChangeSize, waterRect.Top - waterRect.Height() * 1.2f + cubicYChangeSize, waterRect.Left + waterRect.Width() * 0.55f - cubicXChangeSize, waterRect.Top - cubicYChangeSize, waterRect.Left, waterRect.Top - mStrokeWidth / 2.0f); path.LineTo(waterRect.Left, waterRect.Top); return(path); }
private Path CreateWaitPath(RectF bounds) { Path path = new Path(); //create circle path.MoveTo(bounds.CenterX() + mWaitCircleRadius, bounds.CenterY()); //create w path.CubicTo(bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius * 0.5f, bounds.CenterX() + mWaitCircleRadius * 0.3f, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() - mWaitCircleRadius * 0.35f, bounds.CenterY() + mWaitCircleRadius * 0.5f); path.QuadTo(bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() + mWaitCircleRadius * 0.05f, bounds.CenterY() + mWaitCircleRadius * 0.5f); path.LineTo(bounds.CenterX() + mWaitCircleRadius * 0.75f, bounds.CenterY() - mWaitCircleRadius * 0.2f); path.CubicTo(bounds.CenterX(), bounds.CenterY() + mWaitCircleRadius * 1f, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() + mWaitCircleRadius * 0.4f, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY()); //create arc path.ArcTo(new RectF(bounds.CenterX() - mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() + mWaitCircleRadius), 0, -359); path.ArcTo(new RectF(bounds.CenterX() - mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() + mWaitCircleRadius), 1, -359); path.ArcTo(new RectF(bounds.CenterX() - mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() + mWaitCircleRadius), 2, -2); //create w path.CubicTo(bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius * 0.5f, bounds.CenterX() + mWaitCircleRadius * 0.3f, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() - mWaitCircleRadius * 0.35f, bounds.CenterY() + mWaitCircleRadius * 0.5f); path.QuadTo(bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() - mWaitCircleRadius, bounds.CenterX() + mWaitCircleRadius * 0.05f, bounds.CenterY() + mWaitCircleRadius * 0.5f); path.LineTo(bounds.CenterX() + mWaitCircleRadius * 0.75f, bounds.CenterY() - mWaitCircleRadius * 0.2f); path.CubicTo(bounds.CenterX(), bounds.CenterY() + mWaitCircleRadius * 1f, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY() + mWaitCircleRadius * 0.4f, bounds.CenterX() + mWaitCircleRadius, bounds.CenterY()); return(path); }
void UpdateShape() { var path = new APath(); path.MoveTo(_x1, _y1); path.LineTo(_x2, _y2); UpdateShape(path); }
protected override Android.Graphics.Path GetPath(Size availableSize) { var output = new Android.Graphics.Path(); output.MoveTo(ViewHelper.LogicalToPhysicalPixels(X1), ViewHelper.LogicalToPhysicalPixels(Y1)); output.LineTo(ViewHelper.LogicalToPhysicalPixels(X2), ViewHelper.LogicalToPhysicalPixels(Y2)); return(output); }
private Android.Graphics.Path GetPath() { var output = new Android.Graphics.Path(); output.MoveTo((float)X1, (float)Y1); output.LineTo((float)X2, (float)Y2); return(output); }
void UpdateShape() { if (_points != null && _points.Count > 1) { var path = new APath(); path.SetFillType(_fillMode ? FillType.Winding : FillType.EvenOdd); path.MoveTo(_density * (float)_points[0].X, _density * (float)_points[0].Y); for (int index = 1; index < _points.Count; index++) path.LineTo(_density * (float)_points[index].X, _density * (float)_points[index].Y); UpdateShape(path); } }
public void FillPolygon(Brush brush, Point[] points) { APaint.Color = brush.Color.AColor(); APaint.Flags = (Android.Graphics.PaintFlags) 0; APaint.Flags = Flags; APaint.SetStyle(Android.Graphics.Paint.Style.Fill); APaint.StrokeWidth = LineWidth; var p = new Android.Graphics.Path(); p.MoveTo(points[0].X, points[0].Y); foreach (var pt in points) { p.LineTo(pt.X, pt.Y); } ACanvas.DrawPath(p, APaint); p.Dispose(); }
private Android.Graphics.Path GetPath() { var coords = Points; if (coords == null || coords.Count <= 1) { return(null); } var output = new Android.Graphics.Path(); output.MoveTo((float)coords[0].X, (float)coords[0].Y); for (var i = 1; i < coords.Count; i++) { output.LineTo((float)coords[i].X, (float)coords[i].Y); } return(output); }
private bool AddStrokeInternal(IEnumerable <NativePoint> points, NativeColor color, float width) { var strokePoints = points?.ToList(); if (strokePoints == null || strokePoints.Count == 0) { return(false); } var newpath = new NativePath(); newpath.MoveTo(strokePoints[0].X, strokePoints[0].Y); foreach (var point in strokePoints.Skip(1)) { newpath.LineTo(point.X, point.Y); } paths.Add(new InkStroke(newpath, strokePoints, color, width)); return(true); }
private Path CreateBottlePath(RectF bottleRect) { float bottleneckWidth = bottleRect.Width() * 0.3f; float bottleneckHeight = bottleRect.Height() * 0.415f; float bottleneckDecorationWidth = bottleneckWidth * 1.1f; float bottleneckDecorationHeight = bottleneckHeight * 0.167f; Path path = new Path(); //draw the Left side of the bottleneck decoration path.MoveTo(bottleRect.CenterX() - bottleneckDecorationWidth * 0.5f, bottleRect.Top); path.QuadTo(bottleRect.CenterX() - bottleneckDecorationWidth * 0.5f - bottleneckWidth * 0.15f, bottleRect.Top + bottleneckDecorationHeight * 0.5f, bottleRect.CenterX() - bottleneckWidth * 0.5f, bottleRect.Top + bottleneckDecorationHeight); path.LineTo(bottleRect.CenterX() - bottleneckWidth * 0.5f, bottleRect.Top + bottleneckHeight); //draw the Left side of the bottle's body float radius = (bottleRect.Width() - mStrokeWidth) / 2.0f; float CenterY = bottleRect.Bottom - 0.86f * radius; RectF bodyRect = new RectF(bottleRect.Left, CenterY - radius, bottleRect.Right, CenterY + radius); path.AddArc(bodyRect, 255, -135); //draw the Bottom of the bottle float bottleBottomWidth = bottleRect.Width() / 2.0f; path.LineTo(bottleRect.CenterX() - bottleBottomWidth / 2.0f, bottleRect.Bottom); path.LineTo(bottleRect.CenterX() + bottleBottomWidth / 2.0f, bottleRect.Bottom); //draw the Right side of the bottle's body path.AddArc(bodyRect, 60, -135); //draw the Right side of the bottleneck decoration path.LineTo(bottleRect.CenterX() + bottleneckWidth * 0.5f, bottleRect.Top + bottleneckDecorationHeight); path.QuadTo(bottleRect.CenterX() + bottleneckDecorationWidth * 0.5f + bottleneckWidth * 0.15f, bottleRect.Top + bottleneckDecorationHeight * 0.5f, bottleRect.CenterX() + bottleneckDecorationWidth * 0.5f, bottleRect.Top); return(path); }
public override Carto.Graphics.Bitmap OnDrawPopup(PopupDrawInfo popupDrawInfo) { PopupStyle style = popupDrawInfo.Popup.Style; // Calculate scaled dimensions float DPToPX = popupDrawInfo.DPToPX; float PXTODP = 1 / DPToPX; if (style.ScaleWithDPI) { DPToPX = 1; } else { PXTODP = 1; } float screenWidth = popupDrawInfo.ScreenBounds.GetWidth() * PXTODP; float screenHeight = popupDrawInfo.ScreenBounds.GetHeight() * PXTODP; // Update sizes based on scale (uses extension method, cf. Shared/Extensions int fontSize = FontSize.Update(DPToPX); int triangleWidth = TriangleSize.Update(DPToPX); int triangleHeight = TriangleSize.Update(DPToPX); int strokeWidth = StrokeWidth.Update(DPToPX); int screenPadding = ScreenPadding.Update(DPToPX); // Set font var font = Android.Graphics.Typeface.Create("HelveticaNeue-Light", Android.Graphics.TypefaceStyle.Normal); // Calculate the maximum popup size, adjust with dpi int maxPopupWidth = (int)(Math.Min(screenWidth, screenHeight)); float halfStrokeWidth = strokeWidth * 0.5f; int maxTextWidth = maxPopupWidth - (2 * screenPadding + strokeWidth); // Measure text TextPaint textPaint = new TextPaint { Color = TextColor, TextSize = fontSize }; textPaint.SetTypeface(font); var textLayout = new StaticLayout(text, textPaint, maxTextWidth, Layout.Alignment.AlignNormal, 1, 0, false); int textX = (int)Math.Min(textPaint.MeasureText(text), textLayout.Width); int textY = textLayout.Height; int popupWidth = textX + (2 * PopupPadding + strokeWidth + triangleWidth); int popupHeight = textY + (2 * PopupPadding + strokeWidth); var bitmap = Android.Graphics.Bitmap.CreateBitmap(popupWidth, popupHeight, Android.Graphics.Bitmap.Config.Argb8888); var canvas = new Android.Graphics.Canvas(bitmap); var trianglePath = new Android.Graphics.Path(); trianglePath.MoveTo(triangleWidth, 0); trianglePath.LineTo(halfStrokeWidth, triangleHeight * 0.5f); trianglePath.LineTo(triangleWidth, triangleHeight); trianglePath.Close(); int triangleOffsetX = 0; int triangleOffsetY = (popupHeight - triangleHeight) / 2; // Create paint object var paint = new Android.Graphics.Paint(); paint.AntiAlias = true; paint.SetStyle(Android.Graphics.Paint.Style.Stroke); paint.StrokeWidth = strokeWidth; paint.Color = StrokeColor; // Stroke background var background = new Android.Graphics.RectF(); background.Left = triangleWidth; background.Top = halfStrokeWidth; background.Right = popupWidth - strokeWidth; background.Bottom = popupHeight - strokeWidth; canvas.DrawRect(background, paint); // Stroke triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); // Fill background paint.SetStyle(Android.Graphics.Paint.Style.Fill); paint.Color = BackgroundColor; canvas.DrawRect(background, paint); // Fill triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); if (textLayout != null) { // Draw text canvas.Save(); canvas.Translate(halfStrokeWidth + triangleWidth + PopupPadding, halfStrokeWidth + PopupPadding); textLayout.Draw(canvas); canvas.Restore(); } return(BitmapUtils.CreateBitmapFromAndroidBitmap(bitmap)); }
public override Carto.Graphics.Bitmap OnDrawPopup(PopupDrawInfo popupDrawInfo) { PopupStyle style = popupDrawInfo.Popup.Style; // Calculate scaled dimensions float DPToPX = popupDrawInfo.DPToPX; float PXTODP = 1 / DPToPX; if (style.ScaleWithDPI) { DPToPX = 1; } else { PXTODP = 1; } float screenWidth = popupDrawInfo.ScreenBounds.GetWidth() * PXTODP; float screenHeight = popupDrawInfo.ScreenBounds.GetHeight() * PXTODP; // Update sizes based on scale (uses extension method, cf. Shared/Extensions int fontSize = FontSize.Update(DPToPX); int triangleWidth = TriangleSize.Update(DPToPX); int triangleHeight = TriangleSize.Update(DPToPX); int strokeWidth = StrokeWidth.Update(DPToPX); int screenPadding = ScreenPadding.Update(DPToPX); // Set font var font = Android.Graphics.Typeface.Create("HelveticaNeue-Light", Android.Graphics.TypefaceStyle.Normal); // Calculate the maximum popup size, adjust with dpi int maxPopupWidth = (int)(Math.Min(screenWidth, screenHeight)); float halfStrokeWidth = strokeWidth * 0.5f; int maxTextWidth = maxPopupWidth - (2 * screenPadding + strokeWidth); // Measure text TextPaint textPaint = new TextPaint { Color = TextColor, TextSize = fontSize }; textPaint.SetTypeface(font); var textLayout = new StaticLayout(text, textPaint, maxTextWidth, Layout.Alignment.AlignNormal, 1, 0, false); int textX = (int)Math.Min(textPaint.MeasureText(text), textLayout.Width); int textY = textLayout.Height; int popupWidth = textX + (2 * PopupPadding + strokeWidth + triangleWidth); int popupHeight = textY + (2 * PopupPadding + strokeWidth); var bitmap = Android.Graphics.Bitmap.CreateBitmap(popupWidth, popupHeight, Android.Graphics.Bitmap.Config.Argb8888); var canvas = new Android.Graphics.Canvas(bitmap); var trianglePath = new Android.Graphics.Path(); trianglePath.MoveTo(triangleWidth, 0); trianglePath.LineTo(halfStrokeWidth, triangleHeight * 0.5f); trianglePath.LineTo(triangleWidth, triangleHeight); trianglePath.Close(); int triangleOffsetX = 0; int triangleOffsetY = (popupHeight - triangleHeight) / 2; // Create paint object var paint = new Android.Graphics.Paint(); paint.AntiAlias = true; paint.SetStyle(Android.Graphics.Paint.Style.Stroke); paint.StrokeWidth = strokeWidth; paint.Color = StrokeColor; // Stroke background var background = new Android.Graphics.RectF(); background.Left = triangleWidth; background.Top = halfStrokeWidth; background.Right = popupWidth - strokeWidth; background.Bottom = popupHeight - strokeWidth; canvas.DrawRect(background, paint); // Stroke triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); // Fill background paint.SetStyle(Android.Graphics.Paint.Style.Fill); paint.Color = BackgroundColor; canvas.DrawRect(background, paint); // Fill triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); if (textLayout != null) { // Draw text canvas.Save(); canvas.Translate(halfStrokeWidth + triangleWidth + PopupPadding, halfStrokeWidth + PopupPadding); textLayout.Draw(canvas); canvas.Restore(); } return BitmapUtils.CreateBitmapFromAndroidBitmap(bitmap); }
public static void SmoothedPathWithGranularity(List <NativePoint> currentPoints, int granularity, out NativePath smoothedPath, out List <NativePoint> smoothedPoints) { // not enough points to smooth effectively, so return the original path and points. if (currentPoints.Count < 4) { smoothedPath = null; smoothedPoints = null; return; } // create a new bezier path to hold the smoothed path. smoothedPath = new NativePath(); smoothedPoints = new List <NativePoint> (); // duplicate the first and last points as control points. currentPoints.Insert(0, currentPoints[0]); currentPoints.Add(currentPoints[currentPoints.Count - 1]); // add the first point smoothedPath.MoveTo(currentPoints[0].X, currentPoints[0].Y); smoothedPoints.Add(currentPoints[0]); for (var index = 1; index < currentPoints.Count - 2; index++) { var p0 = currentPoints[index - 1]; var p1 = currentPoints[index]; var p2 = currentPoints[index + 1]; var p3 = currentPoints[index + 2]; // add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines for (var i = 1; i < granularity; i++) { var t = (float)i * (1f / (float)granularity); var tt = t * t; var ttt = tt * t; // intermediate point var mid = new NativePoint { X = 0.5f * (2f * p1.X + (p2.X - p0.X) * t + (2f * p0.X - 5f * p1.X + 4f * p2.X - p3.X) * tt + (3f * p1.X - p0.X - 3f * p2.X + p3.X) * ttt), Y = 0.5f * (2 * p1.Y + (p2.Y - p0.Y) * t + (2 * p0.Y - 5 * p1.Y + 4 * p2.Y - p3.Y) * tt + (3 * p1.Y - p0.Y - 3 * p2.Y + p3.Y) * ttt) }; smoothedPath.LineTo(mid.X, mid.Y); smoothedPoints.Add(mid); } // add p2 smoothedPath.LineTo(p2.X, p2.Y); smoothedPoints.Add(p2); } // add the last point var last = currentPoints[currentPoints.Count - 1]; smoothedPath.LineTo(last.X, last.Y); smoothedPoints.Add(last); }
public void FillPolygon(Brush brush, Point[] points) { APaint.Color = brush.Color.AColor(); APaint.Flags = (Android.Graphics.PaintFlags)0; APaint.Flags = Flags; APaint.SetStyle(Android.Graphics.Paint.Style.Fill); APaint.StrokeWidth = LineWidth; var p = new Android.Graphics.Path(); p.MoveTo(points[0].X, points[0].Y); foreach(var pt in points) p.LineTo(pt.X, pt.Y); ACanvas.DrawPath(p, APaint); p.Dispose(); }
/// <summary> /// Obtain a smoothed path with the specified granularity from the current path using Catmull-Rom spline. /// Also outputs a List of the points corresponding to the smoothed path. /// </summary> /// <remarks> /// Implemented using a modified version of the code in the solution at /// http://stackoverflow.com/questions/8702696/drawing-smooth-curves-methods-needed /// </remarks> public static InkStroke SmoothedPathWithGranularity(InkStroke currentPath, int granularity) { var currentPoints = currentPath.GetPoints().ToList(); // not enough points to smooth effectively, so return the original path and points. if (currentPoints.Count < 4) { return(currentPath); } // create a new bezier path to hold the smoothed path. var smoothedPath = new NativePath(); var smoothedPoints = new List <NativePoint> (); // duplicate the first and last points as control points. currentPoints.Insert(0, currentPoints[0]); currentPoints.Add(currentPoints[currentPoints.Count - 1]); // add the first point smoothedPath.MoveTo(currentPoints[0].X, currentPoints[0].Y); smoothedPoints.Add(currentPoints[0]); for (var index = 1; index < currentPoints.Count - 2; index++) { var p0 = currentPoints[index - 1]; var p1 = currentPoints[index]; var p2 = currentPoints[index + 1]; var p3 = currentPoints[index + 2]; // add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines for (var i = 1; i < granularity; i++) { var t = (float)i * (1f / (float)granularity); var tt = t * t; var ttt = tt * t; // intermediate point var mid = new NativePoint { X = 0.5f * (2f * p1.X + (p2.X - p0.X) * t + (2f * p0.X - 5f * p1.X + 4f * p2.X - p3.X) * tt + (3f * p1.X - p0.X - 3f * p2.X + p3.X) * ttt), Y = 0.5f * (2 * p1.Y + (p2.Y - p0.Y) * t + (2 * p0.Y - 5 * p1.Y + 4 * p2.Y - p3.Y) * tt + (3 * p1.Y - p0.Y - 3 * p2.Y + p3.Y) * ttt) }; smoothedPath.LineTo(mid.X, mid.Y); smoothedPoints.Add(mid); } // add p2 smoothedPath.LineTo(p2.X, p2.Y); smoothedPoints.Add(p2); } // add the last point var last = currentPoints[currentPoints.Count - 1]; smoothedPath.LineTo(last.X, last.Y); smoothedPoints.Add(last); // create the new path with the old attributes #if __ANDROID__ || __IOS__ return(new InkStroke(smoothedPath, smoothedPoints.ToList(), currentPath.Color, currentPath.Width)); #elif WINDOWS_PHONE var da = currentPath.DrawingAttributes; smoothedPath.DrawingAttributes = new DrawingAttributes { Color = da.Color, OutlineColor = da.OutlineColor, Width = da.Width, Height = da.Height, }; return(smoothedPath); #elif WINDOWS_UWP var da = currentPath.DrawingAttributes; var builder = new InkStrokeBuilder(); builder.SetDefaultDrawingAttributes(new InkDrawingAttributes { Color = da.Color, Size = da.Size }); return(builder.CreateStroke(smoothedPath)); #endif }