/// <summary> /// /// </summary> /// <param name="bezier"></param> /// <param name="point"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static bool Contains(XBezier bezier, Vector2 point, double dx, double dy) { Vector2[] vertices = new Vector2[4]; int k; Vector2[] convexHull; vertices[0] = new Vector2(bezier.Point1.X + dx, bezier.Point1.Y + dy); vertices[1] = new Vector2(bezier.Point2.X + dx, bezier.Point2.Y + dy); vertices[2] = new Vector2(bezier.Point3.X + dx, bezier.Point3.Y + dy); vertices[3] = new Vector2(bezier.Point4.X + dx, bezier.Point4.Y + dy); mc.ConvexHull(vertices, out convexHull, out k); return Contains(point.X, point.Y, convexHull, k); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="bezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XBezier bezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = bezier.Style; if (style == null) return; double thickness = style.Thickness / _state.Zoom; double half = thickness / 2.0; Tuple<Brush, Pen> cache = null; Brush fill; Pen stroke; if (_enableStyleCache && _styleCache.TryGetValue(style, out cache)) { fill = cache.Item1; stroke = cache.Item2; } else { fill = CreateBrush(style.Fill); stroke = CreatePen(style, thickness); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fill, stroke)); } PathGeometry pg = null; if (_enableBezierCache && _bezierCache.TryGetValue(bezier, out pg)) { var pf = pg.Figures[0]; pf.StartPoint = new Point(bezier.Point1.X + dx, bezier.Point1.Y + dy); pf.IsFilled = bezier.IsFilled; var bs = pf.Segments[0] as BezierSegment; bs.Point1 = new Point(bezier.Point2.X + dx, bezier.Point2.Y + dy); bs.Point2 = new Point(bezier.Point3.X + dx, bezier.Point3.Y + dy); bs.Point3 = new Point(bezier.Point4.X + dx, bezier.Point4.Y + dy); bs.IsStroked = bezier.IsStroked; } else { var pf = new PathFigure() { StartPoint = new Point(bezier.Point1.X + dx, bezier.Point1.Y + dy), IsFilled = bezier.IsFilled }; var bs = new BezierSegment( new Point(bezier.Point2.X + dx, bezier.Point2.Y + dy), new Point(bezier.Point3.X + dx, bezier.Point3.Y + dy), new Point(bezier.Point4.X + dx, bezier.Point4.Y + dy), bezier.IsStroked); //bs.Freeze(); pf.Segments.Add(bs); //pf.Freeze(); pg = new PathGeometry(); pg.Figures.Add(pf); //pg.Freeze(); if (_enableBezierCache) _bezierCache.Add(bezier, pg); } DrawPathGeometryInternal(_dc, half, fill, stroke, bezier.IsStroked, bezier.IsFilled, pg); }
/// <summary> /// /// </summary> /// <param name="bezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static Vector2[] GetVertices(XBezier bezier, double dx, double dy) { Vector2[] vertices = new Vector2[4]; int k; Vector2[] convexHull; vertices[0] = new Vector2(bezier.Point1.X + dx, bezier.Point1.Y + dy); vertices[1] = new Vector2(bezier.Point2.X + dx, bezier.Point2.Y + dy); vertices[2] = new Vector2(bezier.Point3.X + dx, bezier.Point3.Y + dy); vertices[3] = new Vector2(bezier.Point4.X + dx, bezier.Point4.Y + dy); mc.ConvexHull(vertices, out convexHull, out k); return convexHull.Take(k).ToArray(); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="bezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XBezier bezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush brush = ToSolidBrush(bezier.Style.Fill); Pen pen = ToPen(bezier.Style, _scaleToPage); if (bezier.IsFilled) { var path = new GraphicsPath(); path.AddBezier( _scaleToPage(bezier.Point1.X), _scaleToPage(bezier.Point1.Y), _scaleToPage(bezier.Point2.X), _scaleToPage(bezier.Point2.Y), _scaleToPage(bezier.Point3.X), _scaleToPage(bezier.Point3.Y), _scaleToPage(bezier.Point4.X), _scaleToPage(bezier.Point4.Y)); _gfx.FillPath(brush, path); } if (bezier.IsStroked) { _gfx.DrawBezier( pen, _scaleToPage(bezier.Point1.X), _scaleToPage(bezier.Point1.Y), _scaleToPage(bezier.Point2.X), _scaleToPage(bezier.Point2.Y), _scaleToPage(bezier.Point3.X), _scaleToPage(bezier.Point3.Y), _scaleToPage(bezier.Point4.X), _scaleToPage(bezier.Point4.Y)); } brush.Dispose(); pen.Dispose(); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> public override void LeftDown(double x, double y) { double sx = _editor.Project.Options.SnapToGrid ? Editor.Snap(x, _editor.Project.Options.SnapX) : x; double sy = _editor.Project.Options.SnapToGrid ? Editor.Snap(y, _editor.Project.Options.SnapY) : y; switch (_currentState) { case State.None: { _shape = XBezier.Create( sx, sy, _editor.Project.CurrentStyleLibrary.CurrentStyle, _editor.Project.Options.PointShape, _editor.Project.Options.DefaultIsStroked, _editor.Project.Options.DefaultIsFilled); if (_editor.Project.Options.TryToConnect) { TryToConnectPoint1(_shape as XBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Add(_shape); _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateOne(); Move(_shape as XBezier); _editor.Project.CurrentContainer.HelperLayer.Invalidate(); _currentState = State.One; _editor.CancelAvailable = true; } break; case State.One: { var bezier = _shape as XBezier; if (bezier != null) { bezier.Point3.X = sx; bezier.Point3.Y = sy; bezier.Point4.X = sx; bezier.Point4.Y = sy; if (_editor.Project.Options.TryToConnect) { TryToConnectPoint4(_shape as XBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateTwo(); Move(_shape as XBezier); _editor.Project.CurrentContainer.HelperLayer.Invalidate(); _currentState = State.Two; } } break; case State.Two: { var bezier = _shape as XBezier; if (bezier != null) { bezier.Point2.X = sx; bezier.Point2.Y = sy; if (_editor.Project.Options.TryToConnect) { TryToConnectPoint2(_shape as XBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateThree(); Move(_shape as XBezier); _editor.Project.CurrentContainer.HelperLayer.Invalidate(); _currentState = State.Three; } } break; case State.Three: { var bezier = _shape as XBezier; if (bezier != null) { bezier.Point3.X = sx; bezier.Point3.Y = sy; if (_editor.Project.Options.TryToConnect) { TryToConnectPoint3(_shape as XBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Remove(_shape); Remove(); Finalize(_shape as XBezier); _editor.AddWithHistory(_shape); _currentState = State.None; _editor.CancelAvailable = false; } } break; } }
/// <summary> /// /// </summary> /// <param name="bezier"></param> /// <param name="x"></param> /// <param name="y"></param> public void TryToConnectPoint4(XBezier bezier, double x, double y) { var result = ShapeBounds.HitTest(_editor.Project.CurrentContainer, new Vector2(x, y), _editor.Project.Options.HitTreshold); if (result != null && result is XPoint) { bezier.Point4 = result as XPoint; } }