/// <summary> /// Adds the connection. /// </summary> /// <param name="node">The node.</param> /// <exception cref="ArgumentException">Each node cannot be connected to more than 2 points</exception> public void AddConnection(PLNode node) { this.Connections.Add(node); if (this.Connections.Count > 2) { throw new ArgumentException("Each node cannot be connected to more than 2 points"); } }
public override bool Equals(object obj) { PLNode node = (PLNode)obj; if (node == null) { return(false); } return(this.Point.Equals(node.Point)); }
/// <summary> /// Simplifies this polygon. /// </summary> /// <param name="distance">The distance tolerance.</param> /// <param name="angle">The angle tolerance.</param> /// <returns>List<UV>.</returns> /// <exception cref="ArgumentException">Heap cannot remove the found end point</exception> public List <UV> Simplify(double distance, double angle = .0001) { double distanceTolerance = distance * distance; double sine = Math.Sin(angle * Math.PI / 180); double angleTolerance = sine * sine; SortedSet <PLNode> heap = new SortedSet <PLNode>(new PLNodeComparer(distanceTolerance)); PLNode[] allNodes = new PLNode[this.PointCount]; for (int i = 0; i < allNodes.Length; i++) { allNodes[i] = new PLNode(this._pntList[i]); } if (this.Closed) { for (int i = 0; i < allNodes.Length; i++) { int i0 = (i == 0) ? allNodes.Length - 1 : i - 1; int i1 = (i == allNodes.Length - 1) ? 0 : i + 1; allNodes[i].AddConnection(allNodes[i0]); allNodes[i].AddConnection(allNodes[i1]); allNodes[i].LoadFactors(); if (heap.Contains(allNodes[i])) { allNodes[i].Remained = false; // this sucks. Although the polyline does not have equal points, there are // points that are so close that their distance squared is zero! Damn it. // this meains the heap should be reconstructed because removing one node // breaks the connection! I have to make sure that each node is connected // to the neighbors that exist in the heap } else { heap.Add(allNodes[i]); } } if (heap.Count < this.PointCount) // reconstructing the heap { PLNode[] newNodes = new PLNode[heap.Count]; int k = 0; for (int i = 0; i < this.PointCount; i++) { if (allNodes[i].Remained) { newNodes[k] = new PLNode(allNodes[i].Point); k++; } } heap.Clear(); allNodes = newNodes; for (int i = 0; i < allNodes.Length; i++) { int i0 = (i == 0) ? allNodes.Length - 1 : i - 1; int i1 = (i == allNodes.Length - 1) ? 0 : i + 1; allNodes[i].AddConnection(allNodes[i0]); allNodes[i].AddConnection(allNodes[i1]); allNodes[i].LoadFactors(); heap.Add(allNodes[i]); } } } else { for (int i = 0; i < allNodes.Length; i++) { if (i > 0) { allNodes[i].AddConnection(allNodes[i - 1]); } if (i < allNodes.Length - 1) { allNodes[i].AddConnection(allNodes[i + 1]); } allNodes[i].LoadFactors(); if (heap.Contains(allNodes[i])) { allNodes[i].Remained = false; // this sucks. Although the polyline does not have equal points, there are // points that are so close that their distance squared is zero! Damn it. // this meains the heap should be reconstructed because removing one node // breaks the connection! I have to make sure that each node is connected // to the neighbors that exist in the heap } else { heap.Add(allNodes[i]); } } if (heap.Count < this.PointCount) // reconstructing the heap { PLNode[] newNodes = new PLNode[heap.Count]; int k = 0; for (int i = 0; i < this.PointCount; i++) { if (allNodes[i].Remained) { newNodes[k] = new PLNode(allNodes[i].Point); k++; } } heap.Clear(); allNodes = newNodes; for (int i = 0; i < allNodes.Length; i++) { if (i > 0) { allNodes[i].AddConnection(allNodes[i - 1]); } if (i < allNodes.Length - 1) { allNodes[i].AddConnection(allNodes[i + 1]); } allNodes[i].LoadFactors(); if (heap.Contains(allNodes[i])) { allNodes[i].Remained = false; } else { heap.Add(allNodes[i]); } } } } // purging var min = heap.Min; while (!min.IsSignificant(angleTolerance, distanceTolerance)) { heap.Remove(min); if (min.Connections.Count == 1) { throw new ArgumentException("Heap cannot remove the found end point"); } PLNode node1 = min.Connections.First(); min.Connections.Remove(node1); PLNode node2 = min.Connections.First(); min.Connections.Remove(node2); heap.Remove(node1); heap.Remove(node2); node1.Connections.Remove(min); node2.Connections.Remove(min); node1.AddConnection(node2); node2.AddConnection(node1); node1.LoadFactors(); heap.Add(node1); node2.LoadFactors(); heap.Add(node2); min.Remained = false; min = heap.Min; } List <UV> purged = new List <UV>(); for (int i = 0; i < allNodes.Length; i++) { if (allNodes[i].Remained) { purged.Add(allNodes[i].Point); } } return(purged); }