Beispiel #1
0
 /// <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");
     }
 }
Beispiel #2
0
        public override bool Equals(object obj)
        {
            PLNode node = (PLNode)obj;

            if (node == null)
            {
                return(false);
            }
            return(this.Point.Equals(node.Point));
        }
Beispiel #3
0
        /// <summary>
        /// Simplifies this polygon.
        /// </summary>
        /// <param name="distance">The distance tolerance.</param>
        /// <param name="angle">The angle tolerance.</param>
        /// <returns>List&lt;UV&gt;.</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);
        }