/// <summary> /// 构造方法:创建并初始化Editor类型对象。 /// </summary> public Editor() { StringDictionary.Clear(); Int32Dictionary.Clear(); BooleanDictionary.Clear(); DoubleDictionary.Clear(); }
private void DrawSubdivision(Subdivision division) { // generate new random subdivision if desired if (division == null) { PointD offset = new PointD(OutputBox.Width * 0.2, OutputBox.Height * 0.2); SizeD scale = new SizeD(OutputBox.Width * 0.6, OutputBox.Height * 0.6); int count = MersenneTwister.Default.Next(4, 12); PointD[] points = new PointD[count]; for (int i = 0; i < points.Length; i++) { points[i] = new PointD( offset.X + MersenneTwister.Default.NextDouble() * scale.Width, offset.Y + MersenneTwister.Default.NextDouble() * scale.Height); } // outer bounds for Voronoi pseudo-vertices double margin = 3 * FontSize; RectD bounds = new RectD(margin, margin, OutputBox.Width - 2 * margin, OutputBox.Height - 2 * margin); var result = Voronoi.FindAll(points, bounds); division = result.ToVoronoiSubdivision().Source; } _division = division; _division.Validate(); _nearestEdge = -1; _edges = DrawSubdivision(OutputBox, FontSize, division); OutputBox.Children.Add(VertexCircle); }
/// <summary> /// Updates the <see cref="SubdivisionFace"/> keys in the specified dictionaries after the /// specified <see cref="SubdivisionEdge"/> has been split.</summary> /// <param name="edge"> /// The <see cref="SubdivisionEdge"/> whose splitting resulted in the current <see /// cref="SplitEdgeResult"/>.</param> /// <param name="edgeToFace1"> /// An <see cref="Int32Dictionary{T}"/> that maps the keys of any existing half-edges to the /// keys of the incident bounded <see cref="Subdivision.Faces"/> of the corresponding <see /// cref="Subdivision.Edges"/> in a first <see cref="Subdivision"/>.</param> /// <param name="edgeToFace2"> /// An <see cref="Int32Dictionary{T}"/> that maps the keys of any existing half-edges to the /// keys of the incident bounded <see cref="Subdivision.Faces"/> of the corresponding <see /// cref="Subdivision.Edges"/> in a second <see cref="Subdivision"/>.</param> /// <remarks> /// <b>UpdateFaces</b> ensures that the mapping between original and intersected faces /// established by the <see cref="Subdivision.Intersection"/> algorithm is kept up-to-date /// when edge splitting results in a valid <see cref="CreatedEdge"/>.</remarks> public void UpdateFaces(SubdivisionEdge edge, Int32Dictionary <Int32> edgeToFace1, Int32Dictionary <Int32> edgeToFace2) { if (CreatedEdge == null) { return; } int face; if (edgeToFace1.TryGetValue(edge._key, out face)) { Debug.Assert(face != 0); edgeToFace1.Add(CreatedEdge._key, face); } if (edgeToFace2.TryGetValue(edge._key, out face)) { Debug.Assert(face != 0); edgeToFace2.Add(CreatedEdge._key, face); } }
/// <summary> /// 方法:存入int类型的配置信息。 /// </summary> /// <param name="key">关键字</param> /// <param name="value">配置信息</param> public void PutInt32(string key, int value) { Int32Dictionary.Add(key, value); }
/// <summary> /// 构造方法:创建并初始化Editor类型对象。 /// </summary> /// <param name="key">关键字</param> /// <param name="value">配置信息</param> public Editor(String key, Int32 value) { Int32Dictionary.Clear(); PutInt32(key, value); }
/// <summary> /// Draws the specified <see cref="Subdivision"/> to the specified <see cref="Canvas"/>. /// </summary> /// <param name="canvas"> /// The <see cref="Canvas"/> to draw on.</param> /// <param name="fontSize"> /// The <see cref="Control.FontSize"/> for all text labels.</param> /// <param name="division"> /// The <see cref="Subdivision"/> to draw on <paramref name="canvas"/>.</param> /// <returns> /// An <see cref="Int32Dictionary{T}"/> that maps the keys of all half-edges in <paramref /// name="division"/> to the corresponding WPF <see cref="Path"/>.</returns> internal static Int32Dictionary <Path> DrawSubdivision( Canvas canvas, double fontSize, Subdivision division) { canvas.Children.Clear(); var edges = new Int32Dictionary <Path>(division.Edges.Count); // draw vertices const double radius = 2.0; foreach (PointD vertex in division.Vertices.Keys) { var circle = new Ellipse() { Width = 2 * radius, Height = 2 * radius, Stroke = Brushes.Black, Fill = Brushes.Black }; Canvas.SetLeft(circle, vertex.X - radius); Canvas.SetTop(circle, vertex.Y - radius); canvas.Children.Add(circle); } // draw half-edges with keys foreach (var pair in division.Edges) { LineD line = pair.Value.ToLine(); double deltaX = line.End.X - line.Start.X; double deltaY = line.End.Y - line.Start.Y; double length = Math.Sqrt(deltaX * deltaX + deltaY * deltaY); // slightly offset half-edge toward incident face double offsetX = radius * deltaX / length; double offsetY = radius * deltaY / length; double x0 = line.Start.X + offsetX - offsetY; double y0 = line.Start.Y + offsetX + offsetY; double x1 = line.End.X - offsetX - offsetY; double y1 = line.End.Y + offsetX - offsetY; // draw hook in direction of half-edge double angle = line.Angle + 0.75 * Math.PI; Point hookStart = new Point(x1 - deltaX / 4, y1 - deltaY / 4); Point hookEnd = new Point( hookStart.X + Math.Cos(angle) * 8, hookStart.Y + Math.Sin(angle) * 8); PathFigure[] figures = new PathFigure[] { new PathFigure(new Point(x0, y0), new PathSegment[] { new LineSegment(new Point(x1, y1), true) }, false), new PathFigure(hookStart, new PathSegment[] { new LineSegment(hookEnd, true) }, false) }; PathGeometry geometry = new PathGeometry(figures); geometry.Freeze(); Path path = new Path() { Stroke = Brushes.Red, Data = geometry }; canvas.Children.Add(path); edges.Add(pair.Key, path); // draw key of current half-edge double centerX = (line.Start.X + line.End.X) / 2; double fontSizeX = (pair.Key < 10 && deltaY > 0) ? fontSize / 2 : fontSize; double textX = centerX - fontSizeX * deltaY / length - fontSize / 1.8; double centerY = (line.Start.Y + line.End.Y) / 2; double textY = centerY + fontSize * deltaX / length - fontSize / 1.5; TextBlock text = new TextBlock(new Run(pair.Key.ToString())); Canvas.SetLeft(text, textX); Canvas.SetTop(text, textY); canvas.Children.Add(text); } // draw keys of bounded faces foreach (var pair in division.Faces) { if (pair.Key == 0) { continue; } PointD centroid = pair.Value.OuterEdge.CycleCentroid; TextBlock text = new TextBlock(new Run(pair.Key.ToString())); text.FontWeight = FontWeights.Bold; Canvas.SetLeft(text, centroid.X - fontSize / 2); Canvas.SetTop(text, centroid.Y - fontSize / 2); canvas.Children.Add(text); } return(edges); }