/// <summary> /// takes in a parsed path and returns a list of points that can be used to draw the path /// </summary> /// <returns>The drawing points.</returns> /// <param name="segments">Segments.</param> public Vector2[] GetDrawingPoints(List <SvgPathSegment> segments, float flatness = 3) { var path = new System.Drawing.Drawing2D.GraphicsPath(); for (var j = 0; j < segments.Count; j++) { var segment = segments[j]; if (segment is SvgMoveToSegment) { path.StartFigure(); } else if (segment is SvgCubicCurveSegment) { var cubicSegment = segment as SvgCubicCurveSegment; path.AddBezier(ToDrawPoint(segment.Start), ToDrawPoint(cubicSegment.FirstCtrlPoint), ToDrawPoint(cubicSegment.SecondCtrlPoint), ToDrawPoint(segment.End)); } else if (segment is SvgClosePathSegment) { // important for custom line caps. Force the path the close with an explicit line, not just an implicit close of the figure. if (path.PointCount > 0 && !path.PathPoints[0].Equals(path.PathPoints[path.PathPoints.Length - 1])) { var i = path.PathTypes.Length - 1; while (i >= 0 && path.PathTypes[i] > 0) { i--; } if (i < 0) { i = 0; } path.AddLine(path.PathPoints[path.PathPoints.Length - 1], path.PathPoints[i]); } path.CloseFigure(); } else if (segment is SvgLineSegment) { path.AddLine(ToDrawPoint(segment.Start), ToDrawPoint(segment.End)); } else if (segment is SvgQuadraticCurveSegment) { var quadSegment = segment as SvgQuadraticCurveSegment; path.AddBezier(ToDrawPoint(segment.Start), ToDrawPoint(quadSegment.FirstCtrlPoint), ToDrawPoint(quadSegment.SecondCtrlPoint), ToDrawPoint(segment.End)); } else { Debug.Warn("unknown type in getDrawingPoints"); } } path.Flatten(new System.Drawing.Drawing2D.Matrix(), flatness); return(System.Array.ConvertAll(path.PathPoints, i => new Vector2(i.X, i.Y))); }
/// <summary> /// Returns a GraphicsPath which represent a rounded rectangle. /// </summary> /// <param name="r">Rectangle that contains logically the rounded rectangle.</param> /// <param name="r1"></param> /// <param name="r2"></param> /// <param name="r3"></param> /// <param name="r4"></param> /// <returns></returns> private System.Drawing.Drawing2D.GraphicsPath GetRoundedRect(Rectangle r, float r1, float r2, float r3, float r4) { float X = r.X, Y = r.Y, w = r.Width, h = r.Height; System.Drawing.Drawing2D.GraphicsPath rr = new System.Drawing.Drawing2D.GraphicsPath(); rr.AddBezier(X, Y + r1, X, Y, X + r1, Y, X + r1, Y); rr.AddLine(X + r1, Y, X + w - r2, Y); rr.AddBezier(X + w - r2, Y, X + w, Y, X + w, Y + r2, X + w, Y + r2); rr.AddLine(X + w, Y + r2, X + w, Y + h - r3); rr.AddBezier(X + w, Y + h - r3, X + w, Y + h, X + w - r3, Y + h, X + w - r3, Y + h); rr.AddLine(X + w - r3, Y + h, X + r4, Y + h); rr.AddBezier(X + r4, Y + h, X, Y + h, X, Y + h - r4, X, Y + h - r4); rr.AddLine(X, Y + h - r4, X, Y + r1); return(rr); }
/// <summary> /// takes in a parsed path and returns a list of points that can be used to draw the path /// </summary> /// <returns>The drawing points.</returns> /// <param name="segments">Segments.</param> public Vector2[] getDrawingPoints( List<SvgPathSegment> segments, float flatness = 3 ) { var path = new System.Drawing.Drawing2D.GraphicsPath(); for( var j = 0; j < segments.Count; j++ ) { var segment = segments[j]; if( segment is SvgMoveToSegment ) { path.StartFigure(); } else if( segment is SvgCubicCurveSegment ) { var cubicSegment = segment as SvgCubicCurveSegment; path.AddBezier( toDrawPoint( segment.start ), toDrawPoint( cubicSegment.firstCtrlPoint ), toDrawPoint( cubicSegment.secondCtrlPoint ), toDrawPoint( segment.end ) ); } else if( segment is SvgClosePathSegment ) { // important for custom line caps. Force the path the close with an explicit line, not just an implicit close of the figure. if( path.PointCount > 0 && !path.PathPoints[0].Equals( path.PathPoints[path.PathPoints.Length - 1] ) ) { var i = path.PathTypes.Length - 1; while( i >= 0 && path.PathTypes[i] > 0 ) i--; if( i < 0 ) i = 0; path.AddLine( path.PathPoints[path.PathPoints.Length - 1], path.PathPoints[i] ); } path.CloseFigure(); } else if( segment is SvgLineSegment ) { path.AddLine( toDrawPoint( segment.start ), toDrawPoint( segment.end ) ); } else if( segment is SvgQuadraticCurveSegment ) { var quadSegment = segment as SvgQuadraticCurveSegment; path.AddBezier( toDrawPoint( segment.start ), toDrawPoint( quadSegment.firstCtrlPoint ), toDrawPoint( quadSegment.secondCtrlPoint ), toDrawPoint( segment.end ) ); } else { Debug.warn( "unknown type in getDrawingPoints" ); } } path.Flatten( new System.Drawing.Drawing2D.Matrix(), flatness ); return System.Array.ConvertAll( path.PathPoints, i => new Vector2( i.X, i.Y ) ); }
private static void AddSegmentToPath(ICurve seg, ref System.Drawing.Drawing2D.GraphicsPath p) { const float radiansToDegrees = (float)(180.0 / Math.PI); LineSegment line = seg as LineSegment; if (line != null) { p.AddLine(PointF(line.Start), PointF(line.End)); } else { CubicBezierSegment cb = seg as CubicBezierSegment; if (cb != null) { p.AddBezier(PointF(cb.B(0)), PointF(cb.B(1)), PointF(cb.B(2)), PointF(cb.B(3))); } else { Ellipse ellipse = seg as Ellipse; if (ellipse != null) { p.AddArc((float)(ellipse.Center.X - ellipse.AxisA.Length), (float)(ellipse.Center.Y - ellipse.AxisB.Length), (float)(2 * ellipse.AxisA.Length), (float)(2 * ellipse.AxisB.Length), (float)(ellipse.ParStart * radiansToDegrees), (float)((ellipse.ParEnd - ellipse.ParStart) * radiansToDegrees)); } } } }
public override void AddBezierCurve(PointF p1, PointF p2, PointF p3, PointF p4) { p.AddBezier( p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y, p4.X, p4.Y); }
public static System.Drawing.Drawing2D.GraphicsPath DrawRoundRect(Rectangle r, int r1, int r2, int r3, int r4) { float x = r.X; float y = r.Y; float width = r.Width; float height = r.Height; System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); path.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y); path.AddLine(x + r1, y, (x + width) - r2, y); path.AddBezier((x + width) - r2, y, x + width, y, x + width, y + r2, x + width, y + r2); path.AddLine((float)(x + width), (float)(y + r2), (float)(x + width), (float)((y + height) - r3)); path.AddBezier((float)(x + width), (float)((y + height) - r3), (float)(x + width), (float)(y + height), (float)((x + width) - r3), (float)(y + height), (float)((x + width) - r3), (float)(y + height)); path.AddLine((float)((x + width) - r3), (float)(y + height), (float)(x + r4), (float)(y + height)); path.AddBezier(x + r4, y + height, x, y + height, x, (y + height) - r4, x, (y + height) - r4); path.AddLine(x, (y + height) - r4, x, y + r1); return path; }
public override void AddToPath(System.Drawing.Drawing2D.GraphicsPath path, EPoint ptStart, float scale) { System.Collections.ArrayList pts = this.GeneratePoints(ptStart); path.AddBezier( ((EPointF)pts[0]).X * scale, ((EPointF)pts[0]).Y * scale, ((EPointF)pts[1]).X * scale, ((EPointF)pts[1]).Y * scale, ((EPointF)pts[2]).X * scale, ((EPointF)pts[2]).Y * scale, ((EPointF)pts[3]).X * scale, ((EPointF)pts[3]).Y * scale); }
public static System.Drawing.Drawing2D.GraphicsPath DrawRoundRect(Rectangle r, int r1, int r2, int r3, int r4) { float x = r.X; float y = r.Y; float width = r.Width; float height = r.Height; System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); path.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y); path.AddLine(x + r1, y, (x + width) - r2, y); path.AddBezier((x + width) - r2, y, x + width, y, x + width, y + r2, x + width, y + r2); path.AddLine((float)(x + width), (float)(y + r2), (float)(x + width), (float)((y + height) - r3)); path.AddBezier((float)(x + width), (float)((y + height) - r3), (float)(x + width), (float)(y + height), (float)((x + width) - r3), (float)(y + height), (float)((x + width) - r3), (float)(y + height)); path.AddLine((float)((x + width) - r3), (float)(y + height), (float)(x + r4), (float)(y + height)); path.AddBezier(x + r4, y + height, x, y + height, x, (y + height) - r4, x, (y + height) - r4); path.AddLine(x, (y + height) - r4, x, y + r1); return(path); }
protected override void OnPaint(PaintEventArgs pe) { using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath()) { path.AddBezier(this.Width >> 1, this.Height >> 2, this.Width * 1.25f, 0f, this.Width, this.Height * 0.75f, this.Width >> 1, this.Height); path.AddBezier(this.Width >> 1, this.Height >> 2, -this.Width * .25f, 0f, 0f, this.Height * 0.75f, this.Width >> 1, this.Height); this.Region = new Region(path); } }
public void Curve3(double p2x, double p2y, double x, double y) { //from http://stackoverflow.com/questions/9485788/convert-quadratic-curve-to-cubic-curve //Control1X = StartX + (.66 * (ControlX - StartX)) //Control2X = EndX + (.66 * (ControlX - EndX)) float c1x = lastX + (float)((2f / 3f) * (p2x - lastX)); float c1y = lastY + (float)((2f / 3f) * (p2y - lastY)); //--------------------------------------------------------------------- float c2x = (float)(x + ((2f / 3f) * (p2x - x))); float c2y = (float)(y + ((2f / 3f) * (p2y - y))); //--------------------------------------------------------------------- ps.AddBezier( new PointF(lastX, lastY), new PointF(c1x, c1y), new PointF(c2x, c2y), new PointF(lastX = (float)x, lastY = (float)y)); }
protected void AddBezierPath(System.Drawing.Drawing2D.GraphicsPath path, Point pstart, Point pend, bool sside, bool eside) { Point ctrl1 = new Point(pstart.X, pstart.Y + Height / 2); Point ctrl2 = new Point(pend.X, pend.Y - Height / 2); if (sside) { if (pend.X < pstart.X) { ctrl1 = new Point(pstart.X - Width / 2, pstart.Y); } else { ctrl1 = new Point(pstart.X + Width / 2, pstart.Y); } } else { if (pend.Y < pstart.Y) { ctrl1 = new Point(pstart.X, pstart.Y - Height / 2); } } if (this.EndElement.Docks[this.EndAnchor].IsSideDock) { if (pend.X < pstart.X) { ctrl2 = new Point(pend.X + Width / 2, pend.Y); } else { ctrl2 = new Point(pend.X - Width / 2, pend.Y); } } else { if (pend.Y < pstart.Y) { ctrl2 = new Point(pend.X, pend.Y + Height / 2); } } path.AddBezier( pstart.X, pstart.Y, ctrl1.X, ctrl1.Y, ctrl2.X, ctrl2.Y, pend.X, pend.Y); }
void Test1() { for (int i = 0; i < 10; ++i) { Point p0 = new Point(0, 0); Point p1 = new Point(20, 50); Point p2 = new Point(80, 50); Point p3 = new Point(100, i * 10); g.DrawRectangle(Pens.Red, new Rectangle(p0, new System.Drawing.Size(1, 1))); g.DrawRectangle(Pens.Green, new Rectangle(p1, new System.Drawing.Size(1, 1))); g.DrawRectangle(Pens.Green, new Rectangle(p2, new System.Drawing.Size(1, 1))); g.DrawRectangle(Pens.Red, new Rectangle(p3, new System.Drawing.Size(1, 1))); System.Drawing.Drawing2D.GraphicsPath p = new System.Drawing.Drawing2D.GraphicsPath(); p.AddBezier(p0, p1, p2, p3); g.DrawPath(Pens.Black, p); } }
static System.Drawing.Drawing2D.GraphicsPath ResolveGraphicsPath(GraphicsPath path) { //convert from graphics path to internal presentation System.Drawing.Drawing2D.GraphicsPath innerPath = path.InnerPath as System.Drawing.Drawing2D.GraphicsPath; if (innerPath != null) { return(innerPath); } //-------- innerPath = new System.Drawing.Drawing2D.GraphicsPath(); path.InnerPath = innerPath; List <float> points; List <PathCommand> cmds; GraphicsPath.GetPathData(path, out points, out cmds); int j = cmds.Count; int p_index = 0; for (int i = 0; i < j; ++i) { PathCommand cmd = cmds[i]; switch (cmd) { default: throw new NotSupportedException(); case PathCommand.Arc: innerPath.AddArc( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5]); p_index += 6; break; case PathCommand.Bezier: innerPath.AddBezier( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5], points[p_index + 6], points[p_index + 7]); p_index += 8; break; case PathCommand.CloseFigure: innerPath.CloseFigure(); break; case PathCommand.Ellipse: innerPath.AddEllipse( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Line: innerPath.AddLine( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Rect: innerPath.AddRectangle( new System.Drawing.RectangleF( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3])); p_index += 4; break; case PathCommand.StartFigure: break; } } return(innerPath); }
public override void AddToPath(System.Drawing.Drawing2D.GraphicsPath graphicsPath) { graphicsPath.AddBezier(this.Start, this.FirstControlPoint, this.SecondControlPoint, this.End); }
static System.Drawing.Drawing2D.GraphicsPath ResolveGraphicsPath(GraphicsPath path) { //convert from graphics path to internal presentation System.Drawing.Drawing2D.GraphicsPath innerPath = path.InnerPath as System.Drawing.Drawing2D.GraphicsPath; if (innerPath != null) { return innerPath; } //-------- innerPath = new System.Drawing.Drawing2D.GraphicsPath(); path.InnerPath = innerPath; List<float> points; List<PathCommand> cmds; GraphicsPath.GetPathData(path, out points, out cmds); int j = cmds.Count; int p_index = 0; for (int i = 0; i < j; ++i) { PathCommand cmd = cmds[i]; switch (cmd) { default: throw new NotSupportedException(); case PathCommand.Arc: innerPath.AddArc( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5]); p_index += 6; break; case PathCommand.Bezier: innerPath.AddBezier( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5], points[p_index + 6], points[p_index + 7]); p_index += 8; break; case PathCommand.CloseFigure: innerPath.CloseFigure(); break; case PathCommand.Ellipse: innerPath.AddEllipse( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Line: innerPath.AddLine( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Rect: innerPath.AddRectangle( new System.Drawing.RectangleF( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3])); p_index += 4; break; case PathCommand.StartFigure: break; } } return innerPath; }
public override void AddToPath(System.Drawing.Drawing2D.GraphicsPath path) { path.AddBezier(ptStart, ptControl1, ptControl2, ptEnd); }
/// <summary> /// Fill a closed path composed of several drawing operations /// </summary> /// <param name="canvas"></param> public void Fill(System.Drawing.Graphics canvas) { System.Drawing.Drawing2D.GraphicsPath path; path = new System.Drawing.Drawing2D.GraphicsPath(); for (int i = 0; i < m_drawings.Count; i++) { switch (m_drawings[i].Type) { case DrawingType.Line: { path.AddLine(m_drawings[i].Points[0].x, m_drawings[i].Points[0].y, m_drawings[i].Points[1].x, m_drawings[i].Points[1].y); break; } case DrawingType.Arc: { double startAngle, endAngle; startAngle = System.Math.Atan2(m_drawings[i].Points[2].y - (m_drawings[i].Points[1].y + m_drawings[i].Points[0].y) / 2, m_drawings[i].Points[2].x - (m_drawings[i].Points[1].x + m_drawings[i].Points[0].x) / 2); if (startAngle < 0) { startAngle += System.Math.PI * 2; } startAngle = (startAngle / Math.PI) * 180; endAngle = System.Math.Atan2(m_drawings[i].Points[3].y - (m_drawings[i].Points[1].y + m_drawings[i].Points[0].y) / 2, m_drawings[i].Points[3].x - (m_drawings[i].Points[1].x + m_drawings[i].Points[0].x) / 2); if (endAngle < 0) { endAngle += System.Math.PI * 2; } endAngle = (endAngle / Math.PI) * 180; path.AddArc(m_drawings[i].Points[0].x, m_drawings[i].Points[0].y, m_drawings[i].Points[1].x - m_drawings[i].Points[0].x, m_drawings[i].Points[1].y - m_drawings[i].Points[0].y, (float)startAngle, Math.Abs((float)(endAngle - startAngle))); break; } case DrawingType.Bezier: { path.AddBezier(m_drawings[i].Points[0].x, m_drawings[i].Points[0].y, m_drawings[i].Points[2].x, m_drawings[i].Points[2].y, m_drawings[i].Points[3].x, m_drawings[i].Points[3].y, m_drawings[i].Points[1].x, m_drawings[i].Points[1].y); break; } } } canvas.FillPath(m_style.fillingStyle, path); }