/// <summary> /// /// </summary> /// <param name="qbezier"></param> /// <param name="x"></param> /// <param name="y"></param> public void TryToConnectPoint3(XQBezier qbezier, 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) { qbezier.Point3 = result as XPoint; } }
/// <summary> /// /// </summary> /// <param name="qbezier"></param> /// <param name="point"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static bool Contains(XQBezier qbezier, Vector2 point, double dx, double dy) { Vector2[] vertices = new Vector2[3]; int k; Vector2[] convexHull; vertices[0] = new Vector2(qbezier.Point1.X + dx, qbezier.Point1.Y + dy); vertices[1] = new Vector2(qbezier.Point2.X + dx, qbezier.Point2.Y + dy); vertices[2] = new Vector2(qbezier.Point3.X + dx, qbezier.Point3.Y + dy); mc.ConvexHull(vertices, out convexHull, out k); return Contains(point.X, point.Y, convexHull, k); }
/// <summary> /// /// </summary> /// <param name="qbezier"></param> /// <param name="point"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static bool Contains(XQBezier qbezier, Vector2 point, double dx, double dy) { Vector2[] vertices = new Vector2[3]; int k; Vector2[] convexHull; vertices[0] = new Vector2(qbezier.Point1.X + dx, qbezier.Point1.Y + dy); vertices[1] = new Vector2(qbezier.Point2.X + dx, qbezier.Point2.Y + dy); vertices[2] = new Vector2(qbezier.Point3.X + dx, qbezier.Point3.Y + dy); mc.ConvexHull(vertices, out convexHull, out k); return(Contains(point.X, point.Y, convexHull, k)); }
/// <summary> /// /// </summary> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static Vector2[] GetVertices(XQBezier qbezier, double dx, double dy) { Vector2[] vertices = new Vector2[3]; int k; Vector2[] convexHull; vertices[0] = new Vector2(qbezier.Point1.X + dx, qbezier.Point1.Y + dy); vertices[1] = new Vector2(qbezier.Point2.X + dx, qbezier.Point2.Y + dy); vertices[2] = new Vector2(qbezier.Point3.X + dx, qbezier.Point3.Y + dy); mc.ConvexHull(vertices, out convexHull, out k); return(convexHull.Take(k).ToArray()); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XQBezier qbezier, double dx, double dy, ImmutableArray <ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush brush = ToSolidBrush(qbezier.Style.Fill); Pen pen = ToPen(qbezier.Style, _scaleToPage); double x1 = qbezier.Point1.X; double y1 = qbezier.Point1.Y; double x2 = qbezier.Point1.X + (2.0 * (qbezier.Point2.X - qbezier.Point1.X)) / 3.0; double y2 = qbezier.Point1.Y + (2.0 * (qbezier.Point2.Y - qbezier.Point1.Y)) / 3.0; double x3 = x2 + (qbezier.Point3.X - qbezier.Point1.X) / 3.0; double y3 = y2 + (qbezier.Point3.Y - qbezier.Point1.Y) / 3.0; double x4 = qbezier.Point3.X; double y4 = qbezier.Point3.Y; if (qbezier.IsFilled) { var path = new GraphicsPath(); path.AddBezier( _scaleToPage(x1 + dx), _scaleToPage(y1 + dy), _scaleToPage(x2 + dx), _scaleToPage(y2 + dy), _scaleToPage(x3 + dx), _scaleToPage(y3 + dy), _scaleToPage(x4 + dx), _scaleToPage(y4 + dy)); _gfx.FillPath(brush, path); } if (qbezier.IsStroked) { _gfx.DrawBezier( pen, _scaleToPage(x1 + dx), _scaleToPage(y1 + dy), _scaleToPage(x2 + dx), _scaleToPage(y2 + dy), _scaleToPage(x3 + dx), _scaleToPage(y3 + dy), _scaleToPage(x4 + dx), _scaleToPage(y4 + dy)); } brush.Dispose(); pen.Dispose(); }
/// <summary> /// Creates a new instance of the XQBezier class. /// </summary> /// <param name="point1"></param> /// <param name="point2"></param> /// <param name="point3"></param> /// <param name="isStroked"></param> /// <param name="isFilled"></param> /// <returns></returns> public XQBezier QBezier( XPoint point1, XPoint point2, XPoint point3, bool isStroked = true, bool isFilled = false) { var qbezier = XQBezier.Create( point1, point2, point3, Context.Editor.Project.CurrentStyleLibrary.CurrentStyle, Context.Editor.Project.Options.PointShape, isStroked, isFilled); Context.Editor.AddWithHistory(qbezier); return(qbezier); }
/// <summary> /// Creates a new instance of the XQBezier class. /// </summary> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> /// <param name="x3"></param> /// <param name="y3"></param> /// <param name="isStroked"></param> /// <param name="isFilled"></param> /// <returns></returns> public XQBezier QBezier( double x1 = 30, double y1 = 30, double x2 = 45, double y2 = 60, double x3 = 60, double y3 = 30, bool isStroked = true, bool isFilled = false) { var qbezier = XQBezier.Create( x1, y1, x2, y2, x3, y3, Context.Editor.Project.CurrentStyleLibrary.CurrentStyle, Context.Editor.Project.Options.PointShape, isStroked, isFilled); Context.Editor.AddWithHistory(qbezier); return(qbezier); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush brush = ToSolidBrush(qbezier.Style.Fill); Pen pen = ToPen(qbezier.Style, _scaleToPage); double x1 = qbezier.Point1.X; double y1 = qbezier.Point1.Y; double x2 = qbezier.Point1.X + (2.0 * (qbezier.Point2.X - qbezier.Point1.X)) / 3.0; double y2 = qbezier.Point1.Y + (2.0 * (qbezier.Point2.Y - qbezier.Point1.Y)) / 3.0; double x3 = x2 + (qbezier.Point3.X - qbezier.Point1.X) / 3.0; double y3 = y2 + (qbezier.Point3.Y - qbezier.Point1.Y) / 3.0; double x4 = qbezier.Point3.X; double y4 = qbezier.Point3.Y; if (qbezier.IsFilled) { var path = new GraphicsPath(); path.AddBezier( _scaleToPage(x1 + dx), _scaleToPage(y1 + dy), _scaleToPage(x2 + dx), _scaleToPage(y2 + dy), _scaleToPage(x3 + dx), _scaleToPage(y3 + dy), _scaleToPage(x4 + dx), _scaleToPage(y4 + dy)); _gfx.FillPath(brush, path); } if (qbezier.IsStroked) { _gfx.DrawBezier( pen, _scaleToPage(x1 + dx), _scaleToPage(y1 + dy), _scaleToPage(x2 + dx), _scaleToPage(y2 + dy), _scaleToPage(x3 + dx), _scaleToPage(y3 + dy), _scaleToPage(x4 + dx), _scaleToPage(y4 + dy)); } brush.Dispose(); pen.Dispose(); }
public void Draw(object ds, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _ds = ds as CanvasDrawingSession; double thickness = qbezier.Style.Thickness / _state.Zoom; var brush = ToColor(qbezier.Style.Fill); var pen = ToColor(qbezier.Style.Stroke); var ss = CreateStrokeStyle(qbezier.Style); CanvasGeometry g; using (var builder = new CanvasPathBuilder(_ds)) { builder.BeginFigure((float)qbezier.Point1.X, (float)qbezier.Point1.Y); builder.AddQuadraticBezier( new N.Vector2( (float)qbezier.Point2.X, (float)qbezier.Point2.Y), new N.Vector2( (float)qbezier.Point3.X, (float)qbezier.Point3.Y)); builder.EndFigure(CanvasFigureLoop.Open); g = CanvasGeometry.CreatePath(builder); } if (qbezier.IsFilled) { _ds.FillGeometry(g, brush); } if (qbezier.IsStroked) { _ds.DrawGeometry(g, pen, (float)thickness, ss); } g.Dispose(); ss.Dispose(); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { if (!qbezier.IsFilled && !qbezier.IsStroked) return; var _dc = dc as IDrawingContext; Brush brush = ToSolidBrush(qbezier.Style.Fill); Pen pen = ToPen(qbezier.Style, _scaleToPage); var sg = new StreamGeometry(); using (var sgc = sg.Open()) { var p1 = qbezier.Point1; var p2 = qbezier.Point2; var p3 = qbezier.Point3; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; sgc.BeginFigure( new Point(x1, y1), qbezier.IsFilled); sgc.BezierTo( new Point(x2, y2), new Point(x3, y3), new Point(x4, y4)); sgc.EndFigure(false); } _dc.DrawGeometry( qbezier.IsFilled ? brush : null, qbezier.IsStroked ? pen : null, sg); // TODO: sg.Dispose(); // TODO: brush.Dispose(); // TODO: 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 = XQBezier.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 XQBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Add(_shape); _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateOne(); Move(_shape as XQBezier); _editor.Project.CurrentContainer.HelperLayer.Invalidate(); _currentState = State.One; _editor.CancelAvailable = true; } break; case State.One: { var qbezier = _shape as XQBezier; if (qbezier != null) { qbezier.Point2.X = sx; qbezier.Point2.Y = sy; qbezier.Point3.X = sx; qbezier.Point3.Y = sy; if (_editor.Project.Options.TryToConnect) { TryToConnectPoint3(_shape as XQBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateTwo(); Move(_shape as XQBezier); _editor.Project.CurrentContainer.HelperLayer.Invalidate(); _currentState = State.Two; } } break; case State.Two: { var qbezier = _shape as XQBezier; if (qbezier != null) { qbezier.Point2.X = sx; qbezier.Point2.Y = sy; if (_editor.Project.Options.TryToConnect) { TryToConnectPoint2(_shape as XQBezier, sx, sy); } _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Remove(_shape); Remove(); Finalize(_shape as XQBezier); _editor.AddWithHistory(_shape); _currentState = State.None; _editor.CancelAvailable = false; } } break; } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = qbezier.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 (_enableQBezierCache && _qbezierCache.TryGetValue(qbezier, out pg)) { var pf = pg.Figures[0]; pf.StartPoint = new Point(qbezier.Point1.X + dx, qbezier.Point1.Y + dy); pf.IsFilled = qbezier.IsFilled; var qbs = pf.Segments[0] as QuadraticBezierSegment; qbs.Point1 = new Point(qbezier.Point2.X + dx, qbezier.Point2.Y + dy); qbs.Point2 = new Point(qbezier.Point3.X + dx, qbezier.Point3.Y + dy); qbs.IsStroked = qbezier.IsStroked; } else { var pf = new PathFigure() { StartPoint = new Point(qbezier.Point1.X + dx, qbezier.Point1.Y + dy), IsFilled = qbezier.IsFilled }; var qbs = new QuadraticBezierSegment( new Point(qbezier.Point2.X + dx, qbezier.Point2.Y + dy), new Point(qbezier.Point3.X + dx, qbezier.Point3.Y + dy), qbezier.IsStroked); //bs.Freeze(); pf.Segments.Add(qbs); //pf.Freeze(); pg = new PathGeometry(); pg.Figures.Add(pf); //pg.Freeze(); if (_enableQBezierCache) _qbezierCache.Add(qbezier, pg); } DrawPathGeometryInternal(_dc, half, fill, stroke, qbezier.IsStroked, qbezier.IsFilled, pg); }
/// <summary> /// /// </summary> /// <param name="qbezier"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static Vector2[] GetVertices(XQBezier qbezier, double dx, double dy) { Vector2[] vertices = new Vector2[3]; int k; Vector2[] convexHull; vertices[0] = new Vector2(qbezier.Point1.X + dx, qbezier.Point1.Y + dy); vertices[1] = new Vector2(qbezier.Point2.X + dx, qbezier.Point2.Y + dy); vertices[2] = new Vector2(qbezier.Point3.X + dx, qbezier.Point3.Y + dy); mc.ConvexHull(vertices, out convexHull, out k); return convexHull.Take(k).ToArray(); }