public override void AddShape(WpfPoint point, WpfStreamGeometryContext sgc) { var start = new WpfPoint(point.X, point.Y - Size * 0.5); sgc.BeginFigure(start, true, true); sgc.ArcTo(start, new Size(Size, Size), 360, true, WpfSweepDirection.Clockwise, true, true); }
static void AddArrow(WStreamGeometryContext context, MPoint start, MPoint end, double thickness) { if (thickness > 1) { MPoint dir = end - start; MPoint h = dir; double dl = dir.Length; if (dl < 0.001) { return; } dir /= dl; var s = new MPoint(-dir.Y, dir.X); double w = 0.5 * thickness; MPoint s0 = w * s; s *= h.Length * HalfArrowAngleTan; s += s0; double rad = w / HalfArrowAngleCos; context.BeginFigure(Common.WpfPoint(start + s), true, true); context.LineTo(Common.WpfPoint(start - s), true, false); context.LineTo(Common.WpfPoint(end - s0), true, false); context.ArcTo(Common.WpfPoint(end + s0), new WSize(rad, rad), Math.PI - ArrowAngle, false, WSweepDirection.Clockwise, true, false); } else { MPoint dir = end - start; double dl = dir.Length; //take into account the widths double delta = Math.Min(dl / 2, thickness + thickness / 2); dir *= (dl - delta) / dl; end = start + dir; dir = dir.Rotate(Math.PI / 2); MPoint s = dir * HalfArrowAngleTan; context.BeginFigure(Common.WpfPoint(start + s), true, true); context.LineTo(Common.WpfPoint(end), true, true); context.LineTo(Common.WpfPoint(start - s), true, true); } }
static void FillContexForCurve(WStreamGeometryContext context, Curve c) { foreach (ICurve seg in c.Segments) { var bezSeg = seg as CubicBezierSegment; if (bezSeg != null) { context.BezierTo(Common.WpfPoint(bezSeg.B(1)), Common.WpfPoint(bezSeg.B(2)), Common.WpfPoint(bezSeg.B(3)), true, false); } else { var ls = seg as MLineSegment; if (ls != null) { context.LineTo(Common.WpfPoint(ls.End), true, false); } else { var ellipse = seg as MEllipse; if (ellipse != null) { double sweepAngle = EllipseSweepAngle(ellipse); bool largeArc = Math.Abs(sweepAngle) >= Math.PI; MRectangle box = ellipse.FullBox(); context.ArcTo(Common.WpfPoint(ellipse.End), new WSize(box.Width / 2, box.Height / 2), sweepAngle, largeArc, sweepAngle < 0 ? WSweepDirection.Counterclockwise : WSweepDirection.Clockwise, true, true); } else { throw new NotImplementedException(); } } } } }
internal static void FillContextForICurve(WStreamGeometryContext context, ICurve iCurve) { context.BeginFigure(Common.WpfPoint(iCurve.Start), false, false); var c = iCurve as Curve; if (c != null) { FillContexForCurve(context, c); } else { var cubicBezierSeg = iCurve as CubicBezierSegment; if (cubicBezierSeg != null) { context.BezierTo(Common.WpfPoint(cubicBezierSeg.B(1)), Common.WpfPoint(cubicBezierSeg.B(2)), Common.WpfPoint(cubicBezierSeg.B(3)), true, false); } else { var ls = iCurve as MLineSegment; if (ls != null) { context.LineTo(Common.WpfPoint(ls.End), true, false); } else { var rr = iCurve as RoundedRect; if (rr != null) { FillContexForCurve(context, rr.Curve); } else { var poly = iCurve as MPolyline; if (poly != null) { FillContexForPolyline(context, poly); } else { var ellipse = iCurve as MEllipse; if (ellipse != null) { double sweepAngle = EllipseSweepAngle(ellipse); bool largeArc = Math.Abs(sweepAngle) >= Math.PI; MRectangle box = ellipse.FullBox(); context.ArcTo(Common.WpfPoint(ellipse.End), new WSize(box.Width / 2, box.Height / 2), sweepAngle, largeArc, sweepAngle < 0 ? WSweepDirection.Counterclockwise : WSweepDirection.Clockwise, true, true); } else { throw new NotImplementedException(); } } } } } } }