public void CloseContour() { if (_isOpen) { _context.EndFigure(true); _isOpen = false; } }
// 在此覆写方法中实现图形 protected override Geometry CreateDefiningGeometry() { StreamGeometry streamGeometry = new StreamGeometry(); using (StreamGeometryContext context = streamGeometry.Open()) { double X1 = StartPoint.X; double X2 = EndPoint.X; double Y1 = StartPoint.Y; double Y2 = EndPoint.Y; // 往右走一部分的点 double X1Right = X1 + RightBias; double X2Right = X2 + RightBias; //(X1,Y1)--------(X1Right,Y1) // | // | // | //(X2,Y2)<|------(X2Right,Y2) // 这里要计算的角就是下侧的边了 double theta = Math.Atan2(Y2 - Y2, X2Right - X2); double sint = Math.Sin(theta); double cost = Math.Cos(theta); Point pt1 = new Point(X1, Y1); Point pt2 = new Point(X1Right, Y1); Point pt3 = new Point(X2Right, Y2); Point pt4 = new Point(X2, Y2); double HeadWidth = this.HeadWidth; double HeadHeight = this.HeadHeight; // 箭帽的两个点 Point pt5 = new Point( X2 + (HeadWidth * cost - HeadHeight * sint), Y2 + (HeadWidth * sint + HeadHeight * cost)); Point pt6 = new Point( X2 + (HeadWidth * cost + HeadHeight * sint), Y2 - (HeadHeight * cost - HeadWidth * sint)); context.BeginFigure(pt1, false); context.LineTo(pt2); context.LineTo(pt3); context.LineTo(pt4); context.LineTo(pt3); // 这里回到pt3和到pt2是避免从pt4闭合到pt1导致一大块Fill context.LineTo(pt2); context.EndFigure(false); context.BeginFigure(pt5, true); // 带填充 context.LineTo(pt4); context.LineTo(pt6); context.EndFigure(true); // 箭帽闭合 Fill = Brushes.Black; } return(streamGeometry); }
public override void MoveTo(float x0, float y0) { if (_isOpen) { _context.EndFigure(false); _isOpen = false; } // The second parameter does nothing on Skia: https://github.com/AvaloniaUI/Avalonia/issues/1419 _context.BeginFigure(new Point(x0, y0), _canvas.CurrentStyle == PaintStyle.Fill); }
// 在此覆写方法中实现图形 protected override Geometry CreateDefiningGeometry() { StreamGeometry streamGeometry = new StreamGeometry(); using (StreamGeometryContext context = streamGeometry.Open()) { // -- // | | //------ //| | //------ // 画锁圈 Point pt1 = new Point(Width / 4, Height / 2); Point pt2 = new Point(Width / 4, 0); Point pt3 = new Point(Width / 4 * 3, 0); Point pt4 = new Point(Width / 4 * 3, Height / 2); context.BeginFigure(pt1, false); context.LineTo(pt2); context.LineTo(pt3); context.LineTo(pt4); context.EndFigure(false); // 画锁体 Point pt5 = new Point(0, Height / 2); Point pt6 = new Point(Width, Height / 2); Point pt7 = new Point(Width, Height); Point pt8 = new Point(0, Height); context.BeginFigure(pt5, false); context.LineTo(pt6); context.LineTo(pt7); context.LineTo(pt8); context.EndFigure(true); // 画锁上X //context.BeginFigure(pt5, false); //context.LineTo(pt7); //context.EndFigure(false); //context.BeginFigure(pt6, false); //context.LineTo(pt8); //context.EndFigure(false); } return(streamGeometry); }
// 在此覆写方法中实现图形 protected override Geometry CreateDefiningGeometry() { StreamGeometry streamGeometry = new StreamGeometry(); using (StreamGeometryContext context = streamGeometry.Open()) { double X1 = StartPoint.X; double X2 = EndPoint.X; double Y1 = StartPoint.Y; double Y2 = EndPoint.Y; double theta = Math.Atan2(Y1 - Y2, X1 - X2); double sint = Math.Sin(theta); double cost = Math.Cos(theta); Point pt1 = new Point(X1, Y1); Point pt2 = new Point(X2, Y2); double HeadWidth = this.HeadWidth; double HeadHeight = this.HeadHeight; Point pt3 = new Point( X2 + (HeadWidth * cost - HeadHeight * sint), Y2 + (HeadWidth * sint + HeadHeight * cost)); Point pt4 = new Point( X2 + (HeadWidth * cost + HeadHeight * sint), Y2 - (HeadHeight * cost - HeadWidth * sint)); // 绘制直线 context.BeginFigure(pt1, false); context.LineTo(pt2); context.EndFigure(false); // 绘制封闭三角 context.BeginFigure(pt2, true); context.LineTo(pt3); context.LineTo(pt4); context.EndFigure(true); Fill = Brushes.Black; } return(streamGeometry); }
private static void CreateGeometry(StreamGeometryContext context, Rect boundRect, BorderGeometryKeypoints keypoints) { context.BeginFigure(keypoints.TopLeft, true); // Top context.LineTo(keypoints.TopRight); // TopRight corner var radiusX = boundRect.TopRight.X - keypoints.TopRight.X; var radiusY = keypoints.RightTop.Y - boundRect.TopRight.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(keypoints.RightTop, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } // Right context.LineTo(keypoints.RightBottom); // BottomRight corner radiusX = boundRect.BottomRight.X - keypoints.BottomRight.X; radiusY = boundRect.BottomRight.Y - keypoints.RightBottom.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(keypoints.BottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } // Bottom context.LineTo(keypoints.BottomLeft); // BottomLeft corner radiusX = keypoints.BottomLeft.X - boundRect.BottomLeft.X; radiusY = boundRect.BottomLeft.Y - keypoints.LeftBottom.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(keypoints.LeftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } // Left context.LineTo(keypoints.LeftTop); // TopLeft corner radiusX = keypoints.TopLeft.X - boundRect.TopLeft.X; radiusY = keypoints.LeftTop.Y - boundRect.TopLeft.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(keypoints.TopLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } context.EndFigure(true); }
public void AddPathSegment(StreamGeometryContext canvasPathBuilder, ref bool closed) { if (!closed) { canvasPathBuilder.EndFigure(false); } else { closed = false; } canvasPathBuilder.BeginFigure(new Point(_points[0], _points[1]), true); }
private void DrawPolygonsByStreamGeometry( IList <IList <ScreenPoint> > polygons, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray, LineJoin lineJoin) { Path path = null; StreamGeometry streamGeometry = null; StreamGeometryContext sgc = null; var count = 0; Func <ScreenPoint, Point> toPointFunc; if (edgeRenderingMode == EdgeRenderingMode.PreferSpeed) // aliased { toPointFunc = ToPixelAlignedPoint; } else { toPointFunc = ToPoint; } bool isSolid = !fill.IsUndefined(); IBrush cachedBrush = null; if (isSolid) { cachedBrush = GetCachedBrush(fill); } foreach (var polygon in polygons) { if (path == null) { path = CreateAndAdd <Path>(); SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0); if (isSolid) { path.Fill = cachedBrush; } streamGeometry = new StreamGeometry(); sgc = streamGeometry.Open(); sgc.SetFillRule(FillRule.NonZero); } var first = true; foreach (var p in polygon) { if (first) { sgc.BeginFigure(toPointFunc(p), isSolid); first = false; } else { sgc.LineTo(toPointFunc(p)); } } sgc.EndFigure(true); count++; // Must limit the number of figures, otherwise drawing errors... if (count > MaxFiguresPerGeometry) { sgc.Dispose(); path.Data = streamGeometry; path = null; count = 0; } } if (path != null) { sgc.Dispose(); path.Data = streamGeometry; } }
private void DrawEllipsesByStreamGeometry( IList <OxyRect> rects, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray, LineJoin lineJoin) { const double ratio = 0.55228475; // (Math.Sqrt(2) - 1.0) * 4.0 / 3.0; Path path = null; StreamGeometry streamGeometry = null; StreamGeometryContext sgc = null; var count = 0; bool isSolid = !fill.IsUndefined(); IBrush cachedBrush = null; if (isSolid) { cachedBrush = GetCachedBrush(fill); } foreach (var rect in rects) { if (path == null) { path = CreateAndAdd <Path>(); SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0); if (isSolid) { path.Fill = cachedBrush; } streamGeometry = new StreamGeometry(); sgc = streamGeometry.Open(); sgc.SetFillRule(FillRule.NonZero); } var a = rect.Width / 2.0; var b = rect.Height / 2.0; var x0 = rect.Center.X - a; var x1 = rect.Center.X - a * ratio; var x2 = rect.Center.X; var x3 = rect.Center.X + a * ratio; var x4 = rect.Center.X + a; var y0 = rect.Center.Y - b; var y1 = rect.Center.Y - b * ratio; var y2 = rect.Center.Y; var y3 = rect.Center.Y + b * ratio; var y4 = rect.Center.Y + b; sgc.BeginFigure(new Point(x2, y0), isSolid); sgc.CubicBezierTo(new Point(x3, y0), new Point(x4, y1), new Point(x4, y2)); sgc.CubicBezierTo(new Point(x4, y3), new Point(x3, y4), new Point(x2, y4)); sgc.CubicBezierTo(new Point(x1, y4), new Point(x0, y3), new Point(x0, y2)); sgc.CubicBezierTo(new Point(x0, y1), new Point(x1, y0), new Point(x2, y0)); sgc.EndFigure(true); count++; // Must limit the number of figures, otherwise drawing errors... if (count > MaxFiguresPerGeometry) { sgc.Dispose(); path.Data = streamGeometry; path = null; count = 0; } } if (path != null) { sgc.Dispose(); path.Data = streamGeometry; } }
/// <summary> /// Close the geometry to so no more path adding is allowed and return the instance so it can be rendered. /// </summary> public StreamGeometry GetClosedGeometry() { _geometryContext.EndFigure(true); _geometryContext.Dispose(); return(_geometry); }
private static void CreateGeometry(StreamGeometryContext context, Rect boundRect, BorderCoordinates borderCoordinates) { var topLeft = new Point(borderCoordinates.LeftTop, 0); var topRight = new Point(boundRect.Width - borderCoordinates.RightTop, 0); var rightTop = new Point(boundRect.Width, borderCoordinates.TopRight); var rightBottom = new Point(boundRect.Width, boundRect.Height - borderCoordinates.BottomRight); var bottomRight = new Point(boundRect.Width - borderCoordinates.RightBottom, boundRect.Height); var bottomLeft = new Point(borderCoordinates.LeftBottom, boundRect.Height); var leftBottom = new Point(0, boundRect.Height - borderCoordinates.BottomLeft); var leftTop = new Point(0, borderCoordinates.TopLeft); if (topLeft.X > topRight.X) { var scaledX = borderCoordinates.LeftTop / (borderCoordinates.LeftTop + borderCoordinates.RightTop) * boundRect.Width; topLeft = new Point(scaledX, topLeft.Y); topRight = new Point(scaledX, topRight.Y); } if (rightTop.Y > rightBottom.Y) { var scaledY = borderCoordinates.TopRight / (borderCoordinates.TopRight + borderCoordinates.BottomRight) * boundRect.Height; rightTop = new Point(rightTop.X, scaledY); rightBottom = new Point(rightBottom.X, scaledY); } if (bottomRight.X < bottomLeft.X) { var scaledX = borderCoordinates.LeftBottom / (borderCoordinates.LeftBottom + borderCoordinates.RightBottom) * boundRect.Width; bottomRight = new Point(scaledX, bottomRight.Y); bottomLeft = new Point(scaledX, bottomLeft.Y); } if (leftBottom.Y < leftTop.Y) { var scaledY = borderCoordinates.TopLeft / (borderCoordinates.TopLeft + borderCoordinates.BottomLeft) * boundRect.Height; leftBottom = new Point(leftBottom.X, scaledY); leftTop = new Point(leftTop.X, scaledY); } var offset = new Vector(boundRect.TopLeft.X, boundRect.TopLeft.Y); topLeft += offset; topRight += offset; rightTop += offset; rightBottom += offset; bottomRight += offset; bottomLeft += offset; leftBottom += offset; leftTop += offset; context.BeginFigure(topLeft, true); //Top context.LineTo(topRight); //TopRight corner var radiusX = boundRect.TopRight.X - topRight.X; var radiusY = rightTop.Y - boundRect.TopRight.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(rightTop, new Size(radiusY, radiusY), 0, false, SweepDirection.Clockwise); } //Right context.LineTo(rightBottom); //BottomRight corner radiusX = boundRect.BottomRight.X - bottomRight.X; radiusY = boundRect.BottomRight.Y - rightBottom.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(bottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } //Bottom context.LineTo(bottomLeft); //BottomLeft corner radiusX = bottomLeft.X - boundRect.BottomLeft.X; radiusY = boundRect.BottomLeft.Y - leftBottom.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(leftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } //Left context.LineTo(leftTop); //TopLeft corner radiusX = topLeft.X - boundRect.TopLeft.X; radiusY = leftTop.Y - boundRect.TopLeft.Y; if (radiusX != 0 || radiusY != 0) { context.ArcTo(topLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise); } context.EndFigure(true); }
public void AddPathSegment(StreamGeometryContext canvasPathBuilder, ref bool closed) { canvasPathBuilder.EndFigure(closed); closed = true; }