private void GenerateMap(Point startPoint, PointCollection points) { map_DirtTexture = new BitmapImage(new Uri(@"Resources/Dirt texture.png", UriKind.Relative)); map_DirtBrush = new ImageBrush(map_DirtTexture); map_LinePointCollection = new PointCollection() { points.Last(), new Point(points.Last().X, 500), new Point(startPoint.X, 500), startPoint }; map_PolyLineSegment = new PolyLineSegment() { Points = map_LinePointCollection }; map_BezierPointCollection = points; map_PolyBezierSegment = new PolyBezierSegment() { Points = map_BezierPointCollection }; map_PathSegmentCollection = new PathSegmentCollection(); map_PathSegmentCollection.Add(map_PolyBezierSegment); map_PathSegmentCollection.Add(map_PolyLineSegment); map_PathFigure = new PathFigure() { StartPoint = startPoint, Segments = map_PathSegmentCollection }; map_PathFigureCollection = new PathFigureCollection(); map_PathFigureCollection.Add(map_PathFigure); map_PathGeometry = new PathGeometry() { Figures = map_PathFigureCollection }; map_Path = new Path() { Stroke = map_DirtBrush, Fill = map_DirtBrush, StrokeThickness = 2, Data = map_PathGeometry }; }
/// <summary> /// Works out the actual X/Y points for the each value within the /// data and draws the line graph. /// </summary> private void UpdateLineGraph() { // Only proceed if there are some actual values and there are enough values if (this.DataValues == null || this.DataValues.Count < 2 || container.ActualHeight == 0 || this.MaxValue <= this.MinValue) { GraphLine.Visibility = Visibility.Hidden; LastPointMarkerEllipse.Visibility = Visibility.Hidden; ScaleCurrentValue.Content = string.Empty; return; } int count = this.DataValues.Count; double max = Math.Max(this.Threshold, this.DataValues.Max()); this.MaxValue = Math.Max(DEFAULT_MAX, max); double scale = this.MaxValue - this.MinValue; double valuePerPoint = container.ActualHeight / scale; double constantOffset = container.ActualWidth / Math.Min(MAX_POINTS, count); double xOffSet = 0; // For each item work out what the actual X/Y should be _graphPoints.Clear(); int start = count > MAX_POINTS ? count - MAX_POINTS : 0; for (int i = start; i < count; i++) { double trueDiff = this.DataValues[i] - this.MinValue; double heightPx = trueDiff * valuePerPoint; double yValue = container.ActualHeight - heightPx; _graphPoints.Add(new Point(xOffSet, yValue)); xOffSet += constantOffset; } // Add Polygon Points GraphLine.Points = _graphPoints; // set LastPointMarkerEllipse Point lastPoint = _graphPoints.Last(); LastPointMarkerEllipse.SetValue(Canvas.LeftProperty, lastPoint.X - (LastPointMarkerEllipse.Width / 2.0)); LastPointMarkerEllipse.SetValue(Canvas.TopProperty, lastPoint.Y - (LastPointMarkerEllipse.Height / 2.0)); LastPointMarkerEllipse.Visibility = Visibility.Visible; // Set label ScaleCurrentValue.Content = this.DataValues.Last().ToString("N0"); ScaleCurrentValue.SetValue(Canvas.LeftProperty, lastPoint.X - (LastPointMarkerEllipse.Width * 2.0)); if (lastPoint.Y < (GraphLine.ActualHeight / 2.0)) { ScaleCurrentValue.SetValue(Canvas.TopProperty, lastPoint.Y + LastPointMarkerEllipse.Height); } else { ScaleCurrentValue.SetValue(Canvas.TopProperty, lastPoint.Y - (LastPointMarkerEllipse.Height * 3.0)); } // Got points now so show graph GraphLine.Visibility = Visibility.Visible; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { Point result = new Point(); PointCollection collection = value as PointCollection; if (collection != null && parameter != null && collection.Count > 0) { string converterParameter = parameter.ToString().ToUpper(); int index; if (int.TryParse(converterParameter, out index) && collection.Count < index) { result = collection[index]; } else { switch (converterParameter) { case FirstIndexer: result = collection.First(); break; case LastIndexer: result = collection.Last(); break; } } } return(result); }
/// <summary> /// Draws the line using the MaxPolylinesPerLine and MinPointsPerPolyline properties. /// </summary> /// <param name="points">The points.</param> /// <param name="strokeColor">The stroke color.</param> /// <param name="thickness">The thickness.</param> /// <param name="lineJoin">The line join.</param> /// <param name="dashArray">The dash array. Use <c>null</c> to get a solid line.</param> /// <param name="aliased"></param> /// <param name="isHitTestVisible"><c>true</c> if hit testing should be enabled, <c>false</c> otherwise.</param> /// <remarks>See <a href="https://oxyplot.codeplex.com/discussions/456679">discussion</a>.</remarks> private void DrawPolylineBalanced([NotNull] IList <Point> points, Color strokeColor, double thickness, PenLineJoin lineJoin, ICollection <double> dashArray, bool aliased, bool isHitTestVisible) { // balance the number of points per polyline and the number of polylines var numPointsPerPolyline = Math.Max(points.Count / MaxPolylinesPerLine, MinPointsPerPolyline); var polyline = Create <Polyline>(isHitTestVisible); SetStroke(polyline, strokeColor, thickness, lineJoin, dashArray, 0, aliased); var pointCollection = new PointCollection(numPointsPerPolyline); var pointCount = points.Count; double lineLength = 0; var dashPatternLength = dashArray?.Sum() ?? 0; var last = new Point(); for (var i = 0; i < pointCount; i++) { var current = aliased ? ToPixelAlignedPoint(points[i]) : points[i]; pointCollection.Add(current); // get line length if (dashArray != null) { if (i > 0) { var delta = current - last; var dist = Math.Sqrt((delta.X * delta.X) + (delta.Y * delta.Y)); lineLength += dist; } last = current; } // use multiple polylines with limited number of points to improve WPF performance if (pointCollection.Count >= numPointsPerPolyline) { polyline.Points = pointCollection; if (i < pointCount - 1) { // start a new polyline at last point so there is no gap (it is not necessary to use the % operator) var dashOffset = dashPatternLength > 0 ? lineLength / thickness : 0; polyline = Create <Polyline>(isHitTestVisible); SetStroke(polyline, strokeColor, thickness, lineJoin, dashArray, dashOffset, aliased); pointCollection = new PointCollection(numPointsPerPolyline) { pointCollection.Last() }; } } } if (pointCollection.Count > 1 || pointCount == 1) { polyline.Points = pointCollection; } }
/// <summary> /// Draws line connecting two points /// </summary> /// <param name="newPoint"></param> /// <returns>Line</returns> public Line DrawLine(Point newPoint) { if (newPoint != null) { Line newLine = new Line { X1 = points.Last().X, Y1 = points.Last().Y, X2 = newPoint.X, Y2 = newPoint.Y }; newLine.Stroke = Brushes.Black; this.MainCanvas.Children.Add(newLine); return(newLine); } else { throw new ArgumentException("Second point for a line was set to null"); } }
// Make a Path holding a series of Bezier curves. // The points parameter includes the points of the inscribing polygon private Path MakeBezierPath(Point[] points) { // Create a Path to hold the geometry. Path path = new Path(); // Add a PathGeometry. PathGeometry path_geometry = new PathGeometry(); path.Data = path_geometry; // Create a PathFigure. PathFigure path_figure = new PathFigure(); path_geometry.Figures.Add(path_figure); // Create a PathSegmentCollection. PathSegmentCollection path_segment_collection = new PathSegmentCollection(); path_figure.Segments = path_segment_collection; // Add the rest of the points to a PointCollection. PointCollection point_collection = new PointCollection(); for (int i = 0; i < points.Length; i++) { //polygon vertice as 2 controls for the curve var control_point = points[i]; point_collection.Add(control_point); point_collection.Add(control_point); //end point is the middle of next curve var endpoint = new Point( (points[i].X + points[(i + 1 + points.Length) % points.Length].X) / 2, (points[i].Y + points[(i + 1 + points.Length) % points.Length].Y) / 2); point_collection.Add(endpoint); } // Start at the first point. path_figure.StartPoint = point_collection.Last(); // Make a PolyBezierSegment from the points. PolyBezierSegment bezier_segment = new PolyBezierSegment { Points = point_collection }; // Add the PolyBezierSegment to othe segment collection. path_segment_collection.Add(bezier_segment); path.Stroke = Brushes.Orange; thePath = path; return(path); }
/// <summary> /// Works out the actual X/Y points for the each value within the /// ObservableCollection<GraphDataItem> property. /// </summary> private void ObtainPointsForValues() { //Only proceed if there are some actual values and there are enough values if (DataValues == null || container.ActualHeight == 0 || DataValues.Count < MIN_ITEMS_TO_PLOT) { GraphLine.Visibility = Visibility.Hidden; LastPointMarkerEllipse.Visibility = Visibility.Hidden; ScaleCurrentValue.Content = string.Empty; return; } else { #region Workout Points double scale = MaxValue - MinValue; double valuePerPoint = container.ActualHeight / scale; double constantOffset = container.ActualWidth / DataValues.Count; double xOffSet = 0; ///for each item seen work out what the actual X/Y should be ///based on a bit of Maths _graphPoints.Clear(); for (int i = 0; i < DataValues.Count; i++) { double trueDiff = DataValues[i] - MinValue; double heightPx = trueDiff * valuePerPoint; double yValue = container.ActualHeight - heightPx; _graphPoints.Add(new Point(xOffSet, yValue)); xOffSet += constantOffset; } Point lastPoint = _graphPoints.Last(); //set LastPointMarkerEllipse LastPointMarkerEllipse.SetValue(Canvas.LeftProperty, lastPoint.X - (LastPointMarkerEllipse.Width / 2)); LastPointMarkerEllipse.SetValue(Canvas.TopProperty, lastPoint.Y - (LastPointMarkerEllipse.Height / 2)); LastPointMarkerEllipse.Visibility = Visibility.Visible; #endregion #region Label Current Data Point ScaleCurrentValue.Content = this.DataValues.Last().ToString("N0"); ScaleCurrentValue.SetValue(Canvas.LeftProperty, lastPoint.X - (LastPointMarkerEllipse.Width * 2)); ScaleCurrentValue.SetValue(Canvas.TopProperty, lastPoint.Y - (LastPointMarkerEllipse.Height * 2)); #endregion //Add Polygon Points GraphLine.Points = _graphPoints; //Got points now so show graph GraphLine.Visibility = Visibility.Visible; } }
private void AddPointsStraight(Point point, PointCollection points) { if (points.Count == 0) { points.Add(StartPoint); } else { points.Add(points.Last()); } points.Add(point); points.Add(point); }
private int FindDodgePointsPath(List <Planet> planetList, PointCollection points, Point?origin, Point target, int direction, int planetList_i, bool savePoints) { bool pathCompleted = false; int counter = 0; int j = 0; int walkThroughNum = 0; bool startDrawing = false; Point originP = points.Last(); while (!pathCompleted) { if (planetList[planetList_i].DodgePoints[j] == origin) { startDrawing = false; } if (startDrawing) { if (savePoints) { points.Add(planetList[planetList_i].DodgePoints[j]); } counter++; } if (planetList[planetList_i].DodgePoints[j] == originP) { startDrawing = true; walkThroughNum++; } if (walkThroughNum == 2) { pathCompleted = true; } j += direction; if (j == Planet.borderPointCount && direction == 1) { j = 0; } else if (j == -1 && direction == -1) { j = Planet.borderPointCount - 1; } } return(counter); }
/// <summary> /// Draws the line using the MaxPolylinesPerLine and MinPointsPerPolyline properties. /// </summary> /// <param name="points">The points.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The thickness.</param> /// <param name="dashArray">The dash array. Use <c>null</c> to get a solid line.</param> /// <param name="lineJoin">The line join.</param> /// <param name="aliased">Render aliased if set to <c>true</c>.</param> /// <remarks>See <a href="https://oxyplot.codeplex.com/discussions/456679">discussion</a>.</remarks> private void DrawLineBalanced(IList <ScreenPoint> points, OxyColor stroke, double thickness, double[] dashArray, LineJoin lineJoin, bool aliased) { // balance the number of points per polyline and the number of polylines var numPointsPerPolyline = Math.Max(points.Count / MaxPolylinesPerLine, MinPointsPerPolyline); var polyline = this.CreateAndAdd <Polyline>(); this.SetStroke(polyline, stroke, thickness, lineJoin, dashArray, 0, aliased); var pc = new PointCollection(numPointsPerPolyline); var n = points.Count; double lineLength = 0; var dashPatternLength = (dashArray != null) ? dashArray.Sum() : 0; var last = new Point(); for (int i = 0; i < n; i++) { var p = aliased ? this.ToPixelAlignedPoint(points[i]) : this.ToPoint(points[i]); pc.Add(p); // alt. 1 if (dashArray != null) { if (i > 0) { var delta = p - last; var dist = Math.Sqrt((delta.X * delta.X) + (delta.Y * delta.Y)); lineLength += dist; } last = p; } // use multiple polylines with limited number of points to improve WPF performance if (pc.Count >= numPointsPerPolyline) { polyline.Points = pc; if (i < n - 1) { // alt.2 ////if (dashArray != null) ////{ //// lineLength += this.GetLength(polyline); ////} // start a new polyline at last point so there is no gap (it is not necessary to use the % operator) var dashOffset = dashPatternLength > 0 ? lineLength / thickness : 0; polyline = this.CreateAndAdd <Polyline>(); this.SetStroke(polyline, stroke, thickness, lineJoin, dashArray, dashOffset, aliased); pc = new PointCollection(numPointsPerPolyline) { pc.Last() }; } } } if (pc.Count > 1 || n == 1) { polyline.Points = pc; } }
/// <summary> /// 曲线绘制,并填充色 /// </summary> /// <param name="canvas"></param> /// <param name="colorBrush"></param> /// <param name="fillBrush">并填充色</param> /// <param name="startPoint"></param> /// <param name="points"></param> /// <returns></returns> public static Path DrawPolylineAndFill(this Canvas canvas, Color colorBrush, Brush fillBrush, Point startPoint, PointCollection points) { Path currPath = new Path(); if (!points.Any()) { return(currPath); } currPath.Stroke = Brushes.Black; var endpoint = new Point() { X = points.Last().X + 10, Y = startPoint.Y }; var newStartPoint = new Point() { X = startPoint.X, Y = startPoint.Y }; var maxX = points.Max(a => a.X); var maxY = points.Max(a => a.Y); GradientStopCollection gradientStops = new GradientStopCollection() { new GradientStop() { Color = Colors.LightSeaGreen, Offset = 1 }, new GradientStop() { Color = Colors.LightPink, Offset = 0.8 }, new GradientStop() { Color = Colors.Black, Offset = 0.2 } }; LinearGradientBrush linearGradientBrush = new LinearGradientBrush(gradientStops, 90); PathFigure pathFigureArrow = new PathFigure(); pathFigureArrow.IsClosed = true; pathFigureArrow.StartPoint = newStartPoint; foreach (var item in points) { var toadd = new Point(item.X + 10, item.Y + 5); pathFigureArrow.Segments.Add(new LineSegment(toadd, false)); } pathFigureArrow.Segments.Add(new LineSegment(endpoint, false)); PathGeometry pathGeometryArrow = new PathGeometry(); pathGeometryArrow.Figures.Add(pathFigureArrow); currPath.Data = pathGeometryArrow; currPath.Fill = fillBrush == null ? linearGradientBrush : fillBrush; Canvas.SetZIndex(currPath, -99); canvas.Children.Add(currPath); return(currPath); }
private PointCollection DesignAlternativePath(Planet originPlanet, Planet destinationPlanet, Point[] straightPathPoints) { PointCollection points = new PointCollection(); List <Planet> planetList = new List <Planet>(); // finds collisions between default and final position foreach (var item in gameObjects) { if (item is Planet planet) { int collision = FindCollision(originPlanet, planet, destinationPlanet, new Point(originPlanet.Position.X, originPlanet.Position.Y), new Point(destinationPlanet.Position.X, destinationPlanet.Position.Y)); if (collision == -1) { continue; } else if (collision == 1) { planetList.Add(planet); } else { } } } // sorting by distance from origin if (planetList.Count > 1) { planetList.Sort((x, y) => MathClass.GetDistance(originPlanet.Position.X, x.Position.X, originPlanet.Position.Y, x.Position.Y) .CompareTo(MathClass.GetDistance(originPlanet.Position.X, y.Position.X, originPlanet.Position.Y, y.Position.Y))); } planetList.Insert(0, originPlanet); // add origin planet at the start of list planetList.Insert(planetList.Count, destinationPlanet); // add destination planet at the end of list Point? bestPointA = null; Point? bestPointB = null; List <Point> defaultPlanetPathPoints; List <Point> targetPlanetPathPoints; for (int i = 0; i < planetList.Count; i++) { double shortestDist = double.MaxValue; if (i == planetList.Count - 1) // if i == last planet, loop will be ended { break; } #region Deciding between contact or dodge points connection if (i == 0) { defaultPlanetPathPoints = planetList[i].ContactPoints; } else { defaultPlanetPathPoints = planetList[i].DodgePoints; } if (i == planetList.Count - 2) { targetPlanetPathPoints = planetList[i + 1].ContactPoints; } else { targetPlanetPathPoints = planetList[i + 1].DodgePoints; } #endregion foreach (Point a in defaultPlanetPathPoints) { foreach (Point b in targetPlanetPathPoints) { double dist = MathClass.GetDistance(a.X, b.X, a.Y, b.Y); // gets points for straight path if (dist < shortestDist) { shortestDist = dist; bestPointA = a; bestPointB = b; } } } if (bestPointA != null && bestPointB != null) { if (i != 0 && i != planetList.Count - 1) { int clockwiseDirCount = FindDodgePointsPath(planetList, points, bestPointA, points.Last(), 1, i, false); int anticlockwiseDirCount = FindDodgePointsPath(planetList, points, bestPointA, points.Last(), -1, i, false); // finds out which path is shorter if (clockwiseDirCount < anticlockwiseDirCount) { FindDodgePointsPath(planetList, points, bestPointA, points.Last(), 1, i, true); } else { FindDodgePointsPath(planetList, points, bestPointA, points.Last(), -1, i, true); } } points.Add((Point)bestPointA); points.Add((Point)bestPointB); } } return(points); }