protected override void UpdateData() { var geometry = (PathGeometry)Data; geometry.Figures.Clear(); if (ParentMap != null && Locations != null && Locations.Any()) { var points = Locations.Select(l => ParentMap.MapTransform.Transform(l)); var figure = new PathFigure { StartPoint = points.First(), IsClosed = IsClosed, IsFilled = IsClosed }; var segment = new PolyLineSegment(); foreach (var point in points.Skip(1)) { segment.Points.Add(point); } figure.Segments.Add(segment); geometry.Figures.Add(figure); geometry.Transform = ParentMap.ViewportTransform; } else { geometry.ClearValue(Geometry.TransformProperty); } }
/// <summary> /// Creates the part. /// </summary> /// <returns> /// UIElement /// </returns> public override UIElement CreatePart() { SplinePath = new Path(); PathFigure figure = new PathFigure(); BezierSegment bezierPoints = new BezierSegment(); PathGeometry pathGeometry = new PathGeometry(); figure.StartPoint = StartPoint; bezierPoints.Point1 = FirstControlPoint; bezierPoints.Point2 = EndControlPoint; bezierPoints.Point3 = EndPoint; figure.Segments.Add(bezierPoints); pathGeometry.Figures = new PathFigureCollection() { figure }; SplinePath.Data = pathGeometry; SetBindingForStrokeandStrokeThickness(SplinePath); return SplinePath; }
/// <summary> /// Create a visual for single Series Part /// </summary> /// <returns> /// UIElement /// </returns> public override UIElement CreatePart() { AreaPath = new Path(); PathFigure figure = new PathFigure(); LineSegment startLineSegment = new LineSegment(); LineSegment areaEndLineSegment = new LineSegment(); LineSegment endLineSegment = new LineSegment(); PathGeometry pathGeometry = new PathGeometry(); figure.StartPoint = StartPoint; startLineSegment.Point = AreaStartPoint; endLineSegment.Point = EndPoint; areaEndLineSegment.Point = AreaEndPoint; figure.Segments.Add(startLineSegment); figure.Segments.Add(areaEndLineSegment); figure.Segments.Add(endLineSegment); pathGeometry.Figures = new PathFigureCollection() { figure }; AreaPath.Data = pathGeometry; SetBindingForStrokeandStrokeThickness(AreaPath); return AreaPath; }
public void Arc(Canvas surface, double left, double top, double right, double bottom, double startArcX, double startArcY, double endArcX, double endArcY) { var arc = new Path(); var figure = new PathFigure(); var segments = new PathSegmentCollection(); var center = new Point(left + ((right - left) / 2), top + ((bottom - top) / 2)); double degrees = Math.Atan2(startArcY - center.Y, startArcX - center.X) - Math.Atan2(endArcY - center.Y, endArcX - center.X); degrees *= 57.2957795; // Convert from radians to degrees bool isLargeArc = Math.Abs(degrees) > 180; arc.Data = new PathGeometry(); figure.StartPoint = new Point(LtoDX(startArcX), LtoDY(startArcY)); var segment = new ArcSegment { Point = new Point( LtoDX(endArcX), LtoDY(endArcY)), Size = new Size( (LtoDX(right) - LtoDX(left)) / 2, (LtoDY(bottom) - LtoDY(top)) / 2), RotationAngle = 0, IsLargeArc = isLargeArc, SweepDirection = SweepDirection.Counterclockwise }; segments.Add(segment); figure.Segments = segments; ((PathGeometry)arc.Data).Figures.Add(figure); ApplyStyle(arc, false); surface.Children.Add(arc); }
protected override void UpdateData() { var geometry = (PathGeometry)Data; var locations = Locations; Location first; if (ParentMap != null && locations != null && (first = locations.FirstOrDefault()) != null) { var figure = new PathFigure { StartPoint = ParentMap.MapTransform.Transform(first), IsClosed = IsClosed, IsFilled = IsClosed }; var segment = new PolyLineSegment(); foreach (var location in locations.Skip(1)) { segment.Points.Add(ParentMap.MapTransform.Transform(location)); } if (segment.Points.Count > 0) { figure.Segments.Add(segment); } geometry.Figures.Clear(); geometry.Figures.Add(figure); geometry.Transform = ParentMap.ViewportTransform; } else { geometry.Figures.Clear(); geometry.ClearValue(Geometry.TransformProperty); } }
/// <summary> /// Converts a string of Path.Data into PathGeometry. /// </summary> /// <param name="pathStr">Path.Data in string form.</param> /// <returns>PathGeometry from data string</returns> /// <example> /// pathStr = "M532,181 L532,219 L571,219 L570.54004,180.9397 z"; /// var geometry = PathUtils.ParsePathGeometryString(pathStr); /// ArtefactAnimator.AddEase(myPath, Path.DataProperty, geometry, 3, AnimationTransitions.CubicEaseOut, 0); /// </example> public static PathGeometry ParsePathGeometryString ( string pathStr ) { // string too short or doesn't exist if ( pathStr == null || pathStr.Length < 2 )return new PathGeometry(); // groups representing segments var matches = PathGeometryExpression.Matches(pathStr); // single figure holding segements var figure = new PathFigure { Segments = new PathSegmentCollection(), StartPoint = new Point(), IsClosed = pathStr.Substring(pathStr.Length-1, 1).ToLower() == "z" }; // final path geometry var pathGeo = new PathGeometry { Figures = new PathFigureCollection{figure} }; // parse matches and put in figure for (var i = 0; i < matches.Count; i++) ParseMatch(figure, matches[i]); return pathGeo; }
// Start a new figure without closing the old one. public void StartFigure() { // We don't do anything special with figures here. actualFigure = null; }
/// <summary> /// Returns new PathFigure by easing startValue to endValue using a time percentage 0 -> 1. /// </summary> public static PathFigure EaseValue(PathFigure startValue, PathFigure endValue, double percent) { return new PathFigure { IsClosed = endValue.IsClosed, IsFilled = endValue.IsFilled, StartPoint = EaseValue(startValue.StartPoint, endValue.StartPoint, percent), Segments = EaseValue(startValue.Segments, endValue.Segments, percent) }; }
/// <summary> /// Create and apply edge path using calculated ER parameters stored in edge /// </summary> /// <param name="useCurrentCoords">Use current vertices coordinates or final coorfinates (for.ex if move animation is active final coords will be its destination)</param> /// <param name="externalRoutingPoints">Provided custom routing points will be used instead of stored ones.</param> public void PrepareEdgePath(bool useCurrentCoords = false, Point[] externalRoutingPoints = null) { //do not calculate invisible edges if (Visibility != Visibility.Visible || Source == null || Target == null || ManualDrawing) { return; } var template = Template; if (template != null) { #region Get the inputs //get the size of the source var sourceSize = new Size { Width = Source.ActualWidth, Height = Source.ActualHeight }; if (DesignerProperties.GetIsInDesignMode(this)) { sourceSize = new Size(80, 20); } //get the position center of the source var sourcePos = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)) + sourceSize.Width * .5, Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)) + sourceSize.Height * .5 }; //get the size of the target var targetSize = new Size { Width = Target.ActualWidth, Height = Target.ActualHeight }; if (DesignerProperties.GetIsInDesignMode(this)) { targetSize = new Size(80, 20); } //get the position center of the target var targetPos = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)) + targetSize.Width * .5, Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)) + targetSize.Height * .5 }; //get the route informations var routeInformation = externalRoutingPoints == null ? (Edge as IRoutingInfo).RoutingPoints : externalRoutingPoints; #endregion //if self looped edge if (IsSelfLooped) { if (!RootArea.EdgeShowSelfLooped) { return; } var pt = new Point(sourcePos.X + RootArea.EdgeSelfLoopCircleOffset.X - RootArea.EdgeSelfLoopCircleRadius, sourcePos.Y + RootArea.EdgeSelfLoopCircleOffset.X - RootArea.EdgeSelfLoopCircleRadius); var geo = new EllipseGeometry(pt, RootArea.EdgeSelfLoopCircleRadius, RootArea.EdgeSelfLoopCircleRadius); const double dArrowAngle = Math.PI / 2.0; _arrowgeometry = new PathGeometry(); var aPoint = sourcePos; _arrowgeometry.Figures.Add(GeometryHelper.GenerateArrow(aPoint, new Point(), new Point(), dArrowAngle)); _linegeometry = geo; return; } var hasRouteInfo = routeInformation != null && routeInformation.Length > 1; //calculate source and target edge attach points if (RootArea != null && !hasRouteInfo && RootArea.EnableParallelEdges) { if (SourceOffset != 0) { sourcePos = GetParallelOffset(Source, Target, SourceOffset); } if (TargetOffset != 0) { targetPos = GetParallelOffset(Target, Source, TargetOffset); } } /* Rectangular shapes implementation by bleibold */ // Get the TopLeft position of the Source Vertex. var sourcePos1 = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)), Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)) }; // Get the TopLeft position of the Target Vertex. var targetPos1 = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)), Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)) }; //Point p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new Rect(sourceSize), (hasRouteInfo ? routeInformation[1] : (targetPos)), Source.MathShape); //Point p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new Rect(targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2] : (sourcePos), Target.MathShape); var p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new Rect(sourcePos1, sourceSize), (hasRouteInfo ? routeInformation[1] : (targetPos)), Source.MathShape); var p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new Rect(targetPos1, targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2] : (sourcePos), Target.MathShape); _linegeometry = new PathGeometry(); PathFigure lineFigure; _arrowgeometry = new PathGeometry(); PathFigure arrowFigure; //if we have route and route consist of 2 or more points if (RootArea != null && hasRouteInfo) { //replace start and end points with accurate ones var routePoints = routeInformation.ToList(); routePoints.Remove(routePoints.First()); routePoints.Remove(routePoints.Last()); routePoints.Insert(0, p1); routePoints.Add(p2); if (RootArea.EdgeCurvingEnabled) { var oPolyLineSegment = GeometryHelper.GetCurveThroughPoints(routePoints.ToArray(), 0.5, RootArea.EdgeCurvingTolerance); lineFigure = GeometryHelper.GetPathFigureFromPathSegments(routePoints[0], true, true, oPolyLineSegment); //get two last points of curved path to generate correct arrow var cLast = oPolyLineSegment.Points.Last(); var cPrev = oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 2]; arrowFigure = GeometryHelper.GenerateOldArrow(cPrev, cLast); //freeze and create resulting geometry GeometryHelper.TryFreeze(oPolyLineSegment); } else { lineFigure = new PathFigure(p1, new PathSegment[] { new PolyLineSegment(routePoints, true) }, false); arrowFigure = GeometryHelper.GenerateOldArrow(routePoints[routePoints.Count - 2], p2); } } else // no route defined { //!!! Here is the line calculation to not overlap an arrowhead //Vector v = p1 - p2; v = v / v.Length * 5; // Vector n = new Vector(-v.Y, v.X) * 0.7; //segments[0] = new LineSegment(p2 + v, true); lineFigure = new PathFigure(p1, new PathSegment[] { new LineSegment(p2, true) }, false); arrowFigure = GeometryHelper.GenerateOldArrow(p1, p2); } GeometryHelper.TryFreeze(lineFigure); (_linegeometry as PathGeometry).Figures.Add(lineFigure); if (arrowFigure != null) { GeometryHelper.TryFreeze(arrowFigure); _arrowgeometry.Figures.Add(arrowFigure); } GeometryHelper.TryFreeze(_linegeometry); GeometryHelper.TryFreeze(_arrowgeometry); } else { Debug.WriteLine("PrepareEdgePath() -> Edge template not found! Can't apply path to display edge!"); } }
/// <summary> /// Creates a border geometry with a 'pointer'. /// </summary> /// <param name="ha">The horizontal alignment.</param> /// <param name="va">The vertical alignment.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="margin">The margin.</param> /// <returns>The border geometry.</returns> private Geometry CreatePointerBorderGeometry( HorizontalAlignment ha, VerticalAlignment va, double width, double height, out Thickness margin) { Point[] points = null; double m = this.Distance; margin = new Thickness(); if (ha == HorizontalAlignment.Center && va == VerticalAlignment.Bottom) { double x0 = 0; double x1 = width; double x2 = (x0 + x1) / 2; double y0 = 0; double y1 = height; margin = new Thickness { Bottom = m }; points = new[] { new Point(x0, y0), new Point(x1, y0), new Point(x1, y1), new Point(x2 + (m / 2), y1), new Point(x2, y1 + m), new Point(x2 - (m / 2), y1), new Point(x0, y1) }; } if (ha == HorizontalAlignment.Center && va == VerticalAlignment.Top) { double x0 = 0; double x1 = width; double x2 = (x0 + x1) / 2; double y0 = m; double y1 = m + height; margin = new Thickness { Top = m }; points = new[] { new Point(x0, y0), new Point(x2 - (m / 2), y0), new Point(x2, 0), new Point(x2 + (m / 2), y0), new Point(x1, y0), new Point(x1, y1), new Point(x0, y1) }; } if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Center) { double x0 = m; double x1 = m + width; double y0 = 0; double y1 = height; double y2 = (y0 + y1) / 2; margin = new Thickness { Left = m }; points = new[] { new Point(0, y2), new Point(x0, y2 - (m / 2)), new Point(x0, y0), new Point(x1, y0), new Point(x1, y1), new Point(x0, y1), new Point(x0, y2 + (m / 2)) }; } if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Center) { double x0 = 0; double x1 = width; double y0 = 0; double y1 = height; double y2 = (y0 + y1) / 2; margin = new Thickness { Right = m }; points = new[] { new Point(x1 + m, y2), new Point(x1, y2 + (m / 2)), new Point(x1, y1), new Point(x0, y1), new Point(x0, y0), new Point(x1, y0), new Point(x1, y2 - (m / 2)) }; } if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Top) { m *= 0.67; double x0 = m; double x1 = m + width; double y0 = m; double y1 = m + height; margin = new Thickness { Left = m, Top = m }; points = new[] { new Point(0, 0), new Point(m * 2, y0), new Point(x1, y0), new Point(x1, y1), new Point(x0, y1), new Point(x0, m * 2) }; } if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Top) { m *= 0.67; double x0 = 0; double x1 = width; double y0 = m; double y1 = m + height; margin = new Thickness { Top = m, Right = m }; points = new[] { new Point(x1 + m, 0), new Point(x1, y0 + m), new Point(x1, y1), new Point(x0, y1), new Point(x0, y0), new Point(x1 - m, y0) }; } if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Bottom) { m *= 0.67; double x0 = m; double x1 = m + width; double y0 = 0; double y1 = height; margin = new Thickness { Left = m, Bottom = m }; points = new[] { new Point(0, y1 + m), new Point(x0, y1 - m), new Point(x0, y0), new Point(x1, y0), new Point(x1, y1), new Point(x0 + m, y1) }; } if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Bottom) { m *= 0.67; double x0 = 0; double x1 = width; double y0 = 0; double y1 = height; margin = new Thickness { Right = m, Bottom = m }; points = new[] { new Point(x1 + m, y1 + m), new Point(x1 - m, y1), new Point(x0, y1), new Point(x0, y0), new Point(x1, y0), new Point(x1, y1 - m) }; } if (points == null) { return(null); } var pointCollection = new PointCollection(); foreach (var point in points) { pointCollection.Add(point); } var segments = new PathSegmentCollection { new PolyLineSegment { Points = pointCollection } }; var pf = new PathFigure { StartPoint = points[0], Segments = segments, IsClosed = true }; return(new PathGeometry { Figures = new PathFigureCollection { pf } }); }
/// <summary> /// Creates a border geometry with a 'pointer'. /// </summary> /// <param name="ha">The horizontal alignment.</param> /// <param name="va">The vertical alignment.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="margin">The margin.</param> /// <returns>The border geometry.</returns> private Geometry CreatePointerBorderGeometry( HorizontalAlignment ha, VerticalAlignment va, double width, double height, out Thickness margin) { Point[] points = null; double m = this.Distance; margin = new Thickness(); if (ha == HorizontalAlignment.Center && va == VerticalAlignment.Bottom) { double x0 = 0; double x1 = width; double x2 = (x0 + x1) / 2; double y0 = 0; double y1 = height; margin = new Thickness { Bottom = m }; points = new[] { new Point(x0, y0), new Point(x1, y0), new Point(x1, y1), new Point(x2 + (m / 2), y1), new Point(x2, y1 + m), new Point(x2 - (m / 2), y1), new Point(x0, y1) }; } if (ha == HorizontalAlignment.Center && va == VerticalAlignment.Top) { double x0 = 0; double x1 = width; double x2 = (x0 + x1) / 2; double y0 = m; double y1 = m + height; margin = new Thickness { Top = m }; points = new[] { new Point(x0, y0), new Point(x2 - (m / 2), y0), new Point(x2, 0), new Point(x2 + (m / 2), y0), new Point(x1, y0), new Point(x1, y1), new Point(x0, y1) }; } if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Center) { double x0 = m; double x1 = m + width; double y0 = 0; double y1 = height; double y2 = (y0 + y1) / 2; margin = new Thickness { Left = m }; points = new[] { new Point(0, y2), new Point(x0, y2 - (m / 2)), new Point(x0, y0), new Point(x1, y0), new Point(x1, y1), new Point(x0, y1), new Point(x0, y2 + (m / 2)) }; } if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Center) { double x0 = 0; double x1 = width; double y0 = 0; double y1 = height; double y2 = (y0 + y1) / 2; margin = new Thickness { Right = m }; points = new[] { new Point(x1 + m, y2), new Point(x1, y2 + (m / 2)), new Point(x1, y1), new Point(x0, y1), new Point(x0, y0), new Point(x1, y0), new Point(x1, y2 - (m / 2)) }; } if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Top) { m *= 0.67; double x0 = m; double x1 = m + width; double y0 = m; double y1 = m + height; margin = new Thickness { Left = m, Top = m }; points = new[] { new Point(0, 0), new Point(m * 2, y0), new Point(x1, y0), new Point(x1, y1), new Point(x0, y1), new Point(x0, m * 2) }; } if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Top) { m *= 0.67; double x0 = 0; double x1 = width; double y0 = m; double y1 = m + height; margin = new Thickness { Top = m, Right = m }; points = new[] { new Point(x1 + m, 0), new Point(x1, y0 + m), new Point(x1, y1), new Point(x0, y1), new Point(x0, y0), new Point(x1 - m, y0) }; } if (ha == HorizontalAlignment.Left && va == VerticalAlignment.Bottom) { m *= 0.67; double x0 = m; double x1 = m + width; double y0 = 0; double y1 = height; margin = new Thickness { Left = m, Bottom = m }; points = new[] { new Point(0, y1 + m), new Point(x0, y1 - m), new Point(x0, y0), new Point(x1, y0), new Point(x1, y1), new Point(x0 + m, y1) }; } if (ha == HorizontalAlignment.Right && va == VerticalAlignment.Bottom) { m *= 0.67; double x0 = 0; double x1 = width; double y0 = 0; double y1 = height; margin = new Thickness { Right = m, Bottom = m }; points = new[] { new Point(x1 + m, y1 + m), new Point(x1 - m, y1), new Point(x0, y1), new Point(x0, y0), new Point(x1, y0), new Point(x1, y1 - m) }; } if (points == null) { return null; } var pointCollection = new PointCollection(); foreach (var point in points) { pointCollection.Add(point); } var segments = new PathSegmentCollection { new PolyLineSegment { Points = pointCollection } }; var pf = new PathFigure { StartPoint = points[0], Segments = segments, IsClosed = true }; return new PathGeometry { Figures = new PathFigureCollection { pf } }; }
/// <summary> /// Draws the multiple line segments defined by points (0,1) (2,3) (4,5) etc. /// This should have better performance than calling DrawLine for each segment. /// </summary> /// <param name="points">The points.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The stroke thickness.</param> /// <param name="dashArray">The dash array.</param> /// <param name="lineJoin">The line join type.</param> /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param> public void DrawLineSegments( IList<ScreenPoint> points, OxyColor stroke, double thickness, double[] dashArray, LineJoin lineJoin, bool aliased) { var path = new Path(); this.SetStroke(path, stroke, thickness, lineJoin, dashArray, aliased); var pg = new PathGeometry(); for (int i = 0; i + 1 < points.Count; i += 2) { // if (points[i].Y==points[i+1].Y) // { // var line = new Line(); // line.X1 = 0.5+(int)points[i].X; // line.X2 = 0.5+(int)points[i+1].X; // line.Y1 = 0.5+(int)points[i].Y; // line.Y2 = 0.5+(int)points[i+1].Y; // SetStroke(line, OxyColors.DarkRed, thickness, lineJoin, dashArray, aliased); // Add(line); // continue; // } var figure = new PathFigure { StartPoint = points[i].ToPoint(aliased), IsClosed = false }; figure.Segments.Add(new LineSegment { Point = points[i + 1].ToPoint(aliased) }); pg.Figures.Add(figure); } path.Data = pg; this.Add(path); }
public override void OnSeriesUpdateStart() { ActiveSplitters = 0; if (SplittersCollector == int.MaxValue - 1) { //just in case! Splitters.ForEach(s => s.SplitterCollectorIndex = 0); SplittersCollector = 0; } SplittersCollector++; if (Figure != null && Values != null) { var yIni = ChartFunctions.ToDrawMargin(Values.Limit2.Min, AxisOrientation.Y, Model.Chart, ScalesYAt); if (Model.Chart.View.DisableAnimations) { Figure.StartPoint = new Point(0, yIni); } else { Figure.BeginAnimation(PathFigure.StartPointProperty, new PointAnimation(new Point(0, yIni), Model.Chart.View.AnimationsSpeed)); } } if (IsPathInitialized) { return; } IsPathInitialized = true; Path = new Path(); BindingOperations.SetBinding(Path, Shape.StrokeProperty, new Binding { Path = new PropertyPath("Stroke"), Source = this }); BindingOperations.SetBinding(Path, Shape.FillProperty, new Binding { Path = new PropertyPath("Fill"), Source = this }); BindingOperations.SetBinding(Path, Shape.StrokeThicknessProperty, new Binding { Path = new PropertyPath("StrokeThickness"), Source = this }); BindingOperations.SetBinding(Path, VisibilityProperty, new Binding { Path = new PropertyPath("Visibility"), Source = this }); BindingOperations.SetBinding(Path, Panel.ZIndexProperty, new Binding { Path = new PropertyPath(Panel.ZIndexProperty), Source = this }); BindingOperations.SetBinding(Path, Shape.StrokeDashArrayProperty, new Binding { Path = new PropertyPath(StrokeDashArrayProperty), Source = this }); var geometry = new PathGeometry(); Figure = new PathFigure(); geometry.Figures.Add(Figure); Path.Data = geometry; Model.Chart.View.AddToDrawMargin(Path); var y = ChartFunctions.ToDrawMargin(ActualValues.Limit2.Min, AxisOrientation.Y, Model.Chart, ScalesYAt); Figure.StartPoint = new Point(0, y); }
public void PolyPolygon(Canvas surface, IEnumerable<IEnumerable<Point>> vertices) { var polyPath = new Path(); #if NETFX_CORE var geometry = new PathGeometry(); foreach (var polygon in vertices) { var pointIndex = 0; var figure = new PathFigure(); geometry.Figures.Add(figure); foreach (Point item in polygon) { if (pointIndex == 0) { // Move to figure.IsFilled = true; figure.IsClosed = true; figure.StartPoint = new Point(LtoDX(item.X), LtoDY(item.Y)); } else { figure.Segments.Add( new LineSegment() { Point = new Point(LtoDX(item.X), LtoDY(item.Y)) } ); } pointIndex++; } } #else var geometry = new StreamGeometry(); using (StreamGeometryContext ctx = geometry.Open()) { foreach (var polygon in vertices) { var pointIndex = 0; foreach (Point item in polygon) { if (pointIndex == 0) { // Move to ctx.BeginFigure(new Point(LtoDX(item.X), LtoDY(item.Y)), true, true); } else { ctx.LineTo(new Point(LtoDX(item.X), LtoDY(item.Y)), true, false); } pointIndex++; } } } #endif if (_currentState.PolyFillMode == PolyFillMode.WINDING) { geometry.FillRule = FillRule.Nonzero; } #if !NETFX_CORE geometry.Freeze(); #endif polyPath.Data = geometry; #if !NETFX_CORE // Clip var clipGeometry = GetClipGeometry(geometry.Bounds); if (clipGeometry != null) { polyPath.Data = Geometry.Combine(polyPath.Data, clipGeometry, GeometryCombineMode.Intersect, null); } #endif ApplyStyle(polyPath, true); surface.Children.Add(polyPath); }
internal void PaintTrend() { if (_properties == null || _properties.Chart == null || double.IsNaN(ActualWidth) || string.IsNullOrEmpty(_properties.Chart.Symbol) || _updatingChart) { return; } EnsureVisualsCreated(); _backgroundTrend.Width = ActualWidth; _backgroundTrend.Height = ActualHeight; PathGeometry geometry = new PathGeometry(); PathSegmentCollection segments = new PathSegmentCollection(); PathFigure figure = new PathFigure(); Series closeSeries = _properties.Chart.SeriesCollection.FirstOrDefault(_ => _.OHLCType == SeriesTypeOHLC.Close) ?? _properties.Chart.SeriesCollection.FirstOrDefault(); if (closeSeries == null) { return; } IList <double> values = closeSeries .AllValues .Where(_ => _ != null) .Select(_ => _.Value) .ToList(); double min = double.MaxValue; double max = double.MinValue; foreach (double value in values) // No LINQ here!!! { min = Math.Min(min, value); max = Math.Max(max, value); } int i; double y, x; for (i = 0; i < values.Count; i += 5) { double value = values[i]; x = (i * 1f / values.Count) * ActualWidth; if (min != max) { y = ActualHeight * (1f - ((value - min) / (max - min))); } else { y = ActualHeight * 0.5; } if (i == 0) { figure.StartPoint = new Point(x, y); } else { segments.Add(new LineSegment { Point = new Point(x, y) }); } } x = ActualWidth; if (min != max && values.Count > 0) { y = ActualHeight * (1f - ((values[values.Count - 1] - min) / (max - min))); } else { y = ActualHeight * 0.5; } segments.Add(new LineSegment { Point = new Point(x, y) }); segments.Add(new LineSegment { Point = new Point(ActualWidth, ActualHeight) }); segments.Add(new LineSegment { Point = new Point(0, ActualHeight) }); figure.Segments = segments; geometry.Figures.Add(figure); _backgroundTrend.Data = geometry; }
/// <summary> /// 绘制色环 /// </summary> /// <param name="centerX">圆心坐标X点</param> /// <param name="centerY">圆心坐标Y点</param> /// <param name="radiusMax">外径</param> /// <param name="radiusMin">内径</param> private void DrawColorWheel(Double centerX, Double centerY, Double radiusMax, Double radiusMin, byte a) { // 创建绘图容器 Grid colorWheel = new Grid() { Name = "xColorWheel" }; colorWheel.Children.Clear(); // 生成色环表 List <Color> wheelColors = new List <Color>(); for (byte i = 0; i < 255; i++) { wheelColors.Add(Color.FromArgb(a, 255, i, 0)); } for (byte i = 255; i > 0; i--) { wheelColors.Add(Color.FromArgb(a, i, 255, 0)); } for (byte i = 0; i < 255; i++) { wheelColors.Add(Color.FromArgb(a, 0, 255, i)); } for (byte i = 255; i > 0; i--) { wheelColors.Add(Color.FromArgb(a, 0, i, 255)); } for (byte i = 0; i < 255; i++) { wheelColors.Add(Color.FromArgb(a, i, 0, 255)); } for (byte i = 255; i > 0; i--) { wheelColors.Add(Color.FromArgb(a, 255, 0, i)); } // 创建路径变量 int colorCount = wheelColors.Count; // 颜色数量 Double angel = 360.0 / colorCount; // 计算夹角(注:计算参数必须为浮点数,否则结果为0) Double rotate = 0; // 起始角度 Double pointX, pointY; // 缓存绘图路径点 // 计算绘图路径 wheelColors.ForEach((color) => { pointX = centerX + radiusMax * Math.Cos(rotate * Math.PI / 180); pointY = centerY + radiusMax * Math.Sin(rotate * Math.PI / 180); Point point0 = new Point(pointX, pointY); pointX = centerX + radiusMin * Math.Cos(rotate * Math.PI / 180); pointY = centerY + radiusMin * Math.Sin(rotate * Math.PI / 180); Point point1 = new Point(pointX, pointY); rotate += angel; pointX = centerX + radiusMin * Math.Cos(rotate * Math.PI / 180); pointY = centerY + radiusMin * Math.Sin(rotate * Math.PI / 180); Point point2 = new Point(pointX, pointY); pointX = centerX + radiusMax * Math.Cos(rotate * Math.PI / 180); pointY = centerY + radiusMax * Math.Sin(rotate * Math.PI / 180); Point point3 = new Point(pointX, pointY); PathFigure wheelPath = new PathFigure() { IsClosed = true, StartPoint = point0 }; wheelPath.Segments.Add(new LineSegment() { Point = point1 }); wheelPath.Segments.Add(new ArcSegment() { Point = point2, SweepDirection = SweepDirection.Clockwise, Size = new Size(radiusMin, radiusMin) }); wheelPath.Segments.Add(new LineSegment() { Point = point3 }); wheelPath.Segments.Add(new ArcSegment() { Point = point0, Size = new Size(radiusMax, radiusMax) }); PathGeometry wheelPaths = new PathGeometry(); PathFigureCollection pathFigures = new PathFigureCollection(); pathFigures.Add(wheelPath); wheelPaths.Figures = pathFigures; WheelPath = new Path() { StrokeThickness = 0, Fill = new SolidColorBrush(color), Data = wheelPaths }; colorWheel.Children.Add(WheelPath); }); colorWheel.HorizontalAlignment = HorizontalAlignment.Center; colorWheel.VerticalAlignment = VerticalAlignment.Center; colorWheel.AllowDrop = true; grid.Children.Add(colorWheel); Canvas.SetLeft(ellipse, centerX / 2 - 5); Canvas.SetTop(ellipse, centerY / 2); Point point = new Point() { X = centerX, Y = centerY }; double redius = (radiusMax - radiusMin) / 2 + radiusMin; var p = GetPoints(point, (int)redius, 100); Canvas.SetLeft(BlackEllipse, p[0].X - 15); Canvas.SetTop(BlackEllipse, p[0].Y - 15); }
protected override void OnRender(DrawingContext drawingContext) { if (TextView == null || !TextView.VisualLinesValid) { return; } Brush insertBrush = Theme.GetBrush(Theme.Source.DiffInsert); Brush removeBrush = Theme.GetBrush(Theme.Source.DiffRemove); Brush changeBrush = Theme.GetBrush(Theme.Source.DiffChange); IEnumerable <(VisualLine, int)> visualLines = TextView .VisualLines .Select(x => (x, x.FirstDocumentLine.LineNumber)); List <(int number, double y, double height)> lines = new List <(int, double, double)>(); foreach (VisualLine line in TextView.VisualLines) { int number = line.FirstDocumentLine.LineNumber; if (number >= _margin.Count) { continue; } double y = line.GetTextLineVisualYPosition( line.TextLines[0], VisualYPosition.LineTop); y -= TextView.VerticalOffset; double height = line.Height; lines.Add((number, y, height)); } double width = RenderSize.Width; foreach ((int number, double y, double height) in lines) { Brush brush; switch (_margin[number].Kind) { case DiffMarginKind.Insert: brush = insertBrush; break; case DiffMarginKind.Change: brush = changeBrush; break; default: continue; } if (brush != null) { Rect rect = new Rect(0, y, width, height); drawingContext.DrawRectangle(brush, null, rect); } } foreach ((int number, double y, double height) in lines) { if (_margin[number].RemoveCount > 0) { // I'd like to think that there is an easier way to // draw a triangle than all this, but I do not see one. Point top = new Point(0, y + 0.8 * height); Point middle = new Point(width, y + height); Point bottom = new Point(0, y + 1.2 * height); PathFigure figure = new PathFigure(top, new PathSegment[] { new LineSegment(middle, true), new LineSegment(bottom, true) }, closed: true ); PathGeometry geometry = new PathGeometry(); geometry.Figures.Add(figure); Pen pen = new Pen(removeBrush, 2); drawingContext.DrawGeometry(removeBrush, pen, geometry); } } }
private void RenderTheme(DrawingContext dc) { ThemeColor themeColor = ThemeColor; Size size = RenderSize; bool horizontal = Orientation == Orientation.Horizontal; bool isClickable = IsClickable && IsEnabled; bool isHovered = isClickable && IsHovered; bool isPressed = isClickable && IsPressed; ListSortDirection?sortDirection = SortDirection; bool isSorted = sortDirection != null; bool isSelected = IsSelected; EnsureCache((int)LunaFreezables.NumFreezables); if (horizontal) { // When horizontal, rotate the rendering by -90 degrees Matrix m1 = new Matrix(); m1.RotateAt(-90.0, 0.0, 0.0); Matrix m2 = new Matrix(); m2.Translate(0.0, size.Height); MatrixTransform horizontalRotate = new MatrixTransform(m1 * m2); horizontalRotate.Freeze(); dc.PushTransform(horizontalRotate); double temp = size.Width; size.Width = size.Height; size.Height = temp; } // Draw the background LunaFreezables backgroundType = isPressed ? LunaFreezables.PressedBackground : isHovered ? LunaFreezables.HoveredBackground : LunaFreezables.NormalBackground; LinearGradientBrush background = (LinearGradientBrush)GetCachedFreezable((int)backgroundType); if (background == null) { background = new LinearGradientBrush(); background.StartPoint = new Point(); background.EndPoint = new Point(0.0, 1.0); if (isPressed) { if (themeColor == ThemeColor.Metallic) { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB9, 0xB9, 0xC8), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEC, 0xEC, 0xF3), 0.1)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEC, 0xEC, 0xF3), 1.0)); } else { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xC1, 0xC2, 0xB8), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xDE, 0xDF, 0xD8), 0.1)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xDE, 0xDF, 0xD8), 1.0)); } } else if (isHovered || isSelected) { if (themeColor == ThemeColor.Metallic) { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFE, 0xFE, 0xFE), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFE, 0xFE, 0xFE), 0.85)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBD, 0xBE, 0xCE), 1.0)); } else { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFA, 0xF9, 0xF4), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFA, 0xF9, 0xF4), 0.85)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEC, 0xE9, 0xD8), 1.0)); } } else { if (themeColor == ThemeColor.Metallic) { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF9, 0xFA, 0xFD), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF9, 0xFA, 0xFD), 0.85)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBD, 0xBE, 0xCE), 1.0)); } else { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEB, 0xEA, 0xDB), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEB, 0xEA, 0xDB), 0.85)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xCB, 0xC7, 0xB8), 1.0)); } } background.Freeze(); CacheFreezable(background, (int)backgroundType); } dc.DrawRectangle(background, null, new Rect(0.0, 0.0, size.Width, size.Height)); if (isHovered && !isPressed && (size.Width >= 6.0) && (size.Height >= 4.0)) { // When hovered, there is a colored tab at the bottom TranslateTransform positionTransform = new TranslateTransform(0.0, size.Height - 3.0); positionTransform.Freeze(); dc.PushTransform(positionTransform); PathGeometry tabGeometry = new PathGeometry(); PathFigure tabFigure = new PathFigure(); tabFigure.StartPoint = new Point(0.5, 0.5); LineSegment line = new LineSegment(new Point(size.Width - 0.5, 0.5), true); line.Freeze(); tabFigure.Segments.Add(line); ArcSegment arc = new ArcSegment(new Point(size.Width - 2.5, 2.5), new Size(2.0, 2.0), 90.0, false, SweepDirection.Clockwise, true); arc.Freeze(); tabFigure.Segments.Add(arc); line = new LineSegment(new Point(2.5, 2.5), true); line.Freeze(); tabFigure.Segments.Add(line); arc = new ArcSegment(new Point(0.5, 0.5), new Size(2.0, 2.0), 90.0, false, SweepDirection.Clockwise, true); arc.Freeze(); tabFigure.Segments.Add(arc); tabFigure.IsClosed = true; tabFigure.Freeze(); tabGeometry.Figures.Add(tabFigure); tabGeometry.Freeze(); Pen tabStroke = (Pen)GetCachedFreezable((int)LunaFreezables.TabStroke); if (tabStroke == null) { SolidColorBrush tabStrokeBrush = new SolidColorBrush((themeColor == ThemeColor.Homestead) ? Color.FromArgb(0xFF, 0xCF, 0x72, 0x25) : Color.FromArgb(0xFF, 0xF8, 0xA9, 0x00)); tabStrokeBrush.Freeze(); tabStroke = new Pen(tabStrokeBrush, 1.0); tabStroke.Freeze(); CacheFreezable(tabStroke, (int)LunaFreezables.TabStroke); } LinearGradientBrush tabFill = (LinearGradientBrush)GetCachedFreezable((int)LunaFreezables.TabFill); if (tabFill == null) { tabFill = new LinearGradientBrush(); tabFill.StartPoint = new Point(); tabFill.EndPoint = new Point(1.0, 0.0); if (themeColor == ThemeColor.Homestead) { tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xE3, 0x91, 0x4F), 0.0)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xE3, 0x91, 0x4F), 1.0)); } else { tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFC, 0xE0, 0xA6), 0.0)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF6, 0xC4, 0x56), 0.1)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF6, 0xC4, 0x56), 0.9)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xDF, 0x97, 0x00), 1.0)); } tabFill.Freeze(); CacheFreezable(tabFill, (int)LunaFreezables.TabFill); } dc.DrawGeometry(tabFill, tabStroke, tabGeometry); dc.Pop(); // Translate Transform } if (isPressed && (size.Width >= 2.0) && (size.Height >= 2.0)) { // When pressed, there is a border on the left and bottom SolidColorBrush border = (SolidColorBrush)GetCachedFreezable((int)LunaFreezables.PressedBorder); if (border == null) { border = new SolidColorBrush((themeColor == ThemeColor.Metallic) ? Color.FromArgb(0xFF, 0x80, 0x80, 0x99) : Color.FromArgb(0xFF, 0xA5, 0xA5, 0x97)); border.Freeze(); CacheFreezable(border, (int)LunaFreezables.PressedBorder); } dc.DrawRectangle(border, null, new Rect(0.0, 0.0, 1.0, size.Height)); dc.DrawRectangle(border, null, new Rect(0.0, Max0(size.Height - 1.0), size.Width, 1.0)); } if (!isPressed && !isHovered && (size.Width >= 4.0)) { if (SeparatorVisibility == Visibility.Visible) { Brush sideBrush; if (SeparatorBrush != null) { sideBrush = SeparatorBrush; } else { // When not pressed or hovered, draw the resize gripper LinearGradientBrush gripper = (LinearGradientBrush)GetCachedFreezable((int)(horizontal ? LunaFreezables.HorizontalGripper : LunaFreezables.VerticalGripper)); if (gripper == null) { gripper = new LinearGradientBrush(); gripper.StartPoint = new Point(); gripper.EndPoint = new Point(1.0, 0.0); Color highlight = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF); Color shadow = Color.FromArgb(0xFF, 0xC7, 0xC5, 0xB2); if (horizontal) { gripper.GradientStops.Add(new GradientStop(highlight, 0.0)); gripper.GradientStops.Add(new GradientStop(highlight, 0.25)); gripper.GradientStops.Add(new GradientStop(shadow, 0.75)); gripper.GradientStops.Add(new GradientStop(shadow, 1.0)); } else { gripper.GradientStops.Add(new GradientStop(shadow, 0.0)); gripper.GradientStops.Add(new GradientStop(shadow, 0.25)); gripper.GradientStops.Add(new GradientStop(highlight, 0.75)); gripper.GradientStops.Add(new GradientStop(highlight, 1.0)); } gripper.Freeze(); CacheFreezable(gripper, (int)(horizontal ? LunaFreezables.HorizontalGripper : LunaFreezables.VerticalGripper)); } sideBrush = gripper; } dc.DrawRectangle(sideBrush, null, new Rect(horizontal ? 0.0 : Max0(size.Width - 2.0), 4.0, 2.0, Max0(size.Height - 8.0))); } } if (isSorted && (size.Width > 14.0) && (size.Height > 10.0)) { // When sorted, draw an arrow on the right TranslateTransform positionTransform = new TranslateTransform(size.Width - 15.0, (size.Height - 5.0) * 0.5); positionTransform.Freeze(); dc.PushTransform(positionTransform); bool ascending = (sortDirection == ListSortDirection.Ascending); PathGeometry arrowGeometry = (PathGeometry)GetCachedFreezable(ascending ? (int)LunaFreezables.ArrowUpGeometry : (int)LunaFreezables.ArrowDownGeometry); if (arrowGeometry == null) { arrowGeometry = new PathGeometry(); PathFigure arrowFigure = new PathFigure(); if (ascending) { arrowFigure.StartPoint = new Point(0.0, 5.0); LineSegment line = new LineSegment(new Point(5.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(10.0, 5.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } else { arrowFigure.StartPoint = new Point(0.0, 0.0); LineSegment line = new LineSegment(new Point(10.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(5.0, 5.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } arrowFigure.IsClosed = true; arrowFigure.Freeze(); arrowGeometry.Figures.Add(arrowFigure); arrowGeometry.Freeze(); CacheFreezable(arrowGeometry, ascending ? (int)LunaFreezables.ArrowUpGeometry : (int)LunaFreezables.ArrowDownGeometry); } SolidColorBrush arrowFill = (SolidColorBrush)GetCachedFreezable((int)LunaFreezables.ArrowFill); if (arrowFill == null) { arrowFill = new SolidColorBrush(Color.FromArgb(0xFF, 0xAC, 0xA8, 0x99)); arrowFill.Freeze(); CacheFreezable(arrowFill, (int)LunaFreezables.ArrowFill); } dc.DrawGeometry(arrowFill, null, arrowGeometry); dc.Pop(); // Position Transform } if (horizontal) { dc.Pop(); // Horizontal Rotate } }
private void VM_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(TraceMapViewModel.Points)) { var points = VM.Points; // Поиск минимумов и максимумов var maxPoint = points.Length > 1 ? points[0] : new Point(0, 0); var minPoint = points.Length > 1 ? points[0] : new Point(0, 0); foreach (var point in points) { if (point.X < minPoint.X) { minPoint.X = point.X; } if (point.Y < minPoint.Y) { minPoint.Y = point.Y; } if (point.X > maxPoint.X) { maxPoint.X = point.X; } if (point.Y > maxPoint.Y) { maxPoint.Y = point.Y; } } foreach (var point in MainVM.Model.Points) { if (point.X < minPoint.X) { minPoint.X = point.X; } if (point.Y < minPoint.Y) { minPoint.Y = point.Y; } if (point.X > maxPoint.X) { maxPoint.X = point.X; } if (point.Y > maxPoint.Y) { maxPoint.Y = point.Y; } } const int padding = 10; const int multiplier = 10; VM.Width = (maxPoint.X - minPoint.X) * multiplier + 2 * padding + 2; VM.Height = (maxPoint.Y - minPoint.Y) * multiplier + 2 * padding + 2; grid_MapOuter.Width = VM.Width * 1.2; grid_MapOuter.Height = VM.Height * 1.2; grid_Map.Children.Clear(); // Отрисовка линии void AddLine(Point p1, Point p2, Brush color, double thickness = 1) { grid_Map.Children.Add(new Line { X1 = padding + multiplier * (p1.X - minPoint.X), X2 = padding + multiplier * (p2.X - minPoint.X), Y1 = padding + multiplier * (p1.Y - minPoint.Y), Y2 = padding + multiplier * (p2.Y - minPoint.Y), StrokeThickness = thickness, Stroke = color, }); } // Отрисовка дуги void AddArc(Point p1, Point p2, int direction) { const double radius = 3; var x1 = padding + multiplier * (p1.X - minPoint.X); var x2 = padding + multiplier * (p2.X - minPoint.X); var y1 = padding + multiplier * (p1.Y - minPoint.Y); var y2 = padding + multiplier * (p2.Y - minPoint.Y); var arc = new ArcSegment() { Point = new WinPoint(x2, y2), Size = new Size(radius * multiplier, radius * multiplier), SweepDirection = direction == 1 ? SweepDirection.Counterclockwise : SweepDirection.Clockwise, }; var figure = new PathFigure() { StartPoint = new WinPoint(x1, y1) }; figure.Segments.Add(arc); var geometry = new PathGeometry(); geometry.Figures.Add(figure); var path = new Path() { Data = geometry, Stroke = Brushes.Red, StrokeThickness = 1 }; grid_Map.Children.Add(path); } // Открисовка круга void AddEllipse(Point p1, Brush color, double diameter = 0.3) { var x1 = padding + multiplier * (p1.X - minPoint.X); var y1 = padding + multiplier * (p1.Y - minPoint.Y); var size = diameter * multiplier; grid_Map.Children.Add(new Ellipse() { Width = size, Height = size, Fill = color, Margin = new Thickness(x1 - size / 2, y1 - size / 2, 0, 0), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, }); } // Отрисовка треугольника void AddTriangle(Point p1, Brush fill, Brush border = null, double radius = 0.5) { AddEllipse(p1, border); var x1 = padding + multiplier * (p1.X - minPoint.X); var y1 = padding + multiplier * (p1.Y - minPoint.Y); var size = radius * multiplier; var xc = size; var yc = size; var triangle = new[] { new WinPoint(xc, yc + size), new WinPoint(xc + size * 0.866, yc - size * 0.5), new WinPoint(xc - size * 0.866, yc - size * 0.5), }; var dxy = Convert.ToInt32(p1.Degrees) % 90 == 45 ? size / 0.707 : size; var polygon = new Polygon() { Width = 2 * size, Height = 2 * size, Points = new PointCollection(triangle), Stroke = border ?? fill, Fill = fill, }; var polygonGrid = new Grid() { Width = 2 * size, Height = 2 * size, Margin = new Thickness(x1 - dxy, y1 - dxy, 0, 0), LayoutTransform = new RotateTransform(p1.Degrees), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, }; polygonGrid.Children.Add(polygon); grid_Map.Children.Add(polygonGrid); } // Сетка if (VM.ShouldDrawGrid) { for (var i = (int)minPoint.X - 1; i <= Math.Ceiling(maxPoint.X) + 1; i++) { AddLine(new Point(i, minPoint.Y - 1), new Point(i, maxPoint.Y + 1), Brushes.DarkGray, 0.25); } for (var i = (int)minPoint.Y - 1; i <= Math.Ceiling(maxPoint.Y) + 1; i++) { AddLine(new Point(minPoint.X - 1, i), new Point(maxPoint.X + 1, i), Brushes.DarkGray, 0.25); } } // Ось OY AddLine(new Point(0, 0), new Point(0, 1), Brushes.Black, 0.5); AddLine(new Point(0.2, 0.8), new Point(0, 1), Brushes.Black, 0.5); AddLine(new Point(-0.2, 0.8), new Point(0, 1), Brushes.Black, 0.5); // Трасса for (var i = 0; i < points.Length - 1 && i < MainVM.Model.Order.Count; i++) { var block = MainVM.Model.Order[i]; if (block.StartsWith("T")) { // Рисуем дугу var direction = MainVM.Model.Topology[i].Direction; AddArc(points[i], points[i + 1], direction); } else { // Рисуем линию AddLine(points[i], points[i + 1], Brushes.Red); if (block.StartsWith("B")) { var rotatedPoint = MathFunctions.RotateCoordinates(points[i].Angle, points[i]); rotatedPoint.Y += 1.5; rotatedPoint.X += 0.2; var p1 = MathFunctions.RotateCoordinates(-points[i].Angle, rotatedPoint); rotatedPoint.Y += 1; var p2 = MathFunctions.RotateCoordinates(-points[i].Angle, rotatedPoint); rotatedPoint.X -= 0.2 * 2; var p4 = MathFunctions.RotateCoordinates(-points[i].Angle, rotatedPoint); rotatedPoint.Y -= 1; var p3 = MathFunctions.RotateCoordinates(-points[i].Angle, rotatedPoint); // Рисуем линии моста AddLine(p1, p2, Brushes.Black, thickness: 0.5); AddLine(p3, p4, Brushes.Black, thickness: 0.5); } } // Рисуем точку стыка AddEllipse(points[i], Brushes.Red, 0.2); } void AddText(string text, Point p, double fontSize = 7, Brush color = null) { var x1 = padding + multiplier * (p.X - minPoint.X); var y1 = padding + multiplier * (p.Y - minPoint.Y); var textBox = new TextBlock() { Text = text, FontSize = fontSize, Foreground = color ?? Brushes.Black, LayoutTransform = new ScaleTransform(1, -1), Margin = new Thickness(x1, y1, 0, 0), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, }; grid_Map.Children.Add(textBox); } // Точки маршрута foreach (var route in MainVM.Model.Points) { AddEllipse(route, Brushes.Blue); // Стоимость точек AddText($"{route.Price:F0}", route); } // Второй курсор if (VM.Cursor2Point is Point cursorPoint2) { var fill = cursorPoint2.Price > 0.5 ? new SolidColorBrush(Color.FromArgb(100, 100, 0, 255)) : Brushes.Transparent; AddTriangle(cursorPoint2, fill, Brushes.BlueViolet); AddText($"x:{cursorPoint2.X:F0} y:{cursorPoint2.Y:F0}\n", cursorPoint2, 5); } // Основной курсор алгоритма WASD if (VM.Cursor1Point is Point cursorPoint) { var fill = cursorPoint.Price > 0.5 ? new SolidColorBrush(Color.FromArgb(100, 16, 255, 16)) : Brushes.Transparent; AddTriangle(cursorPoint, fill, Brushes.Green); AddText($"x:{cursorPoint.X:F0} y:{cursorPoint.Y:F0}\n", cursorPoint, 5); } // Центройды for (var i = 0; i < VM?.Context?.Centroids?.Count; i++) { if (VM?.Context?.Centroids[i] is Point centroid) { AddEllipse(centroid, new SolidColorBrush(Colors.Aqua) { Opacity = 0.5 }, 0.75); AddText($"{centroid.Price:F0}", new Point(centroid.X, centroid.Y - 1), 5, Brushes.DarkGray); } } } }
private void ApplyStyle(Shape shape, bool fillShape) { if (_currentState.CurrentPen == null) { // Stock Pen var newBrush = new SolidColorBrush(Colors.Black); #if !NETFX_CORE newBrush.Freeze(); #endif shape.Stroke = newBrush; shape.StrokeThickness = 1; } else { LogPen currentPen = _currentState.CurrentPen; if (currentPen.Width > 0) { shape.StrokeThickness = ScaleWidth(currentPen.Width); } // Style if ((PenStyle)(currentPen.Style & 0x000F) == PenStyle.PS_NULL) { // Do nothing, null is the default //shape.Stroke = null; } else { var newBrush = new SolidColorBrush(currentPen.Colour); #if !NETFX_CORE newBrush.Freeze(); #endif shape.Stroke = newBrush; if ((PenStyle)(currentPen.Style & 0x000F) == PenStyle.PS_DASH) { shape.StrokeDashArray.Add(30); shape.StrokeDashArray.Add(10); } else if ((PenStyle)(currentPen.Style & 0x000F) == PenStyle.PS_DASHDOT) { shape.StrokeDashArray.Add(30); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); } else if ((PenStyle)(currentPen.Style & 0x000F) == PenStyle.PS_DASHDOTDOT) { shape.StrokeDashArray.Add(30); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); } else if ((PenStyle)(currentPen.Style & 0x000F) == PenStyle.PS_DOT) { shape.StrokeDashArray.Add(10); shape.StrokeDashArray.Add(10); shape.StrokeDashCap = PenLineCap.Round; } } // Join if ((PenStyle)(currentPen.Style & 0xF000) == PenStyle.PS_JOIN_BEVEL) { shape.StrokeLineJoin = PenLineJoin.Bevel; } else if ((PenStyle)(currentPen.Style & 0xF000) == PenStyle.PS_JOIN_MITER) { // Do nothing, miter is the default shape.StrokeLineJoin = PenLineJoin.Miter; if (_miterLimit != 0) { shape.StrokeMiterLimit = _miterLimit; } } else if ((PenStyle)(currentPen.Style & 0xF000) == PenStyle.PS_JOIN_ROUND) { shape.StrokeLineJoin = PenLineJoin.Round; } // End cap if ((PenStyle)(currentPen.Style & 0x0F00) == PenStyle.PS_ENDCAP_FLAT) { // Do nothing, flat is the default // shape.StrokeEndLineCap = PenLineCap.Flat; // shape.StrokeStartLineCap = PenLineCap.Flat; } else if ((PenStyle)(currentPen.Style & 0x0F00) == PenStyle.PS_ENDCAP_SQUARE) { shape.StrokeEndLineCap = PenLineCap.Square; shape.StrokeStartLineCap = PenLineCap.Square; } else if ((PenStyle)(currentPen.Style & 0x0F00) == PenStyle.PS_ENDCAP_ROUND) { shape.StrokeEndLineCap = PenLineCap.Round; shape.StrokeStartLineCap = PenLineCap.Round; } } if (_currentState.CurrentBrush == null & fillShape) { // Stock brush var newBrush = new SolidColorBrush(Colors.White); #if !NETFX_CORE newBrush.Freeze(); #endif shape.Fill = newBrush; } else if (fillShape) { LogBrush currentBrush = _currentState.CurrentBrush; if (currentBrush.Style == BrushStyle.BS_NULL) { // Do nothing, null is the default // shape.Fill = null; } else if (currentBrush.Image != null) { #if !NETFX_CORE var imgBrush = new ImageBrush { ImageSource = currentBrush.Image, Stretch = Stretch.None, TileMode = TileMode.Tile, Viewport = new Rect(0, 0, ScaleWidth(currentBrush.Image.Width), ScaleHeight(currentBrush.Image.Height)), ViewportUnits = BrushMappingMode.Absolute, Viewbox = new Rect(0, 0, ScaleWidth(currentBrush.Image.Width), ScaleHeight(currentBrush.Image.Height)), ViewboxUnits = BrushMappingMode.Absolute }; imgBrush.Freeze(); shape.Fill = imgBrush; #endif // TODO: Figure out a way to stop the tile anti-aliasing } else if (currentBrush.Style == BrushStyle.BS_PATTERN | currentBrush.Style == BrushStyle.BS_DIBPATTERN | currentBrush.Style == BrushStyle.BS_DIBPATTERNPT) { var newBrush = new SolidColorBrush(Colors.Black); #if !NETFX_CORE newBrush.Freeze(); #endif shape.Fill = newBrush; } else if (currentBrush.Style == BrushStyle.BS_HATCHED) { #if !NETFX_CORE var patternBrush = new VisualBrush(); var patternTile = new Canvas(); var stroke1 = new Path(); var stroke2 = new Path(); var figure1 = new PathFigure(); var figure2 = new PathFigure(); var segments1 = new PathSegmentCollection(); var segments2 = new PathSegmentCollection(); patternBrush.TileMode = TileMode.Tile; patternBrush.Viewport = new Rect(0, 0, 10, 10); patternBrush.ViewportUnits = BrushMappingMode.Absolute; patternBrush.Viewbox = new Rect(0, 0, 10, 10); patternBrush.ViewboxUnits = BrushMappingMode.Absolute; stroke1.Data = new PathGeometry(); stroke2.Data = new PathGeometry(); switch (currentBrush.Hatch) { case HatchStyle.HS_BDIAGONAL: // A 45-degree upward, left-to-right hatch. figure1.StartPoint = new Point(0, 10); var up45Segment = new LineSegment { Point = new Point(10, 0) }; segments1.Add(up45Segment); figure1.Segments = segments1; ((PathGeometry)stroke1.Data).Figures.Add(figure1); patternTile.Children.Add(stroke1); break; case HatchStyle.HS_CROSS: // A horizontal and vertical cross-hatch. figure1.StartPoint = new Point(5, 0); figure2.StartPoint = new Point(0, 5); var downXSegment = new LineSegment { Point = new Point(5, 10) }; segments1.Add(downXSegment); figure1.Segments = segments1; var rightXSegment = new LineSegment { Point = new Point(10, 5) }; segments2.Add(rightXSegment); figure1.Segments = segments1; figure2.Segments = segments2; ((PathGeometry)stroke1.Data).Figures.Add(figure1); ((PathGeometry)stroke2.Data).Figures.Add(figure2); patternTile.Children.Add(stroke1); patternTile.Children.Add(stroke2); break; case HatchStyle.HS_DIAGCROSS: // A 45-degree crosshatch. figure1.StartPoint = new Point(0, 0); figure2.StartPoint = new Point(0, 10); var downDXSegment = new LineSegment { Point = new Point(10, 10) }; segments1.Add(downDXSegment); figure1.Segments = segments1; var rightDXSegment = new LineSegment { Point = new Point(10, 0) }; segments2.Add(rightDXSegment); figure1.Segments = segments1; figure2.Segments = segments2; ((PathGeometry)stroke1.Data).Figures.Add(figure1); ((PathGeometry)stroke2.Data).Figures.Add(figure2); patternTile.Children.Add(stroke1); patternTile.Children.Add(stroke2); break; case HatchStyle.HS_FDIAGONAL: // A 45-degree downward, left-to-right hatch. figure1.StartPoint = new Point(0, 0); var down45Segment = new LineSegment { Point = new Point(10, 10) }; segments1.Add(down45Segment); figure1.Segments = segments1; ((PathGeometry)stroke1.Data).Figures.Add(figure1); patternTile.Children.Add(stroke1); break; case HatchStyle.HS_HORIZONTAL: // A horizontal hatch. figure1.StartPoint = new Point(0, 10); var bottomSegment = new LineSegment { Point = new Point(10, 10) }; segments1.Add(bottomSegment); figure1.Segments = segments1; ((PathGeometry)stroke1.Data).Figures.Add(figure1); patternTile.Children.Add(stroke1); break; case HatchStyle.HS_VERTICAL: // A vertical hatch. figure1.StartPoint = new Point(10, 0); var verticalSegment = new LineSegment { Point = new Point(10, 10) }; segments1.Add(verticalSegment); figure1.Segments = segments1; ((PathGeometry)stroke1.Data).Figures.Add(figure1); patternTile.Children.Add(stroke1); break; } patternBrush.Visual = patternTile; //patternBrush.Freeze(); // Cant freeze a visual brush shape.Fill = patternBrush; #endif } else { var newBrush = new SolidColorBrush(currentBrush.Colour); #if !NETFX_CORE newBrush.Freeze(); #endif shape.Fill = newBrush; } } }
public override void beginPath() { _path = new PathGeometry(); _pathFigure = null; }
public void Pie(Canvas surface, double left, double top, double right, double bottom, double radial1X, double radial1Y, double radial2X, double radial2Y) { var pie = new Path(); var figure = new PathFigure(); var segments = new PathSegmentCollection(); var center = new Point(left + ((right - left) / 2), top + ((bottom - top) / 2)); var degrees = Math.Atan2(radial1Y - center.Y, radial1X - center.X) - Math.Atan2(radial2Y - center.Y, radial2X - center.X); degrees *= 57.2957795; // Convert from radians to degrees bool isLargeArc = Math.Abs(degrees) > 180; pie.Data = new PathGeometry(); figure.IsClosed = true; figure.StartPoint = new Point(LtoDX(radial1X), LtoDY(radial1Y)); var segment = new ArcSegment { Point = new Point(LtoDX(radial1X), LtoDY(radial1Y)), Size = new Size((LtoDX(right) - LtoDX(left)) / 2, (LtoDY(bottom) - LtoDY(top)) / 2), RotationAngle = 0, IsLargeArc = isLargeArc, SweepDirection = SweepDirection.Counterclockwise, }; segments.Add(segment); segments.Add( new LineSegment { Point = center } ); figure.Segments = segments; ((PathGeometry)pie.Data).Figures.Add(figure); ApplyStyle(pie, true); surface.Children.Add(pie); }
private static void OnValueChanged(DependencyObject d) { RadialGauge radialGauge = (RadialGauge)d; if (!double.IsNaN(radialGauge.Value)) { if (radialGauge.StepSize != 0) { radialGauge.Value = radialGauge.RoundToMultiple(radialGauge.Value, radialGauge.StepSize); } var middleOfScale = 100 - radialGauge.ScalePadding - (radialGauge.ScaleWidth / 2); var valueText = radialGauge.GetTemplateChild(ValueTextPartName) as TextBlock; radialGauge.ValueAngle = radialGauge.ValueToAngle(radialGauge.Value); // Needle if (radialGauge._needle != null) { radialGauge._needle.RotationAngleInDegrees = (float)radialGauge.ValueAngle; } // Trail var trail = radialGauge.GetTemplateChild(TrailPartName) as Path; if (trail != null) { if (radialGauge.ValueAngle > radialGauge.NormalizedMinAngle) { trail.Visibility = Visibility.Visible; if (radialGauge.ValueAngle - radialGauge.NormalizedMinAngle == 360) { // Draw full circle. var eg = new EllipseGeometry(); eg.Center = new Point(100, 100); eg.RadiusX = 100 - radialGauge.ScalePadding - (radialGauge.ScaleWidth / 2); eg.RadiusY = eg.RadiusX; trail.Data = eg; } else { // Draw arc. var pg = new PathGeometry(); var pf = new PathFigure(); pf.IsClosed = false; pf.StartPoint = radialGauge.ScalePoint(radialGauge.NormalizedMinAngle, middleOfScale); var seg = new ArcSegment(); seg.SweepDirection = SweepDirection.Clockwise; seg.IsLargeArc = radialGauge.ValueAngle > (180 + radialGauge.NormalizedMinAngle); seg.Size = new Size(middleOfScale, middleOfScale); seg.Point = radialGauge.ScalePoint(Math.Min(radialGauge.ValueAngle, radialGauge.NormalizedMaxAngle), middleOfScale); // On overflow, stop trail at MaxAngle. pf.Segments.Add(seg); pg.Figures.Add(pf); trail.Data = pg; } } else { trail.Visibility = Visibility.Collapsed; } } // Value Text if (valueText != null) { valueText.Text = radialGauge.Value.ToString(radialGauge.ValueStringFormat); } } }
internal override void draw() { // 绘图形 Path path = new Path(); Path patha = new Path(); if (isFirstLayer) { //Data="M 100,100 A 200,200 45 0 0 0,0 A 200,200 45 0 1 90,100" /> PathGeometry pg = new PathGeometry(); PathFigure pf = new PathFigure(); pg.Figures.Add(pf); pf.StartPoint = from; PathGeometry pga = new PathGeometry(); PathFigure pfa = new PathFigure(); pga.Figures.Add(pfa); pfa.StartPoint = froma; if (isUp) { ArcSegment ps = new ArcSegment(to, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Counterclockwise, false); pf.Segments.Add(ps); ps = new ArcSegment(from2, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Clockwise, false); pf.Segments.Add(ps); ps = new ArcSegment(to, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Counterclockwise, false); pfa.Segments.Add(ps); ps = new ArcSegment(froma2, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Clockwise, false); pfa.Segments.Add(ps); } else { ArcSegment ps = new ArcSegment(to, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Clockwise, false); pf.Segments.Add(ps); ps = new ArcSegment(from2, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Counterclockwise, false); pf.Segments.Add(ps); ps = new ArcSegment(to, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Clockwise, false); pfa.Segments.Add(ps); ps = new ArcSegment(froma2, new Size(len * 1.5, len * 1.5), 45, false, SweepDirection.Counterclockwise, false); pfa.Segments.Add(ps); } path.Data = pg; path.Fill = branchBrush; path.StrokeThickness = 0; patha.Data = pga; byte gb = (byte)(255.0f * (1.0f - 1.0f * bones.Count(p => p.isWarning) / bones.Count)); patha.Fill = new SolidColorBrush(Color.FromRgb(255, gb, gb)); patha.StrokeThickness = 0; patha.Effect = new System.Windows.Media.Effects.BlurEffect() { Radius = 5 }; } else { LineGeometry geo = new LineGeometry(from, to); path.Data = geo; path.Stroke = branchBrush; path.StrokeThickness = thickness; path.StrokeEndLineCap = PenLineCap.Triangle; } if (isWarning) { path.Effect = new System.Windows.Media.Effects.DropShadowEffect() { ShadowDepth = 0, BlurRadius = 5, Color = Colors.Yellow } } ; Canvas.SetZIndex(path, -1 * layer); fish.canv.Children.Add(path); Canvas.SetZIndex(patha, -1 * layer); fish.canv.Children.Add(patha); foreach (SubBone bon in bones) { bon.draw(); } }
public DataPoint(DateTime Time, double Value, double X, double Y, FrameworkElement DataUIElement, PathFigure figure, LineSegment lineSegment, string Name = null, string Description = null) { this.Time = Time; this.Value = Value; this.X = X; this.Y = Y; this.DataUIElements = new List <FrameworkElement>(); DataUIElements.Add(DataUIElement); this.Name = Name; this.Description = Description; this.LineSegment = lineSegment; this.Figure = figure; }
/// <summary> /// Adds a polygon to this path. /// </summary> public void AddPolygon(XPoint[] points) { #if CORE int count = points.Length; if (count == 0) return; _corePath.MoveTo(points[0].X, points[0].Y); for (int idx = 0; idx < count - 1; idx++) _corePath.LineTo(points[idx].X, points[idx].Y, false); _corePath.LineTo(points[count - 1].X, points[count - 1].Y, true); _corePath.CloseSubpath(); #endif #if GDI try { Lock.EnterGdiPlus(); _gdipPath.AddPolygon(XGraphics.MakePointFArray(points)); } finally { Lock.ExitGdiPlus(); } #endif #if WPF || NETFX_CORE #if !SILVERLIGHT && !NETFX_CORE _pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(XGraphics.MakePointArray(points), XFillMode.Alternate, true)); #else var figure = new PathFigure(); figure.StartPoint = new SysPoint(points[0].X, points[0].Y); figure.IsClosed = true; PolyLineSegment segment = new PolyLineSegment(); int count = points.Length; // For correct drawing the start point of the segment must not be the same as the first point. for (int idx = 1; idx < count; idx++) segment.Points.Add(new SysPoint(points[idx].X, points[idx].Y)); #if !SILVERLIGHT && !NETFX_CORE seg.IsStroked = true; #endif figure.Segments.Add(segment); _pathGeometry.Figures.Add(figure); #endif // TODO: NOT NEEDED //CloseFigure(); // StartFigure() isn't needed because AddGeometry() implicitly starts a new figure, but CloseFigure() is needed for the next adding not to continue this figure. #endif }
public override void Draw(DrawingContext dc) { if (!IsVisible) { return; } base.Draw(dc); // // p2 // /\ // / \ // p4 -p3- p5 // | // | // p1 // Vector v = EndPoint - StartPoint; var vn = v; vn.Normalize(); if (v.Length > 0) { // // Startpoint that lies on the edge of an UmlDiagramClass // var p1 = StartConnectorPoint; // // Endpoint that lies on the edge of an UmlDiagramClass // var p2 = EndConnectorPoint; Vector endApproachVector = !DoubleUtility.AreClose(0.0, BendingOffset) ? GetDirectionVectorOnCurve(EndOffset) : vn; var v1 = endApproachVector * Utils.Rotation30Matrix; var v2 = endApproachVector * Utils.RotationMin30Matrix; v1.Normalize(); v2.Normalize(); var p3 = p2 - endApproachVector * Math.Cos(30 * Math.PI / 180) * ArrowLength; var p4 = p2 - v1 * ArrowLength; var p5 = p2 - v2 * ArrowLength; PathGeometry geo = new PathGeometry(); PathFigure figure = new PathFigure(); figure.StartPoint = StartPoint; if (!DoubleUtility.AreClose(0.0, BendingOffset)) { PolyQuadraticBezierSegment bezier = new PolyQuadraticBezierSegment(); bezier.Points.Add(BendingPoint); bezier.Points.Add(EndPoint); figure.Segments.Add(bezier); } else { LineSegment lineSegment = new LineSegment(EndPoint, true); figure.Segments.Add(lineSegment); } PathGeometry geo2 = new PathGeometry(); PathFigure arrowFigure = new PathFigure(); arrowFigure.StartPoint = p2; PolyLineSegment polyLineSegment = new PolyLineSegment(new[] { p4, p5, p2 }, true); arrowFigure.Segments.Add(polyLineSegment); geo.Figures.Add(figure); geo2.Figures.Add(arrowFigure); dc.DrawGeometry(null, GetMainLinePen(), geo); dc.DrawGeometry(Utils.DefaultBackgroundBrush, Utils.DefaultPen, geo2); } }
protected IEnumerable<Point> GetPoints(PathFigure figure) { yield return figure.StartPoint; foreach (PolyLineSegment segment in figure.Segments) { foreach (var point in segment.Points) { yield return point; } } }
private IRenderingElement GenerateSgroupBrackets(Sgroup sgroup, IList <SgroupBracket> brackets, IReadOnlyDictionary <IAtom, AtomSymbol> symbols, string subscriptSuffix, string superscriptSuffix) { // brackets are square by default (style:0) var style = (int?)sgroup.GetValue(SgroupKey.CtabBracketStyle); bool round = style != null && style == 1; ElementGroup result = new ElementGroup(); var atoms = sgroup.Atoms; var crossingBonds = sgroup.Bonds; // easy to depict in correct orientation, we just // point each bracket at the atom of a crossing // bond that is 'in' the group - this scales // to more than two brackets // first we need to pair the brackets with the bonds var pairs = crossingBonds.Count == brackets.Count ? BracketBondPairs(brackets, crossingBonds) : Dictionaries.Empty <SgroupBracket, IBond>(); // override bracket layout around single atoms to bring them in closer if (atoms.Count == 1) { IAtom atom = atoms.First(); // e.g. 2 HCL, 8 H2O etc. if (IsUnsignedInt(subscriptSuffix) && !crossingBonds.Any() && symbols.ContainsKey(atom)) { TextOutline prefix = new TextOutline('·' + subscriptSuffix, font, emSize).Resize(1 / scale, 1 / -scale); Rect prefixBounds = prefix.LogicalBounds; AtomSymbol symbol = symbols[atom]; Rect bounds = symbol.GetConvexHull().Outline.Bounds; // make slightly large bounds = new Rect(bounds.Bottom - 2 * stroke, bounds.Left - 2 * stroke, bounds.Width + 4 * stroke, bounds.Height + 4 * stroke); prefix = prefix.Translate(bounds.Bottom - prefixBounds.Top, symbol.GetAlignmentCenter().Y - prefixBounds.CenterY()); result.Add(GeneralPath.ShapeOf(prefix.GetOutline(), foreground)); } // e.g. CC(O)nCC else if (crossingBonds.Count > 0) { double scriptscale = labelScale; TextOutline leftBracket = new TextOutline("(", font, emSize).Resize(1 / scale, 1 / -scale); TextOutline rightBracket = new TextOutline(")", font, emSize).Resize(1 / scale, 1 / -scale); var leftCenter = leftBracket.GetCenter(); var rightCenter = rightBracket.GetCenter(); if (symbols.ContainsKey(atom)) { AtomSymbol symbol = symbols[atom]; var bounds = symbol.GetConvexHull().Outline.Bounds; // make slightly large bounds = new Rect(bounds.Left - 2 * stroke, bounds.Top - 2 * stroke, bounds.Width + 4 * stroke, bounds.Height + 4 * stroke); leftBracket = leftBracket.Translate(bounds.Left - 0.1 - leftCenter.X, symbol.GetAlignmentCenter().Y - leftCenter.Y); rightBracket = rightBracket.Translate(bounds.Right + 0.1 - rightCenter.X, symbol.GetAlignmentCenter().Y - rightCenter.Y); } else { Vector2 p = atoms.First().Point2D.Value; leftBracket = leftBracket.Translate(p.X - 0.2 - leftCenter.X, p.Y - leftCenter.Y); rightBracket = rightBracket.Translate(p.X + 0.2 - rightCenter.X, p.Y - rightCenter.Y); } result.Add(GeneralPath.ShapeOf(leftBracket.GetOutline(), foreground)); result.Add(GeneralPath.ShapeOf(rightBracket.GetOutline(), foreground)); var rightBracketBounds = rightBracket.GetBounds(); // subscript/superscript suffix annotation if (subscriptSuffix != null && subscriptSuffix.Any()) { TextOutline subscriptOutline = LeftAlign(MakeText(subscriptSuffix.ToLowerInvariant(), new Vector2(rightBracketBounds.Right, rightBracketBounds.Top - 0.1), new Vector2(-0.5 * rightBracketBounds.Width, 0), scriptscale)); result.Add(GeneralPath.ShapeOf(subscriptOutline.GetOutline(), foreground)); } if (superscriptSuffix != null && superscriptSuffix.Any()) { TextOutline superscriptOutline = LeftAlign(MakeText(superscriptSuffix.ToLowerInvariant(), new Vector2(rightBracketBounds.Right, rightBracketBounds.Bottom + 0.1), new Vector2(-rightBracketBounds.Width, 0), scriptscale)); result.Add(GeneralPath.ShapeOf(superscriptOutline.GetOutline(), foreground)); } } } else if (pairs.Any()) { SgroupBracket suffixBracket = null; Vector2? suffixBracketPerp = null; foreach (var e in pairs) { var bracket = e.Key; var bond = e.Value; var inGroupAtom = atoms.Contains(bond.Begin) ? bond.Begin : bond.End; var p1 = bracket.FirstPoint; var p2 = bracket.SecondPoint; var perp = VecmathUtil.NewPerpendicularVector(VecmathUtil.NewUnitVector(p1, p2)); // point the vector at the atom group Vector2 midpoint = VecmathUtil.Midpoint(p1, p2); if (Vector2.Dot(perp, VecmathUtil.NewUnitVector(midpoint, inGroupAtom.Point2D.Value)) < 0) { perp = Vector2.Negate(perp); } perp *= bracketDepth; if (round) { result.Add(CreateRoundBracket(p1, p2, perp, midpoint)); } else { result.Add(CreateSquareBracket(p1, p2, perp)); } if (suffixBracket == null) { suffixBracket = bracket; suffixBracketPerp = perp; } else { // is this bracket better as a suffix? Vector2 sp1 = suffixBracket.FirstPoint; Vector2 sp2 = suffixBracket.SecondPoint; double bestMaxX = Math.Max(sp1.X, sp2.X); double thisMaxX = Math.Max(p1.X, p2.X); double bestMaxY = Math.Max(sp1.Y, sp2.Y); double thisMaxY = Math.Max(p1.Y, p2.Y); // choose the most eastern or.. the most southern double xDiff = thisMaxX - bestMaxX; double yDiff = thisMaxY - bestMaxY; if (xDiff > EQUIV_THRESHOLD || (xDiff > -EQUIV_THRESHOLD && yDiff < -EQUIV_THRESHOLD)) { suffixBracket = bracket; suffixBracketPerp = perp; } } } // write the labels if (suffixBracket != null) { Vector2 subSufPnt = suffixBracket.FirstPoint; Vector2 supSufPnt = suffixBracket.SecondPoint; // try to put the subscript on the bottom double xDiff = subSufPnt.X - supSufPnt.X; double yDiff = subSufPnt.Y - supSufPnt.Y; if (yDiff > EQUIV_THRESHOLD || (yDiff > -EQUIV_THRESHOLD && xDiff > EQUIV_THRESHOLD)) { Vector2 tmpP = subSufPnt; subSufPnt = supSufPnt; supSufPnt = tmpP; } // subscript/superscript suffix annotation if (subscriptSuffix != null && subscriptSuffix.Any()) { TextOutline subscriptOutline = LeftAlign(MakeText(subscriptSuffix.ToLowerInvariant(), subSufPnt, suffixBracketPerp.Value, labelScale)); result.Add(GeneralPath.ShapeOf(subscriptOutline.GetOutline(), foreground)); } if (superscriptSuffix != null && superscriptSuffix.Any()) { TextOutline superscriptOutline = LeftAlign(MakeText(superscriptSuffix.ToLowerInvariant(), supSufPnt, suffixBracketPerp.Value, labelScale)); result.Add(GeneralPath.ShapeOf(superscriptOutline.GetOutline(), foreground)); } } } else if (brackets.Count == 2) { var b1p1 = brackets[0].FirstPoint; var b1p2 = brackets[0].SecondPoint; var b2p1 = brackets[1].FirstPoint; var b2p2 = brackets[1].SecondPoint; var b1vec = VecmathUtil.NewUnitVector(b1p1, b1p2); var b2vec = VecmathUtil.NewUnitVector(b2p1, b2p2); var b1pvec = VecmathUtil.NewPerpendicularVector(b1vec); var b2pvec = VecmathUtil.NewPerpendicularVector(b2vec); // Point the vectors at each other if (Vector2.Dot(b1pvec, VecmathUtil.NewUnitVector(b1p1, b2p1)) < 0) { b1pvec = Vector2.Negate(b1pvec); } if (Vector2.Dot(b2pvec, VecmathUtil.NewUnitVector(b2p1, b1p1)) < 0) { b2pvec = Vector2.Negate(b2pvec); } // scale perpendicular vectors by how deep the brackets need to be b1pvec *= bracketDepth; b2pvec *= bracketDepth; // bad brackets if (double.IsNaN(b1pvec.X) || double.IsNaN(b1pvec.Y) || double.IsNaN(b2pvec.X) || double.IsNaN(b2pvec.Y)) { return(result); } { var path = new PathGeometry(); if (round) { { // bracket 1 (cp: control point) var pf = new PathFigure { StartPoint = new Point(b1p1.X + b1pvec.X, b1p1.Y + b1pvec.Y) }; Vector2 cpb1 = VecmathUtil.Midpoint(b1p1, b1p2); cpb1 += VecmathUtil.Negate(b1pvec); var seg = new QuadraticBezierSegment { Point1 = new Point(cpb1.X, cpb1.Y), Point2 = new Point(b1p2.X + b1pvec.X, b1p2.Y + b1pvec.Y) }; pf.Segments.Add(seg); path.Figures.Add(pf); } { // bracket 2 (cp: control point) var pf = new PathFigure { StartPoint = new Point(b2p1.X + b2pvec.X, b2p1.Y + b2pvec.Y) }; Vector2 cpb2 = VecmathUtil.Midpoint(b2p1, b2p2); cpb2 += VecmathUtil.Negate(b2pvec); var seg = new QuadraticBezierSegment { Point1 = new Point(cpb2.X, cpb2.Y), Point2 = new Point(b2p2.X + b2pvec.X, b2p2.Y + b2pvec.Y) }; pf.Segments.Add(seg); path.Figures.Add(pf); } } else { { // bracket 1 var pf = new PathFigure { StartPoint = new Point(b1p1.X + b1pvec.X, b1p1.Y + b1pvec.Y) }; var seg = new PolyLineSegment(); seg.Points.Add(new Point(b1p1.X, b1p1.Y)); seg.Points.Add(new Point(b1p2.X, b1p2.Y)); seg.Points.Add(new Point(b1p2.X + b1pvec.X, b1p2.Y + b1pvec.Y)); pf.Segments.Add(seg); path.Figures.Add(pf); } { // bracket 2 var pf = new PathFigure { StartPoint = new Point(b2p1.X + b2pvec.X, b2p1.Y + b2pvec.Y) }; var seg = new PolyLineSegment(); seg.Points.Add(new Point(b2p1.X, b2p1.Y)); seg.Points.Add(new Point(b2p2.X, b2p2.Y)); seg.Points.Add(new Point(b2p2.X + b2pvec.X, b2p2.Y + b2pvec.Y)); pf.Segments.Add(seg); path.Figures.Add(pf); } } result.Add(GeneralPath.OutlineOf(path, stroke, foreground)); } // work out where to put the suffix labels (e.g. ht/hh/eu) superscript // and (e.g. n, xl, c, mix) subscript // TODO: could be improved double b1MaxX = Math.Max(b1p1.X, b1p2.X); double b2MaxX = Math.Max(b2p1.X, b2p2.X); double b1MaxY = Math.Max(b1p1.Y, b1p2.Y); double b2MaxY = Math.Max(b2p1.Y, b2p2.Y); Vector2 subSufPnt = b2p2; Vector2 supSufPnt = b2p1; Vector2 subpvec = b2pvec; double bXDiff = b1MaxX - b2MaxX; double bYDiff = b1MaxY - b2MaxY; if (bXDiff > EQUIV_THRESHOLD || (bXDiff > -EQUIV_THRESHOLD && bYDiff < -EQUIV_THRESHOLD)) { subSufPnt = b1p2; supSufPnt = b1p1; subpvec = b1pvec; } double xDiff = subSufPnt.X - supSufPnt.X; double yDiff = subSufPnt.Y - supSufPnt.Y; if (yDiff > EQUIV_THRESHOLD || (yDiff > -EQUIV_THRESHOLD && xDiff > EQUIV_THRESHOLD)) { Vector2 tmpP = subSufPnt; subSufPnt = supSufPnt; supSufPnt = tmpP; } // subscript/superscript suffix annotation if (subscriptSuffix != null && subscriptSuffix.Any()) { TextOutline subscriptOutline = LeftAlign(MakeText(subscriptSuffix.ToLowerInvariant(), subSufPnt, subpvec, labelScale)); result.Add(GeneralPath.ShapeOf(subscriptOutline.GetOutline(), foreground)); } if (superscriptSuffix != null && superscriptSuffix.Any()) { TextOutline superscriptOutline = LeftAlign(MakeText(superscriptSuffix.ToLowerInvariant(), supSufPnt, subpvec, labelScale)); result.Add(GeneralPath.ShapeOf(superscriptOutline.GetOutline(), foreground)); } } return(result); }
void drawTail() { Path path = new Path(); PathGeometry pg = new PathGeometry(); path.Data = pg; Point sp0, sp, cp1, cp2, ep; Vector vc, vc2; double zlen; RotateTransform r; PathFigure pf = new PathFigure(); pg.Figures.Add(pf); sp0 = new Point(to.X - 15, to.Y - fish.para.MainBoneThickness / 2); pf.StartPoint = sp0; //if (fish.para.fishDirection== EFishDirection.头向右) { ep = new Point(20, 200); vc = ep - sp0; zlen = vc.Length; vc.Normalize(); r = new RotateTransform(-90); vc2 = (Vector)r.Transform((Point)vc); cp1 = sp0 + 0.3 * zlen * vc; cp1 = cp1 + 0.1 * zlen * vc2; cp2 = sp0 + 0.7 * zlen * vc; cp2 = cp2 - 0.15 * zlen * vc2; BezierSegment bs = new BezierSegment(cp1, cp2, ep, true); pf.Segments.Add(bs); sp = ep; ep = new Point(20, fish.para.fishHeight - 200); vc = ep - sp; zlen = vc.Length; vc.Normalize(); r = new RotateTransform(-90); vc2 = (Vector)r.Transform((Point)vc); cp1 = sp + 0.4 * zlen * vc; cp1 = cp1 + 0.3 * zlen * vc2; cp2 = sp + 0.6 * zlen * vc; cp2 = cp2 + 0.3 * zlen * vc2; bs = new BezierSegment(cp1, cp2, ep, true); pf.Segments.Add(bs); sp = ep; ep = new Point(to.X - 15, to.Y + fish.para.MainBoneThickness / 2); vc = ep - sp; zlen = vc.Length; vc.Normalize(); r = new RotateTransform(-90); vc2 = (Vector)r.Transform((Point)vc); cp1 = sp + 0.3 * zlen * vc; cp1 = cp1 - 0.13 * zlen * vc2; cp2 = sp + 0.7 * zlen * vc; cp2 = cp2 + 0.13 * zlen * vc2; bs = new BezierSegment(cp1, cp2, ep, true); pf.Segments.Add(bs); pf.Segments.Add(new LineSegment(sp0, true)); path.Stroke = Brushes.Silver; path.StrokeThickness = 1; path.Fill = fish.para.HeadTailBrush; path.Opacity = fish.para.HeadTailOpacity; fish.canv.Children.Add(path); } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="arc"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XArc arc, double dx, double dy, ImmutableArray <ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = arc.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)); } } var a = WpfArc.FromXArc(arc, dx, dy); PathGeometry pg = null; if (_enableArcCache && _arcCache.TryGetValue(arc, out pg)) { var pf = pg.Figures[0]; pf.StartPoint = new Point(a.Start.X, a.Start.Y); pf.IsFilled = arc.IsFilled; var segment = pf.Segments[0] as ArcSegment; segment.Point = new Point(a.End.X, a.End.Y); segment.Size = new Size(a.Radius.Width, a.Radius.Height); segment.IsLargeArc = a.IsLargeArc; segment.IsStroked = arc.IsStroked; } else { var pf = new PathFigure() { StartPoint = new Point(a.Start.X, a.Start.Y), IsFilled = arc.IsFilled }; var segment = new ArcSegment( new Point(a.End.X, a.End.Y), new Size(a.Radius.Width, a.Radius.Height), 0.0, a.IsLargeArc, SweepDirection.Clockwise, arc.IsStroked); //segment.Freeze(); pf.Segments.Add(segment); //pf.Freeze(); pg = new PathGeometry(); pg.Figures.Add(pf); //pg.Freeze(); if (_enableArcCache) { _arcCache.Add(arc, pg); } } DrawPathGeometryInternal(_dc, half, fill, stroke, arc.IsStroked, arc.IsFilled, pg); }
// Reset this path. public void Reset() { pathPoints = new PointF[0]; // reset path points actualFigure = null; pathFigures.Clear(); needPenBrush = false; fillMode = FillMode.Alternate; }
/// <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); }
public object Clone() { PathFigure cpy = new PathFigure(); foreach( PathObject o in pathObjs ) { cpy.AddPathObject( o.Clone() ); } return cpy; }
/// <summary> /// Draws the pie piece /// </summary> private void SetRenderData() { var innerArcStartPoint = PieUtils.ComputeCartesianCoordinate(RotationAngle, InnerRadius, this); innerArcStartPoint.X += XOffset; innerArcStartPoint.Y += YOffset; var innerArcEndPoint = PieUtils.ComputeCartesianCoordinate(RotationAngle + WedgeAngle, InnerRadius, this); innerArcEndPoint.X += XOffset; innerArcEndPoint.Y += YOffset; var outerArcStartPoint = PieUtils.ComputeCartesianCoordinate(RotationAngle, Radius, this); outerArcStartPoint.X += XOffset; outerArcStartPoint.Y += YOffset; var outerArcEndPoint = PieUtils.ComputeCartesianCoordinate(RotationAngle + WedgeAngle, Radius, this); outerArcEndPoint.X += XOffset; outerArcEndPoint.Y += YOffset; var innerArcMidPoint = PieUtils.ComputeCartesianCoordinate(RotationAngle + WedgeAngle * .5, InnerRadius, this); innerArcMidPoint.X += XOffset; innerArcMidPoint.Y += YOffset; var outerArcMidPoint = PieUtils.ComputeCartesianCoordinate(RotationAngle + WedgeAngle * .5, Radius, this); outerArcMidPoint.X += XOffset; outerArcMidPoint.Y += YOffset; var largeArc = WedgeAngle > 180.0d; var requiresMidPoint = Math.Abs(WedgeAngle - 360) < .01; if (PushOut > 0 && !requiresMidPoint) { var offset = PieUtils.ComputeCartesianCoordinate(RotationAngle + WedgeAngle / 2, PushOut, this); offset.X -= Width * .5; offset.Y -= Height * .5; innerArcStartPoint.X += offset.X; innerArcStartPoint.Y += offset.Y; innerArcEndPoint.X += offset.X; innerArcEndPoint.Y += offset.Y; outerArcStartPoint.X += offset.X; outerArcStartPoint.Y += offset.Y; outerArcEndPoint.X += offset.X; outerArcEndPoint.Y += offset.Y; } var outerArcSize = new Size(Radius, Radius); var innerArcSize = new Size(InnerRadius, InnerRadius); var pathFigure = new PathFigure { IsClosed = true, IsFilled = true, StartPoint = innerArcStartPoint }; if (requiresMidPoint) { pathFigure.Segments.Add(new LineSegment { Point = outerArcStartPoint }); pathFigure.Segments.Add(new ArcSegment { Point = outerArcMidPoint, Size = outerArcSize, RotationAngle = 0, IsLargeArc = false, SweepDirection = SweepDirection.Clockwise }); pathFigure.Segments.Add(new ArcSegment { Point = outerArcEndPoint, Size = outerArcSize, RotationAngle = 0, IsLargeArc = false, SweepDirection = SweepDirection.Clockwise }); pathFigure.Segments.Add(new LineSegment { Point = innerArcEndPoint }); pathFigure.Segments.Add(new ArcSegment { Point = innerArcMidPoint, Size = innerArcSize, RotationAngle = 0, IsLargeArc = false, SweepDirection = SweepDirection.Counterclockwise }); pathFigure.Segments.Add(new ArcSegment { Point = innerArcStartPoint, Size = innerArcSize, RotationAngle = 0, IsLargeArc = false, SweepDirection = SweepDirection.Counterclockwise }); } else { pathFigure.Segments.Add(new LineSegment { Point = outerArcStartPoint }); pathFigure.Segments.Add(new ArcSegment { Point = outerArcEndPoint, Size = outerArcSize, RotationAngle = 0, IsLargeArc = largeArc, SweepDirection = SweepDirection.Clockwise }); pathFigure.Segments.Add(new LineSegment { Point = innerArcEndPoint }); pathFigure.Segments.Add(new ArcSegment { Point = innerArcStartPoint, Size = innerArcSize, RotationAngle = 0, IsLargeArc = largeArc, SweepDirection = SweepDirection.Counterclockwise }); } Data = new PathGeometry { Figures = new PathFigureCollection() { pathFigure }, FillRule = FillRule.EvenOdd }; }
public MainWindow() { // This should only be done once, // so it is being done here. // Processing.Audio.Initialize(); InitializeComponent(); MainWindow.height = (int)this.Height; MainWindow.width = (int)this.Width; DispatcherTimer Timer = new DispatcherTimer(); Timer.Interval = TimeSpan.FromMilliseconds(tickAmount); Path path = new Path(); path.Stroke = System.Windows.Media.Brushes.RoyalBlue; path.StrokeThickness = 10; mainCanvas.Children.Add(path); Timer.Tick += (delegate(object s, EventArgs args) { if (!_isManipulating) { if (currentlySelectedObject != null ) { if (angle > 360) { if (currentlySelectedObject is Button) { ((Button)currentlySelectedObject).PerformClick(); } else if (currentlySelectedObject is NavigationButton) { ((NavigationButton)currentlySelectedObject).Click(); } else { ((SelectionPage)currentPage).Click(); } path.Visibility = Visibility.Hidden; angle = 0; } else { path.Visibility = Visibility.Visible; System.Windows.Point mousePos = Mouse.GetPosition(mainCanvas); System.Windows.Point endPoint = new System.Windows.Point(mousePos.X + 40 * Math.Sin(angle / 180.0 * Math.PI), mousePos.Y - 40 * Math.Cos(angle / 180.0 * Math.PI)); PathFigure figure = new PathFigure(); figure.StartPoint = new System.Windows.Point(mousePos.X, mousePos.Y - 40); figure.Segments.Add(new ArcSegment( endPoint, new System.Windows.Size(40, 40), 0, angle >= 180, SweepDirection.Clockwise, true )); PathGeometry geometry = new PathGeometry(); geometry.Figures.Add(figure); path.Data = geometry; // Number of ticks in one second --> number of degrees angle += (360 / (1000 / tickAmount)); // <<<< CHANGE THIS BACK!! } } else { path.Visibility = Visibility.Hidden; angle = 0; } } }); homePage = new HomePage(); browseMusicPage = new BrowseMusic(); browseTutorialsPage = new BrowseTutorials(); freeFormPage = new FreeFormMode(); // tutorPage = new TutorMode(); soloPage = new SoloPage(); loadingPage = new LoadingPage(); frame.Navigate(homePage); currentPage = homePage; Timer.Start(); AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)HandleKeyDownEvent); AddHandler(Keyboard.KeyUpEvent, (KeyEventHandler)HandleKeyUpEvent); // Set the cursor to a hand image this.Cursor = new Cursor(new System.IO.MemoryStream(Properties.Resources.hand)); }
internal static void TranslateSelection(PathEditorTarget pathEditorTarget, ICollection <PathPart> pathParts, Vector offset) { List <BitArray> list = new List <BitArray>(pathEditorTarget.PathGeometry.Figures.Count); for (int index = 0; index < pathEditorTarget.PathGeometry.Figures.Count; ++index) { list.Add(new BitArray(PathFigureUtilities.PointCount(pathEditorTarget.PathGeometry.Figures[index]), false)); } foreach (PathPart pathPart in (IEnumerable <PathPart>)pathParts) { PathPoint pathPoint = pathPart as PathPoint; if ((PathPart)pathPoint != (PathPart)null) { if (pathPoint.PartIndex < list[pathPoint.FigureIndex].Count) { list[pathPoint.FigureIndex][pathPoint.PartIndex] = true; } } else { PathSegment pathSegment = pathPart as PathSegment; if ((PathPart)pathSegment != (PathPart)null) { list[pathSegment.FigureIndex][pathSegment.PartIndex] = true; PathFigure pathFigure = pathEditorTarget.PathGeometry.Figures[pathPart.FigureIndex]; if (pathFigure.IsClosed && pathPart.PartIndex == 0) { int num1 = PathFigureUtilities.PointCount(pathFigure); int num2 = 1; if (PathFigureUtilities.IsCloseSegmentDegenerate(pathFigure)) { num2 = PathSegmentUtilities.GetPointCount(pathFigure.Segments[pathFigure.Segments.Count - 1]); } list[pathSegment.FigureIndex][num1 - num2] = true; } else { int segmentIndex; int segmentPointIndex; PathFigureUtilities.GetSegmentFromPointIndex(pathFigure, pathPart.PartIndex, out segmentIndex, out segmentPointIndex); int pointCount = PathSegmentUtilities.GetPointCount(pathFigure.Segments[segmentIndex]); int index = pathSegment.PartIndex - pointCount; if (index >= 0) { list[pathSegment.FigureIndex][index] = true; } } } } } for (int figureIndex = 0; figureIndex < pathEditorTarget.PathGeometry.Figures.Count; ++figureIndex) { BitArray bitArray = list[figureIndex]; PathFigureEditor pathFigureEditor = new PathFigureEditor(pathEditorTarget.PathGeometry.Figures[figureIndex], pathEditorTarget.PathDiffChangeList, figureIndex); int num = PathFigureUtilities.PointCount(pathFigureEditor.PathFigure); for (int index = 0; index < num; ++index) { if (bitArray[index]) { pathFigureEditor.MovePoint(index, offset + pathFigureEditor.GetPoint(index)); } } } }
public void LineTo(Canvas surface, double x, double y) { var line = new Path(); var curPos = _currentState.CurrentPosition; var startPos = new Point(LtoDX(curPos.X), LtoDY(curPos.Y)); var endPos = new Point(LtoDX(x), LtoDY(y)); #if NETFX_CORE var geometry = new PathGeometry(); var figure = new PathFigure(); geometry.Figures.Add(figure); figure.StartPoint = startPos; figure.Segments.Add( new LineSegment() { Point = endPos } ); #else var geometry = new StreamGeometry(); using (var ctx = geometry.Open()) { ctx.BeginFigure(startPos, false, false); ctx.LineTo(endPos, true, false); } geometry.Freeze(); #endif line.Data = geometry; #if !NETFX_CORE line.SnapsToDevicePixels = true; #endif ApplyStyle(line, false); surface.Children.Add(line); _currentState.CurrentPosition = new Point(x, y); }
/// <summary> /// This method is called by the framework to create a <see cref="FrameworkElement"/> /// that will be included into the <see cref="IRenderContext"/>. /// </summary> /// <param name="context">The context that describes where the visual will be used.</param> /// <returns> /// The arrow visual to include in the canvas object visual tree./>. /// </returns> /// <seealso cref="UpdateVisual"/> Visual IVisualCreator.CreateVisual(IRenderContext context) { // Create a new Path to draw the arrow if (arrowFigure == null) { arrowFigure = new PathFigure { StartPoint = new Point(-7, -thickness / 2), Segments = { new LineSegment { Point = new Point(-7, thickness / 2) }, new BezierSegment { Point1 = new Point(-5, thickness / 2), Point2 = new Point(-1.5, thickness / 2), Point3 = new Point(1, thickness * 1.666) }, new BezierSegment { Point1 = new Point(0, thickness * 0.833), Point2 = new Point(0, -thickness * 0.833), Point3 = new Point(1, -thickness * 1.666) }, new BezierSegment { Point1 = new Point(-1.5, -thickness / 2), Point2 = new Point(-5, -thickness / 2), Point3 = new Point(-7, -thickness / 2) } } }; arrowFigure.Freeze(); } Path p = new Path { // set Stretch, MinWidth and MinHeight so Path gets drawn in negative coordinate range Stretch = Stretch.None, MinWidth = 1, MinHeight = 1, Fill = pathFill, // Draw arrow outline Data = new PathGeometry { Figures = { arrowFigure } } }; // Remember thickness for update p.SetRenderDataCache(thickness); // Rotate arrow and move it to correct position p.RenderTransform = new MatrixTransform { Matrix = new Matrix(direction.X, direction.Y, -direction.Y, direction.X, anchor.X, anchor.Y) }; return(p); }
//public static Line CreateLine(GBoxObj parent, GBoxObj child) //{ // Line l = new Line(); // l.X1 = parent.ColorBox.X + parent.ColorBox.Width / 2; // l.Y1 = parent.ColorBox.Y + parent.ColorBox.Height; // l.X2 = child.ColorBox.X + child.ColorBox.Width / 2; // l.Y2 = child.ColorBox.Y; // l.Tag = parent.Tag.ToString() + StaticCfg.Ins.ParentChildSplit + child.Tag.ToString(); // if (Math.Min(parent.GTagBox.Level, child.GTagBox.Level) == 0) // { // l.Stroke = new SolidColorBrush(GetColor(parent.GTagBox.Distance + 1, parent.GTagBox.Level + 1)); // l.StrokeThickness = StaticCfg.Ins.StrokeThickness * 1.5; // l.StrokeDashArray = StaticCfg.Ins.StrokeDashArray; // } // else // { // l.Stroke = new SolidColorBrush(GetColor(parent.GTagBox.Distance + 1, parent.GTagBox.Level + 1)); // l.StrokeThickness = StaticCfg.Ins.StrokeThickness; // l.StrokeDashArray = StaticCfg.Ins.StrokeDashArray; // } // return l; //} public static Path CreateBezier(Tuple <GTagBoxTree, GTagBoxTree, int> p_c, TreeLayoutEnv env) { GTagBoxTree p = p_c.Item1; GTagBoxTree c = p_c.Item2; int direct = (int)p_c.Item3; System.Windows.Point p1 = new System.Windows.Point(); System.Windows.Point p5 = new System.Windows.Point(); System.Windows.Point p2 = new System.Windows.Point(); System.Windows.Point p4 = new System.Windows.Point(); System.Windows.Point p3 = new System.Windows.Point(); if (direct == 1) { p1.X = p.GTagBox.InnerBox.Right; p5.X = c.GTagBox.InnerBox.Left; } else { p1.X = p.GTagBox.InnerBox.Left; p5.X = c.GTagBox.InnerBox.Right; } p1.Y = (p.GTagBox.InnerBox.Top + p.GTagBox.InnerBox.Bottom) / 2; p5.Y = (c.GTagBox.InnerBox.Top + c.GTagBox.InnerBox.Bottom) / 2; p3.X = (p1.X + p5.X) / 2; p3.Y = (p1.Y + p5.Y) / 2; const int N = 3; p2.X = (p1.X * N + p5.X) / (N + 1); p4.X = (p1.X + p5.X * N) / (N + 1); p2.Y = p1.Y; p4.Y = p5.Y; Path path = env.New(p_c); if (path.Data == null) { PathGeometry pg = new PathGeometry(); PathFigureCollection pfc = new PathFigureCollection(); PathFigure pf = new PathFigure(); BezierSegment seg1 = new BezierSegment(p1, p2, p3, true); seg1.IsSmoothJoin = true; BezierSegment seg2 = new BezierSegment(p3, p4, p5, true); seg2.IsSmoothJoin = true; //Path->PathGeometry->PathFigureCollection->PathFigure->PathSegmentCollection->BezierSegment path.Data = pg; //PathGeometry pg.Figures = pfc; //PathFigureCollection pfc.Add(pf); //PF pf.StartPoint = p1; pf.Segments.Add(seg1); pf.Segments.Add(seg2); pg.Figures.Add(pf); } else { PathGeometry pg = path.Data as PathGeometry; PathFigureCollection pfc = pg.Figures as PathFigureCollection; PathFigure pf = pfc[0] as PathFigure; pf.StartPoint = p1; BezierSegment seg1 = pf.Segments[0] as BezierSegment; BezierSegment seg2 = pf.Segments[1] as BezierSegment; seg1.Point1 = p1; seg1.Point2 = p2; seg1.Point3 = p3; seg2.Point1 = p3; seg2.Point2 = p4; seg2.Point3 = p5; //pg.Figures.Add(pf); } SetBezierStyle(p.GTagBox, c.GTagBox, path); return(path); }
private void RenderColorChart(DrawingContext dc, double width, double height) { //Determine the radius of the overall circle; we want this to be square in order to get a true circle, so use the min. extent double dblRadius = Math.Min(width / 2, height / 2); var szRadius = new Size(dblRadius, dblRadius); //Calculate the center of the control var ptCenter = new Point(dblRadius, dblRadius); if (SectorBrushes != null && SectorBrushes.Count > 1) { //The radius (degrees) that a single sector will cover double dblSectorRadius = 360d / SectorBrushes.Count; for (int intSectorCounter = 0; intSectorCounter < SectorBrushes.Count; intSectorCounter++) { //Get the start- and end-points of the current arc segment to be drawn var ptArcStartPoint = GetPointAtAngle(ptCenter, dblRadius, intSectorCounter * dblSectorRadius); var ptArcEndPoint = GetPointAtAngle(ptCenter, dblRadius, (intSectorCounter + 1) * dblSectorRadius); //The bounding rectangle of the current arc Sector var rctArcRect = new Rect(ptArcStartPoint, ptArcEndPoint); //Construct the shape var pg = new PathGeometry(); var pf = new PathFigure(); pg.Figures.Add(pf); pf.StartPoint = ptArcStartPoint; pf.IsFilled = true; // Add the current sector's arc-segment pf.Segments.Add( new ArcSegment( ptArcEndPoint, szRadius, dblSectorRadius, (dblSectorRadius >= 180), SweepDirection.Clockwise, false ) ); // Add a line that ends in the center of the control pf.Segments.Add( new LineSegment(ptCenter, true) ); // Close the figure (IOW, this will add a line between the center of the control and // the arc's start point, resulting in a pie shape) pf.IsClosed = true; //Draw the arc (skipping the Pen used for drawing a line around the shape) dc.DrawGeometry(SectorBrushes[intSectorCounter], null, pg); } } else if (SectorBrushes != null && SectorBrushes.Count == 1) { dc.DrawEllipse(SectorBrushes[0], null, ptCenter, dblRadius, dblRadius); } //Draw a circle around the sectors, if both a non-transparent color and a StrokeWidth>0 have been supplied. if (StrokeColor != null && StrokeColor != Colors.Transparent && StrokeWidth > 0) { dc.DrawEllipse(null, CachedStrokePen, ptCenter, dblRadius, dblRadius); } }
private void UpdatePath() { var innerRadius = InnerRadius + StrokeThickness / 2; var outerRadius = Radius - StrokeThickness / 2; if (_isUpdating || ActualWidth == 0 || innerRadius <= 0 || outerRadius < innerRadius) { return; } var pathGeometry = new PathGeometry(); var pathFigure = new PathFigure { IsClosed = true }; var center = Center ?? new Point( outerRadius + StrokeThickness / 2, outerRadius + StrokeThickness / 2); // Starting Point pathFigure.StartPoint = new Point( center.X + Math.Sin(StartAngle * Math.PI / 180) * innerRadius, center.Y - Math.Cos(StartAngle * Math.PI / 180) * innerRadius); // Inner Arc var innerArcSegment = new ArcSegment { IsLargeArc = (EndAngle - StartAngle) >= 180.0, Point = new Point( center.X + Math.Sin(EndAngle * Math.PI / 180) * innerRadius, center.Y - Math.Cos(EndAngle * Math.PI / 180) * innerRadius), Size = new Size(innerRadius, innerRadius), SweepDirection = SweepDirection.Clockwise }; var lineSegment = new LineSegment { Point = new Point( center.X + Math.Sin(EndAngle * Math.PI / 180) * outerRadius, center.Y - Math.Cos(EndAngle * Math.PI / 180) * outerRadius) }; // Outer Arc var outerArcSegment = new ArcSegment { IsLargeArc = (EndAngle - StartAngle) >= 180.0, Point = new Point( center.X + Math.Sin(StartAngle * Math.PI / 180) * outerRadius, center.Y - Math.Cos(StartAngle * Math.PI / 180) * outerRadius), Size = new Size(outerRadius, outerRadius), SweepDirection = SweepDirection.Counterclockwise }; pathFigure.Segments.Add(innerArcSegment); pathFigure.Segments.Add(lineSegment); pathFigure.Segments.Add(outerArcSegment); pathGeometry.Figures.Add(pathFigure); InvalidateArrange(); Data = pathGeometry; }
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (!this.runFlag) { return; } this.V0 = Power.Value; if (this.V0 == 0) { MessageBox.Show("You need to set power before shot! Check instruction!"); return; } Point point = e.GetPosition(this); var arrowTop = Canvas.GetTop(Arrow); var arrowLeft = Canvas.GetLeft(Arrow); Arrow.RenderTransform = animatedTranslateTransform; this.currentAngle = Math.Atan2(point.Y - arrowTop, point.X - arrowLeft); if (this.currentAngle > 1.57 || this.currentAngle < -1.57) { return; } var vy = this.V0 * Math.Sin(this.currentAngle); var vx = this.V0 * Math.Cos(this.currentAngle); var h = Math.Pow(vy, 2) / 2; var z = Math.Pow(V0, 2) * Math.Sin(2 * this.currentAngle); this.shotTime = TimeSpan.FromSeconds(Math.Abs(2 * this.V0 * Math.Sin(this.currentAngle) / 10)); var enemyLeft = Canvas.GetLeft(Enemy); var y1 = arrowTop - this.CalculateY(-enemyLeft); Rect r1 = new Rect(enemyLeft, y1, Arrow.ActualWidth, Arrow.ActualHeight); if (r1.IntersectsWith(r2)) { this.targeted = true; } List <double> listOfFunctionPoints = new List <double>(); double step = z / 10; double nextX = step; while (z * 1.2 < nextX) { if (-nextX > this.ActualWidth * 1.5) { break; } listOfFunctionPoints.Add(nextX); nextX += step; } if (listOfFunctionPoints.Count >= 11) { listOfFunctionPoints.RemoveAt(10); } if (targeted) { var firstPointXAfterEnemy = listOfFunctionPoints.FirstOrDefault(x => x < -enemyLeft); if (firstPointXAfterEnemy != 0) { var index = listOfFunctionPoints.IndexOf(firstPointXAfterEnemy); listOfFunctionPoints = listOfFunctionPoints.Take(index).ToList(); } listOfFunctionPoints.Add(-enemyLeft); } this.shotTime = TimeSpan.FromSeconds(listOfFunctionPoints.Max() / z * this.shotTime.TotalSeconds); PathGeometry animationPath = new PathGeometry(); PathFigure pFigure = new PathFigure(); pFigure.StartPoint = new Point(0, 0); PolyBezierSegment pBezierSegment = new PolyBezierSegment(); foreach (double pointX in listOfFunctionPoints) { pBezierSegment.Points.Add(new Point(-pointX, -this.CalculateY(pointX))); } //// Debug - show calculated values in window. //Dane.Visibility = Visibility.Hidden; // Dane.Visibility = Visibility.Visible; //Dane.Content = $"Enemy left : {enemyLeft}, Hmax = {h}, Zmax={z}, time: {this.shotTime.TotalMilliseconds}, pointX={point.X}, pointY={point.Y}"; //foreach (var item in pBezierSegment.Points) //{ // Dane.Content += Environment.NewLine + $"Point : {item.X}, {item.Y}"; //} pFigure.Segments.Add(pBezierSegment); animationPath.Figures.Add(pFigure); animationPath.Freeze(); this.ArrowAnimation(animationPath, this.shotTime); //Obliczanie rezultatu if (!this.targeted) { Result.Content = "Last shot result : Miss!"; //Jeśli nie trafimy to nie dodajemy żadnego punktów do naszego wyniku } else { //Jeśli trafimy to dodajemy 100 punktów - siła naszego strzału Result.Content = "Last shot result : Hit!"; result += 100 - this.Power.Value; } }
/// <summary> /// Refreshes this instance. /// </summary> public override void Refresh() { if (SplinePath != null) { PathFigure figure = new PathFigure(); BezierSegment bezierPoints = new BezierSegment(); PathGeometry pathGeometry = new PathGeometry(); figure.StartPoint = StartPoint; bezierPoints.Point1 = FirstControlPoint; bezierPoints.Point2 = EndControlPoint; bezierPoints.Point3 = EndPoint; figure.Segments.Add(bezierPoints); pathGeometry.Figures = new PathFigureCollection() { figure }; SplinePath.Data = pathGeometry; } }
/// <summary> /// Refresh the Series Part /// </summary> public override void Refresh() { if (AreaPath != null) { PathFigure figure = new PathFigure(); LineSegment startLineSegment = new LineSegment(); LineSegment areaEndLineSegment = new LineSegment(); LineSegment endLineSegment = new LineSegment(); PathGeometry pathGeometry = new PathGeometry(); figure.StartPoint = StartPoint; startLineSegment.Point = AreaStartPoint; endLineSegment.Point = EndPoint; areaEndLineSegment.Point = AreaEndPoint; figure.Segments.Add(startLineSegment); figure.Segments.Add(areaEndLineSegment); figure.Segments.Add(endLineSegment); pathGeometry.Figures = new PathFigureCollection() { figure }; AreaPath.Data = pathGeometry; } }
/// <summary> /// Adds an ellipse to the current path. /// </summary> public void AddEllipse(double x, double y, double width, double height) { #if CORE double w = width / 2; double h = height / 2; double xc = x + w; double yc = y + h; _corePath.MoveTo(x + w, y); _corePath.QuadrantArcTo(xc, yc, w, h, 1, true); _corePath.QuadrantArcTo(xc, yc, w, h, 4, true); _corePath.QuadrantArcTo(xc, yc, w, h, 3, true); _corePath.QuadrantArcTo(xc, yc, w, h, 2, true); _corePath.CloseSubpath(); #endif #if GDI try { Lock.EnterGdiPlus(); _gdipPath.AddEllipse((float)x, (float)y, (float)width, (float)height); } finally { Lock.ExitGdiPlus(); } #endif #if WPF || NETFX_CORE #if !SILVERLIGHT && !NETFX_CORE _pathGeometry.AddGeometry(new EllipseGeometry(new Rect(x, y, width, height))); #else var figure = new PathFigure(); figure.StartPoint = new SysPoint(x, y + height / 2); var segment = new ArcSegment { Point = new SysPoint(x + width, y + height / 2), Size = new SysSize(width / 2, height / 2), IsLargeArc = true, RotationAngle = 180, SweepDirection = SweepDirection.Clockwise, }; figure.Segments.Add(segment); segment = new ArcSegment { Point = figure.StartPoint, Size = new SysSize(width / 2, height / 2), IsLargeArc = true, RotationAngle = 180, SweepDirection = SweepDirection.Clockwise, }; figure.Segments.Add(segment); _pathGeometry.Figures.Add(figure); #endif // StartFigure() isn't needed because AddGeometry() implicitly starts a new figure, // but CloseFigure() is needed for the next adding not to continue this figure. CloseFigure(); #endif }
/// <summary> /// Render callback. /// </summary> protected override void OnRender(DrawingContext drawingContext) { CornerRadius cornerRadius = CornerRadius; Rect shadowBounds = new Rect(new Point(ShadowDepth, ShadowDepth), new Size(RenderSize.Width, RenderSize.Height)); Color color = Color; if (shadowBounds.Width > 0 && shadowBounds.Height > 0 && color.A > 0) { // The shadow is drawn with a dark center the size of the shadow bounds // deflated by shadow depth on each side. double centerWidth = shadowBounds.Right - shadowBounds.Left - 2 * ShadowDepth; double centerHeight = shadowBounds.Bottom - shadowBounds.Top - 2 * ShadowDepth; // Clamp corner radii to be less than 1/2 the side of the inner shadow bounds double maxRadius = Math.Min(centerWidth * 0.5, centerHeight * 0.5); cornerRadius.TopLeft = Math.Min(cornerRadius.TopLeft, maxRadius); cornerRadius.TopRight = Math.Min(cornerRadius.TopRight, maxRadius); cornerRadius.BottomLeft = Math.Min(cornerRadius.BottomLeft, maxRadius); cornerRadius.BottomRight = Math.Min(cornerRadius.BottomRight, maxRadius); // Get the brushes for the 9 regions Brush[] brushes = GetBrushes(color, cornerRadius); // Snap grid to device pixels double centerTop = shadowBounds.Top + ShadowDepth; double centerLeft = shadowBounds.Left + ShadowDepth; double centerRight = shadowBounds.Right - ShadowDepth; double centerBottom = shadowBounds.Bottom - ShadowDepth; // Because of different corner radii there are 6 potential x (or y) lines to snap to double[] guidelineSetX = new double[] { centerLeft, centerLeft + cornerRadius.TopLeft, centerRight - cornerRadius.TopRight, centerLeft + cornerRadius.BottomLeft, centerRight - cornerRadius.BottomRight, centerRight }; double[] guidelineSetY = new double[] { centerTop, centerTop + cornerRadius.TopLeft, centerTop + cornerRadius.TopRight, centerBottom - cornerRadius.BottomLeft, centerBottom - cornerRadius.BottomRight, centerBottom }; drawingContext.PushGuidelineSet(new GuidelineSet(guidelineSetX, guidelineSetY)); // The corner rectangles are drawn drawn ShadowDepth pixels bigger to // account for the blur cornerRadius.TopLeft = cornerRadius.TopLeft + ShadowDepth; cornerRadius.TopRight = cornerRadius.TopRight + ShadowDepth; cornerRadius.BottomLeft = cornerRadius.BottomLeft + ShadowDepth; cornerRadius.BottomRight = cornerRadius.BottomRight + ShadowDepth; // Draw Top row Rect topLeft = new Rect(shadowBounds.Left, shadowBounds.Top, cornerRadius.TopLeft, cornerRadius.TopLeft); drawingContext.DrawRectangle(brushes[TopLeft], null, topLeft); double topWidth = guidelineSetX[2] - guidelineSetX[1]; if (topWidth > 0) { Rect top = new Rect(guidelineSetX[1], shadowBounds.Top, topWidth, ShadowDepth); drawingContext.DrawRectangle(brushes[Top], null, top); } Rect topRight = new Rect(guidelineSetX[2], shadowBounds.Top, cornerRadius.TopRight, cornerRadius.TopRight); drawingContext.DrawRectangle(brushes[TopRight], null, topRight); // Middle row double leftHeight = guidelineSetY[3] - guidelineSetY[1]; if (leftHeight > 0) { Rect left = new Rect(shadowBounds.Left, guidelineSetY[1], ShadowDepth, leftHeight); drawingContext.DrawRectangle(brushes[Left], null, left); } double rightHeight = guidelineSetY[4] - guidelineSetY[2]; if (rightHeight > 0) { Rect right = new Rect(guidelineSetX[5], guidelineSetY[2], ShadowDepth, rightHeight); drawingContext.DrawRectangle(brushes[Right], null, right); } // Bottom row Rect bottomLeft = new Rect(shadowBounds.Left, guidelineSetY[3], cornerRadius.BottomLeft, cornerRadius.BottomLeft); drawingContext.DrawRectangle(brushes[BottomLeft], null, bottomLeft); double bottomWidth = guidelineSetX[4] - guidelineSetX[3]; if (bottomWidth > 0) { Rect bottom = new Rect(guidelineSetX[3], guidelineSetY[5], bottomWidth, ShadowDepth); drawingContext.DrawRectangle(brushes[Bottom], null, bottom); } Rect bottomRight = new Rect(guidelineSetX[4], guidelineSetY[4], cornerRadius.BottomRight, cornerRadius.BottomRight); drawingContext.DrawRectangle(brushes[BottomRight], null, bottomRight); // Fill Center // Because the heights of the top/bottom rects and widths of the left/right rects are fixed // and the corner rects are drawn with the size of the corner, the center // may not be a square. In this case, create a path to fill the area // When the target object's corner radius is 0, only need to draw one rect if (cornerRadius.TopLeft == ShadowDepth && cornerRadius.TopLeft == cornerRadius.TopRight && cornerRadius.TopLeft == cornerRadius.BottomLeft && cornerRadius.TopLeft == cornerRadius.BottomRight) { // All corners of target are 0, render one large rectangle Rect center = new Rect(guidelineSetX[0], guidelineSetY[0], centerWidth, centerHeight); drawingContext.DrawRectangle(brushes[Center], null, center); } else { // If the corner radius is TL=2, TR=1, BL=0, BR=2 the following shows the shape that needs to be created. // _________________ // | |_ // _ _| | // | | // | _ _| // | | // |___________________| // The missing corners of the shape are filled with the radial gradients drawn above // Define shape counter clockwise PathFigure figure = new PathFigure(); if (cornerRadius.TopLeft > ShadowDepth) { figure.StartPoint = new Point(guidelineSetX[1], guidelineSetY[0]); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[1], guidelineSetY[1]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[0], guidelineSetY[1]), true)); } else { figure.StartPoint = new Point(guidelineSetX[0], guidelineSetY[0]); } if (cornerRadius.BottomLeft > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[0], guidelineSetY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[3], guidelineSetY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[3], guidelineSetY[5]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[0], guidelineSetY[5]), true)); } if (cornerRadius.BottomRight > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[4], guidelineSetY[5]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[4], guidelineSetY[4]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[4]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[5]), true)); } if (cornerRadius.TopRight > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[2], guidelineSetY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[2], guidelineSetY[0]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[0]), true)); } figure.IsClosed = true; figure.Freeze(); PathGeometry geometry = new PathGeometry(); geometry.Figures.Add(figure); geometry.Freeze(); drawingContext.DrawGeometry(brushes[Center], null, geometry); } drawingContext.Pop(); } }
/// <summary> /// Starts a new figure without closing the current figure. /// </summary> public void StartFigure() { #if CORE // TODO: ??? #endif #if GDI try { Lock.EnterGdiPlus(); _gdipPath.StartFigure(); } finally { Lock.ExitGdiPlus(); } #endif #if WPF || NETFX_CORE PathFigure figure = CurrentPathFigure; if (figure.Segments.Count != 0) { figure = new PathFigure(); _pathGeometry.Figures.Add(figure); } #endif }
public void MatrixAnimationUsingPathDoesRotateWithTangentExample() { // Create a NameScope for the page so that // we can use Storyboards. NameScope.SetNameScope(MainGrid, new NameScope()); // Create a button. Map.MapBlock aButton = new Map.MapBlock(); aButton.LeftSideVisable = true; aButton.RightSideVisable = true; // Create a MatrixTransform. This transform // will be used to move the button. MatrixTransform buttonMatrixTransform = new MatrixTransform(); aButton.RenderTransform = buttonMatrixTransform; // Register the transform's name with the page // so that it can be targeted by a Storyboard. MainGrid.RegisterName("ButtonMatrixTransform", buttonMatrixTransform); // Create a Canvas to contain the button // and add it to the page. // Although this example uses a Canvas, // any type of panel will work. Canvas mainPanel = new Canvas(); mainPanel.Width = 400; mainPanel.Height = 400; mainPanel.Children.Add(aButton); MainGrid.Children.Add(mainPanel); // Create the animation path. PathGeometry animationPath = new PathGeometry(); PathFigure pFigure = new PathFigure(); pFigure.StartPoint = new Point(10, 100); PolyBezierSegment pBezierSegment = new PolyBezierSegment(); pBezierSegment.Points.Add(new Point(35, 0)); pBezierSegment.Points.Add(new Point(135, 0)); pBezierSegment.Points.Add(new Point(160, 100)); pBezierSegment.Points.Add(new Point(180, 190)); pBezierSegment.Points.Add(new Point(285, 200)); pBezierSegment.Points.Add(new Point(310, 100)); pFigure.Segments.Add(pBezierSegment); animationPath.Figures.Add(pFigure); // Freeze the PathGeometry for performance benefits. animationPath.Freeze(); // Create a MatrixAnimationUsingPath to move the // button along the path by animating // its MatrixTransform. MatrixAnimationUsingPath matrixAnimation = new MatrixAnimationUsingPath(); matrixAnimation.PathGeometry = animationPath; matrixAnimation.Duration = TimeSpan.FromSeconds(5); matrixAnimation.RepeatBehavior = RepeatBehavior.Forever; // Set the animation's DoesRotateWithTangent property // to true so that rotates the rectangle in addition // to moving it. matrixAnimation.DoesRotateWithTangent = true; // Set the animation to target the Matrix property // of the MatrixTransform named "ButtonMatrixTransform". Storyboard.SetTargetName(matrixAnimation, "ButtonMatrixTransform"); Storyboard.SetTargetProperty(matrixAnimation, new PropertyPath(MatrixTransform.MatrixProperty)); // Create a Storyboard to contain and apply the animation. Storyboard pathAnimationStoryboard = new Storyboard(); pathAnimationStoryboard.Children.Add(matrixAnimation); // Start the storyboard when the button is loaded. aButton.Loaded += delegate(object sender, RoutedEventArgs e) { // Start the storyboard. pathAnimationStoryboard.Begin(MainGrid); }; }
/// <summary> /// Draws a collection of polygons, where all polygons have the same stroke and fill. /// This performs better than calling DrawPolygon multiple times. /// </summary> /// <param name="polygons">The polygons.</param> /// <param name="fill">The fill color.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The stroke thickness.</param> /// <param name="dashArray">The dash array.</param> /// <param name="lineJoin">The line join type.</param> /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param> public void DrawPolygons( IList<IList<ScreenPoint>> polygons, OxyColor fill, OxyColor stroke, double thickness, double[] dashArray, LineJoin lineJoin, bool aliased) { var path = new Path(); this.SetStroke(path, stroke, thickness, lineJoin, dashArray, aliased); if (fill.IsVisible()) { path.Fill = this.GetCachedBrush(fill); } var pg = new PathGeometry { FillRule = FillRule.Nonzero }; foreach (var polygon in polygons) { var figure = new PathFigure { IsClosed = true }; bool first = true; foreach (var p in polygon) { if (first) { figure.StartPoint = p.ToPoint(aliased); first = false; } else { figure.Segments.Add(new LineSegment { Point = p.ToPoint(aliased) }); } } pg.Figures.Add(figure); } path.Data = pg; this.Add(path); }
private void Run_Click(object sender, RoutedEventArgs e) { var VMCountriesPartStyle = "VM_CountriesPartStyle"; var binding = new Binding(VMCountriesPartStyle) { Mode = BindingMode.OneWay }; this.SetBinding(CountriesPartStyleProperty, binding); float pieWidth = 250, pieHeight = 250, centerX = pieWidth / 2, centerY = pieHeight / 2, radius = pieWidth / 2; mainCanvas.Width = pieWidth; mainCanvas.Height = pieHeight; Categories = new List <Category>(); List <SolidColorBrush> colors = new List <SolidColorBrush> { new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80bfff")), // blue new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ff99cc")), // pink new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ffcc99")), // orenge new SolidColorBrush((Color)ColorConverter.ConvertFromString("#66ff66")), // green new SolidColorBrush((Color)ColorConverter.ConvertFromString("#d9b3ff")), // perpul }; int i = 0; foreach (KeyValuePair <string, int> entry in CountriesPartStyle) { Category category = new Category { Title = entry.Key, Percentage = entry.Value, ColorBrush = colors[i], }; Categories.Add(category); i++; // Check witch country is the country with the biggest Percentage. if (entry.Value > maxPart) { maxPart = entry.Value; contryResult = entry.Key; color = colors[i - 1].ToString(); } } detailsItemsControl.ItemsSource = Categories; // Draw pie float angle = 0, prevAngle = 0; foreach (var category in Categories) { double line1X = (radius * Math.Cos(angle * Math.PI / 180)) + centerX; double line1Y = (radius * Math.Sin(angle * Math.PI / 180)) + centerY; angle = category.Percentage * (float)360 / 100 + prevAngle; Debug.WriteLine(angle); double arcX = (radius * Math.Cos(angle * Math.PI / 180)) + centerX; double arcY = (radius * Math.Sin(angle * Math.PI / 180)) + centerY; var line1Segment = new LineSegment(new Point(line1X, line1Y), false); double arcWidth = radius, arcHeight = radius; bool isLargeArc = category.Percentage > 50; var arcSegment = new ArcSegment() { Size = new Size(arcWidth, arcHeight), Point = new Point(arcX, arcY), SweepDirection = SweepDirection.Clockwise, IsLargeArc = isLargeArc, }; var line2Segment = new LineSegment(new Point(centerX, centerY), false); var pathFigure = new PathFigure( new Point(centerX, centerY), new List <PathSegment>() { line1Segment, arcSegment, line2Segment, }, true); var pathFigures = new List <PathFigure>() { pathFigure, }; var pathGeometry = new PathGeometry(pathFigures); var path = new Path() { Fill = category.ColorBrush, Data = pathGeometry, }; mainCanvas.Children.Add(path); prevAngle = angle; // Draw outlines var outline1 = new Line() { X1 = centerX, Y1 = centerY, X2 = line1Segment.Point.X, Y2 = line1Segment.Point.Y, Stroke = Brushes.White, StrokeThickness = 5, }; var outline2 = new Line() { X1 = centerX, Y1 = centerY, X2 = arcSegment.Point.X, Y2 = arcSegment.Point.Y, Stroke = Brushes.White, StrokeThickness = 5, }; mainCanvas.Children.Add(outline1); mainCanvas.Children.Add(outline2); } // Update result view. resultsView.Visibility = Visibility.Visible; resultVal.Text = contryResult; resultVal.Background = new BrushConverter().ConvertFromString(color) as SolidColorBrush; maxPart = 0; }
private void DrawBorder(DrawingContext dc, ref Rect bounds) { if (bounds.Width >= 5.0 && bounds.Height >= 5.0) { Brush brush = this.BorderBrush; Pen pen = null; if (brush != null) { if (ImageButtonChromeControl._commonBorderPen == null) { lock (ImageButtonChromeControl._resourceAccess) { if (ImageButtonChromeControl._commonBorderPen == null) { if (!brush.IsFrozen && brush.CanFreeze) { brush = brush.Clone(); brush.Freeze(); } Pen pen2 = new Pen(brush, 1.0); if (pen2.CanFreeze) { pen2.Freeze(); ImageButtonChromeControl._commonBorderPen = pen2; } } } } if (ImageButtonChromeControl._commonBorderPen != null && brush == ImageButtonChromeControl._commonBorderPen.Brush) { pen = ImageButtonChromeControl._commonBorderPen; } else { if (!brush.IsFrozen && brush.CanFreeze) { brush = brush.Clone(); brush.Freeze(); } pen = new Pen(brush, 1.0); if (pen.CanFreeze) { pen.Freeze(); } } } Pen borderOverlayPen = this.BorderOverlayPen; if (pen != null || borderOverlayPen != null) { if (this.RoundCorners) { Rect rectangle = new Rect(bounds.Left + 0.5, bounds.Top + 0.5, bounds.Width - 1.0, bounds.Height - 1.0); if (base.IsEnabled && pen != null) { dc.DrawRoundedRectangle(null, pen, rectangle, 2.75, 2.75); } if (borderOverlayPen != null) { dc.DrawRoundedRectangle(null, borderOverlayPen, rectangle, 2.75, 2.75); return; } } else { PathFigure pathFigure = new PathFigure(); pathFigure.StartPoint = new Point(0.5, 0.5); pathFigure.Segments.Add(new LineSegment(new Point(0.5, bounds.Bottom - 0.5), true)); pathFigure.Segments.Add(new LineSegment(new Point(bounds.Right - 2.5, bounds.Bottom - 0.5), true)); pathFigure.Segments.Add(new ArcSegment(new Point(bounds.Right - 0.5, bounds.Bottom - 2.5), new Size(2.0, 2.0), 0.0, false, SweepDirection.Counterclockwise, true)); pathFigure.Segments.Add(new LineSegment(new Point(bounds.Right - 0.5, bounds.Top + 2.5), true)); pathFigure.Segments.Add(new ArcSegment(new Point(bounds.Right - 2.5, bounds.Top + 0.5), new Size(2.0, 2.0), 0.0, false, SweepDirection.Counterclockwise, true)); pathFigure.IsClosed = true; PathGeometry pathGeometry = new PathGeometry(); pathGeometry.Figures.Add(pathFigure); if (base.IsEnabled && pen != null) { dc.DrawGeometry(null, pen, pathGeometry); } if (borderOverlayPen != null) { dc.DrawGeometry(null, borderOverlayPen, pathGeometry); } } } } }
protected override void OnViewportChanged(ViewportChangedEventArgs e) { var projection = ParentMap.MapProjection; if (projection.IsNormalCylindrical) { if (path == null) { path = new Path { Data = new PathGeometry() }; path.SetBinding(Shape.StrokeProperty, GetBinding(StrokeProperty, nameof(Stroke))); path.SetBinding(Shape.StrokeThicknessProperty, GetBinding(StrokeThicknessProperty, nameof(StrokeThickness))); path.SetBinding(Shape.StrokeDashArrayProperty, GetBinding(StrokeDashArrayProperty, nameof(StrokeDashArray))); path.SetBinding(Shape.StrokeDashOffsetProperty, GetBinding(StrokeDashOffsetProperty, nameof(StrokeDashOffset))); path.SetBinding(Shape.StrokeDashCapProperty, GetBinding(StrokeDashCapProperty, nameof(StrokeDashCap))); Children.Add(path); } var bounds = projection.ViewportRectToBoundingBox(new Rect(0d, 0d, ParentMap.RenderSize.Width, ParentMap.RenderSize.Height)); var lineDistance = GetLineDistance(); var labelStart = new Location( Math.Ceiling(bounds.South / lineDistance) * lineDistance, Math.Ceiling(bounds.West / lineDistance) * lineDistance); var labelEnd = new Location( Math.Floor(bounds.North / lineDistance) * lineDistance, Math.Floor(bounds.East / lineDistance) * lineDistance); var lineStart = new Location( Math.Min(Math.Max(labelStart.Latitude - lineDistance, -projection.MaxLatitude), projection.MaxLatitude), labelStart.Longitude - lineDistance); var lineEnd = new Location( Math.Min(Math.Max(labelEnd.Latitude + lineDistance, -projection.MaxLatitude), projection.MaxLatitude), labelEnd.Longitude + lineDistance); var geometry = (PathGeometry)path.Data; geometry.Figures.Clear(); for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance) { var figure = new PathFigure { StartPoint = projection.LocationToViewportPoint(new Location(lat, lineStart.Longitude)), IsClosed = false, IsFilled = false }; figure.Segments.Add(new LineSegment { Point = projection.LocationToViewportPoint(new Location(lat, lineEnd.Longitude)) }); geometry.Figures.Add(figure); } for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance) { var figure = new PathFigure { StartPoint = projection.LocationToViewportPoint(new Location(lineStart.Latitude, lon)), IsClosed = false, IsFilled = false }; figure.Segments.Add(new LineSegment { Point = projection.LocationToViewportPoint(new Location(lineEnd.Latitude, lon)) }); geometry.Figures.Add(figure); } var labelFormat = GetLabelFormat(lineDistance); var childIndex = 1; // 0 for Path for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance) { for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance) { TextBlock label; if (childIndex < Children.Count) { label = (TextBlock)Children[childIndex]; } else { var renderTransform = new TransformGroup(); renderTransform.Children.Add(new TranslateTransform()); renderTransform.Children.Add(ParentMap.RotateTransform); renderTransform.Children.Add(new TranslateTransform()); label = new TextBlock { RenderTransform = renderTransform }; if (FontFamily != null) { label.SetBinding(TextBlock.FontFamilyProperty, GetBinding(FontFamilyProperty, nameof(FontFamily))); } label.SetBinding(TextBlock.FontSizeProperty, GetBinding(FontSizeProperty, nameof(FontSize))); label.SetBinding(TextBlock.FontStyleProperty, GetBinding(FontStyleProperty, nameof(FontStyle))); label.SetBinding(TextBlock.FontStretchProperty, GetBinding(FontStretchProperty, nameof(FontStretch))); label.SetBinding(TextBlock.FontWeightProperty, GetBinding(FontWeightProperty, nameof(FontWeight))); label.SetBinding(TextBlock.ForegroundProperty, GetBinding(ForegroundProperty, nameof(Foreground))); Children.Add(label); } childIndex++; label.Text = GetLabelText(lat, labelFormat, "NS") + "\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW"); label.Tag = new Location(lat, lon); label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0]; translateTransform.X = StrokeThickness / 2d + 2d; translateTransform.Y = -label.DesiredSize.Height / 2d; } while (Children.Count > childIndex) { Children.RemoveAt(Children.Count - 1); } } // don't use MapPanel.Location because labels may be at more than 180° distance from map center for (int i = 1; i < Children.Count; i++) { var label = (TextBlock)Children[i]; var location = (Location)label.Tag; var viewportTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[2]; var viewportPosition = projection.LocationToViewportPoint(location); viewportTransform.X = viewportPosition.X; viewportTransform.Y = viewportPosition.Y; } } else if (path != null) { path = null; Children.Clear(); } base.OnViewportChanged(e); }
private static Geometry ProcessPathData(List<PathInfo> pis) { PathGeometry geometry = new PathGeometry(); PathFigure figure = null; foreach (var pi in pis) { switch (pi.segmentType) { case SegmentType.Move: figure = new PathFigure() { StartPoint = pi.point }; geometry.Figures.Add(figure); break; case SegmentType.Line: figure.Segments.Add(new LineSegment() { Point = pi.point }); break; case SegmentType.Arc: figure.Segments.Add(new ArcSegment() { Size = new Size(pi.size.X, pi.size.Y), IsLargeArc = pi.isLargeArc, Point = pi.point, RotationAngle = pi.angle, SweepDirection = pi.isSweepDirectionClockwise ? SweepDirection.Clockwise : SweepDirection.Counterclockwise }); break; case SegmentType.Close: figure.IsClosed = true; break; default: break; } } return geometry; }
Visual CreateQuadraticBezierSegments() { DrawingContext dc; DrawingVisual dv = PrepareDrawingVisual(out dc); Point startPoint = new Point(20, 120); Point[] points = { new Point(30, 20), new Point(150, 130), new Point(200, 20), new Point(215, 60) }; PathGeometry path; PathFigure figure; Brush brush = Brushes.DarkOrange; Pen pen = new Pen(Brushes.DarkBlue, 3); BeginBox(dc, 1, BoxOptions.Tile, "stroke"); path = new PathGeometry(); path.Figures.Add(figure = new PathFigure()); figure.StartPoint = startPoint; figure.Segments.Add(new PolyQuadraticBezierSegment(points, true)); dc.DrawGeometry(null, pen, path); EndBox(dc); BeginBox(dc, 2, BoxOptions.Tile, "stroke, figure closed"); path = new PathGeometry(); path.Figures.Add(figure = new PathFigure()); figure.StartPoint = startPoint; figure.IsClosed = true; figure.Segments.Add(new PolyQuadraticBezierSegment(points, true)); dc.DrawGeometry(null, pen, path); EndBox(dc); BeginBox(dc, 3, BoxOptions.Tile, "fill"); path = new PathGeometry(); path.Figures.Add(figure = new PathFigure()); figure.StartPoint = startPoint; figure.Segments.Add(new PolyQuadraticBezierSegment(points, true)); dc.DrawGeometry(brush, null, path); EndBox(dc); BeginBox(dc, 4, BoxOptions.Tile, "fill, figure closed"); path = new PathGeometry(); path.Figures.Add(figure = new PathFigure()); figure.StartPoint = startPoint; figure.IsClosed = true; figure.Segments.Add(new PolyQuadraticBezierSegment(points, true)); dc.DrawGeometry(brush, null, path); EndBox(dc); BeginBox(dc, 5, BoxOptions.Tile, "fill & stroke"); path = new PathGeometry(); path.Figures.Add(figure = new PathFigure()); figure.StartPoint = startPoint; figure.Segments.Add(new PolyQuadraticBezierSegment(points, true)); dc.DrawGeometry(brush, pen, path); EndBox(dc); BeginBox(dc, 6, BoxOptions.Tile, "fill & stroke, figure closed"); path = new PathGeometry(); path.Figures.Add(figure = new PathFigure()); figure.StartPoint = startPoint; figure.IsClosed = true; figure.Segments.Add(new PolyQuadraticBezierSegment(points, true)); dc.DrawGeometry(brush, pen, path); EndBox(dc); //BeginBox(dc, 7); //EndBox(dc); //BeginBox(dc, 8); //EndBox(dc); dc.Close(); return(dv); }
public void DrawArc(float cx, float cy, float radius, float startAngle, float endAngle, float w) { var s = GetNextShape(TypeId.Arc); var e = s.Element as Path; if (e.Data == null || s.X != cx || s.Y != cy || s.Radius != radius || s.Width != startAngle || s.Height != endAngle) { s.X = cx; s.Y = cy; s.Radius = radius; s.Width = startAngle; s.Height = endAngle; var fig = new PathFigure(); var sa = -startAngle; var ea = -endAngle; fig.StartPoint = new Point( cx + radius * Math.Cos(sa), cy + radius * Math.Sin(sa)); fig.Segments.Add(new ArcSegment() { Point = new Point( cx + radius * Math.Cos(ea), cy + radius * Math.Sin(ea)), Size = new Size(radius, radius), SweepDirection = SweepDirection.Counterclockwise, }); var geo = new PathGeometry(); geo.Figures.Add(fig); e.Data = geo; } if (s.Thickness != w) { s.Thickness = w; e.StrokeThickness = w; } if (s.Color != _currentColor || s.DrawOp != DrawOp.Draw) { s.Color = _currentColor; s.DrawOp = DrawOp.Draw; e.Stroke = _currentColor.GetBrush(); e.Fill = null; } }
protected override void OnViewportChanged() { var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), ParentMap.RenderSize)); var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); var minSpacing = MinLineSpacing * 360d / (Math.Pow(2d, ParentMap.ZoomLevel) * 256d); var spacing = LineSpacings[LineSpacings.Length - 1]; if (spacing >= minSpacing) { spacing = LineSpacings.FirstOrDefault(s => s >= minSpacing); } var labelStart = new Location( Math.Ceiling(start.Latitude / spacing) * spacing, Math.Ceiling(start.Longitude / spacing) * spacing); var labelEnd = new Location( Math.Floor(end.Latitude / spacing) * spacing, Math.Floor(end.Longitude / spacing) * spacing); var lineStart = new Location( Math.Min(Math.Max(labelStart.Latitude - spacing, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude), labelStart.Longitude - spacing); var lineEnd = new Location( Math.Min(Math.Max(labelEnd.Latitude + spacing, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude), labelEnd.Longitude + spacing); if (!lineStart.Equals(graticuleStart) || !lineEnd.Equals(graticuleEnd)) { graticuleStart = lineStart; graticuleEnd = lineEnd; var geometry = (PathGeometry)path.Data; geometry.Figures.Clear(); geometry.Transform = ParentMap.ViewportTransform; for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing) { var figure = new PathFigure { StartPoint = ParentMap.MapTransform.Transform(new Location(lat, lineStart.Longitude)), IsClosed = false, IsFilled = false }; figure.Segments.Add(new LineSegment { Point = ParentMap.MapTransform.Transform(new Location(lat, lineEnd.Longitude)), }); geometry.Figures.Add(figure); } for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing) { var figure = new PathFigure { StartPoint = ParentMap.MapTransform.Transform(new Location(lineStart.Latitude, lon)), IsClosed = false, IsFilled = false }; figure.Segments.Add(new LineSegment { Point = ParentMap.MapTransform.Transform(new Location(lineEnd.Latitude, lon)), }); geometry.Figures.Add(figure); } var childIndex = 1; // 0 for Path var format = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°"; for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing) { for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing) { TextBlock label; if (childIndex < Children.Count) { label = (TextBlock)Children[childIndex]; } else { var renderTransform = new TransformGroup(); renderTransform.Children.Add(new TranslateTransform()); renderTransform.Children.Add(ParentMap.RotateTransform); renderTransform.Children.Add(new TranslateTransform()); label = new TextBlock { RenderTransform = renderTransform }; label.SetBinding(TextBlock.ForegroundProperty, new Binding { Source = this, Path = new PropertyPath("Foreground") }); Children.Add(label); } childIndex++; if (FontFamily != null) { label.FontFamily = FontFamily; } label.FontSize = FontSize; label.FontStyle = FontStyle; label.FontStretch = FontStretch; label.FontWeight = FontWeight; label.Text = string.Format("{0}\n{1}", CoordinateString(lat, format, "NS"), CoordinateString(Location.NormalizeLongitude(lon), format, "EW")); label.Tag = new Location(lat, lon); label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0]; translateTransform.X = StrokeThickness / 2d + 2d; translateTransform.Y = -label.DesiredSize.Height / 2d; } } while (Children.Count > childIndex) { Children.RemoveAt(Children.Count - 1); } } // don't use MapPanel.Location because labels may be at more than 180° distance from map center for (int i = 1; i < Children.Count; i++) { var label = (TextBlock)Children[i]; var location = (Location)label.Tag; var viewportTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[2]; var viewportPosition = ParentMap.LocationToViewportPoint(location); viewportTransform.X = viewportPosition.X; viewportTransform.Y = viewportPosition.Y; } base.OnViewportChanged(); }
ShapeData DoArc(float cx, float cy, float radius, float startAngle, float endAngle) { var s = GetNextShape (TypeId.Arc); var e = s.Element as Path; if (e.Data == null || s.X != cx || s.Y != cy || s.Radius != radius || s.Width != startAngle || s.Height != endAngle) { s.X = cx; s.Y = cy; s.Radius = radius; s.Width = startAngle; s.Height = endAngle; var fig = new PathFigure(); var sa = -startAngle; var ea = -endAngle; fig.StartPoint = new Point( cx + radius * Math.Cos(sa), cy + radius * Math.Sin(sa)); fig.Segments.Add(new ArcSegment() { Point = new Point( cx + radius * Math.Cos(ea), cy + radius * Math.Sin(ea)), Size = new Size(radius, radius), SweepDirection = SweepDirection.Counterclockwise, }); var geo = new PathGeometry(); geo.Figures.Add(fig); e.Data = geo; } return s; }
/// <summary> /// Creates a path geometry from a polygon. /// </summary> public static PathGeometry CreatePolygonGeometry(SysPoint[] points, XFillMode fillMode, bool closed) { PolyLineSegment seg = new PolyLineSegment(); int count = points.Length; // For correct drawing the start point of the segment must not be the same as the first point. for (int idx = 1; idx < count; idx++) seg.Points.Add(new SysPoint(points[idx].X, points[idx].Y)); #if !SILVERLIGHT && !NETFX_CORE seg.IsStroked = true; #endif PathFigure fig = new PathFigure(); fig.StartPoint = new SysPoint(points[0].X, points[0].Y); fig.Segments.Add(seg); fig.IsClosed = closed; PathGeometry geo = new PathGeometry(); geo.FillRule = fillMode == XFillMode.Winding ? FillRule.Nonzero : FillRule.EvenOdd; geo.Figures.Add(fig); return geo; }
public PathGeometry CloneDeep(PathGeometry pathGeometry) { var newPathGeometry = new PathGeometry(); foreach (var figure in pathGeometry.Figures) { var newFigure = new PathFigure(); newFigure.StartPoint = figure.StartPoint; // Even figures have to be deep cloned. Assigning them directly will result in // an InvalidOperationException being thrown with the message "Element is already the child of another element." foreach (var segment in figure.Segments) { // I only impemented cloning the abstract PathSegments to one implementation, // the PolyLineSegment class. If your paths use other kinds of segments, you'll need // to implement that kind of coding yourself. var segmentAsPolyLineSegment = segment as PolyLineSegment; if (segmentAsPolyLineSegment != null) { var newSegment = new PolyLineSegment(); foreach (var point in segmentAsPolyLineSegment.Points) { newSegment.Points.Add(point); } newFigure.Segments.Add(newSegment); } var segmentAsLineSegment = segment as LineSegment; if (segmentAsLineSegment != null) { var newSegment = new LineSegment(); newSegment.Point = segmentAsLineSegment.Point; newFigure.Segments.Add(newSegment); } var segmentAsArcSegment = segment as ArcSegment; if (segmentAsArcSegment != null) { var newSegment = new ArcSegment(); newSegment.Point = segmentAsArcSegment.Point; newSegment.SweepDirection = segmentAsArcSegment.SweepDirection; newSegment.RotationAngle = segmentAsArcSegment.RotationAngle; newSegment.IsLargeArc = segmentAsArcSegment.IsLargeArc; newSegment.Size = segmentAsArcSegment.Size; newFigure.Segments.Add(newSegment); } } newPathGeometry.Figures.Add(newFigure); } return newPathGeometry; }