コード例 #1
0
        private void RigthRotate(BalancedKdTreeNode <T> node)
        {
            if (node.LeftChild == null || node.RightChild == null)
            {
                throw new NotImplementedException();
            }

            BalancedKdTreeNode <T> leftChild = node.LeftChild;

            node.LeftChild = leftChild.RightChild;

            if (node.Parent == null)
            {
                this.Root = leftChild;
            }
            else if (object.ReferenceEquals(node, node.Parent.LeftChild))
            {
                node.Parent.LeftChild = leftChild;
            }
            else
            {
                node.Parent.RightChild = leftChild;
            }

            leftChild.RightChild = node;
        }
コード例 #2
0
        private void Add(BalancedKdTreeNode <T> parent, BalancedKdTreeNode <T> childValue)
        {
            int functionIndex = GetNodeLevel(parent) % comparers.Count;

            if (this.comparers[functionIndex](parent.Point, childValue.Point) >= 0)
            {
                if (parent.LeftChild != NilNode)
                {
                    Add(parent.LeftChild, childValue);
                }
                else
                {
                    parent.LeftChild = childValue;
                }
            }
            else
            {
                if (parent.RightChild != NilNode)
                {
                    Add(parent.RightChild, childValue);
                }
                else
                {
                    parent.RightChild = childValue;
                }
            }
        }
コード例 #3
0
 private int GetNodeLevel(BalancedKdTreeNode <T> node)
 {
     if (object.Equals(null, node.Parent))
     {
         return(0);
     }
     else
     {
         return(GetNodeLevel(node.Parent) + 1);
     }
 }
コード例 #4
0
        public void Insert(T value)
        {
            BalancedKdTreeNode <T> node = new BalancedKdTreeNode <T>(value, Trees.NodeColor.Red)
            {
                Parent = this.Root
            };

            //node.LeftChild = nilNode;
            //node.RigthChild = nilNode;

            Add(this.Root, node);

            InsertFixup(node);
        }
コード例 #5
0
        private List <T> GetAllValues(BalancedKdTreeNode <T> node)
        {
            var result = new List <T>();

            result.Add(node.Point);

            if (node.LeftChild != null && !node.LeftChild.IsNilNode())
            {
                result.AddRange(GetAllValues(node.LeftChild));
            }

            if (node.RightChild != null && !node.RightChild.IsNilNode())
            {
                result.AddRange(GetAllValues(node.RightChild));
            }

            return(result);
        }
コード例 #6
0
        private List <T> FindNeighbours(T point, double radius, BalancedKdTreeNode <T> node, Func <T, T, double> distanceFunc = null)
        {
            var result = new List <T>();

            //if (distanceFunc(point, node.Point) <= radius)
            //{
            //    result.Add(node.Point);
            //}

            if (node.LeftChild != null && !node.LeftChild.IsNilNode())
            {
                var relation = SpatialUtility.CalculateAxisAlignedRectangleRelationToCircle(PointFunc(point), radius, node.LeftChild.MinimumBoundingBox);

                if (relation == IRI.Msh.Common.Model.SpatialRelation.Contained)
                {
                    result.AddRange(GetAllValues(node.LeftChild));
                }
                else if (relation == IRI.Msh.Common.Model.SpatialRelation.Intersects)
                {
                    result.AddRange(FindNeighbours(point, radius, node.LeftChild, distanceFunc));
                }
            }

            if (node.RightChild != null && !node.RightChild.IsNilNode())
            {
                var relation = SpatialUtility.CalculateAxisAlignedRectangleRelationToCircle(PointFunc(point), radius, node.RightChild.MinimumBoundingBox);

                if (relation == IRI.Msh.Common.Model.SpatialRelation.Contained)
                {
                    result.AddRange(GetAllValues(node.RightChild));
                }
                else if (relation == IRI.Msh.Common.Model.SpatialRelation.Intersects)
                {
                    result.AddRange(FindNeighbours(point, radius, node.RightChild, distanceFunc));
                }
            }

            return(result);
        }
コード例 #7
0
        private T FindNearestNeighbour(T point, double distance, BalancedKdTreeNode <T> node, Func <T, T, double> distanceFunc)
        {
            double minDistance = Math.Min(distance, distanceFunc(point, node.Point));

            T result = node.Point;

            if (node.LeftChild != null &&
                !node.LeftChild.IsNilNode() &&
                SpatialUtility.CircleRectangleIntersects(PointFunc(point), minDistance, node.LeftChild.MinimumBoundingBox))
            {
                var newPoint = FindNearestNeighbour(point, minDistance, node.LeftChild, distanceFunc);

                if (distanceFunc(point, newPoint) < minDistance)
                {
                    minDistance = distanceFunc(point, newPoint);

                    result = newPoint;
                }
            }

            if (node.RightChild != null &&
                !node.RightChild.IsNilNode() &&
                SpatialUtility.CircleRectangleIntersects(PointFunc(point), minDistance, node.RightChild.MinimumBoundingBox))
            {
                var newPoint = FindNearestNeighbour(point, minDistance, node.RightChild, distanceFunc);

                if (distanceFunc(point, newPoint) < minDistance)
                {
                    minDistance = distanceFunc(point, newPoint);

                    result = newPoint;
                }
            }

            return(result);
        }
コード例 #8
0
        private void InsertFixup(BalancedKdTreeNode <T> node)
        {
            while (node.Parent.Color == Trees.NodeColor.Red)
            {
                if (object.ReferenceEquals(node.Parent, node.Parent.Parent.LeftChild))
                {
                    BalancedKdTreeNode <T> y = node.Parent.Parent.RightChild;

                    if (y.Color == Trees.NodeColor.Red)
                    {
                        node.Parent.Color = Trees.NodeColor.Black;

                        y.Color = Trees.NodeColor.Black;

                        node.Parent.Parent.Color = Trees.NodeColor.Red;

                        node = node.Parent.Parent;
                    }
                    else if (object.ReferenceEquals(node, node.Parent.RightChild))
                    {
                        node = node.Parent;

                        LeftRotate(node);
                    }
                    else
                    {
                        node.Parent.Color = Trees.NodeColor.Black;

                        node.Parent.Parent.Color = Trees.NodeColor.Red;

                        RigthRotate(node.Parent.Parent);
                    }
                }
                else if (object.ReferenceEquals(node.Parent, node.Parent.Parent.RightChild))
                {
                    BalancedKdTreeNode <T> y = node.Parent.Parent.LeftChild;

                    if (y.Color == Trees.NodeColor.Red)
                    {
                        node.Parent.Color = Trees.NodeColor.Black;

                        y.Color = Trees.NodeColor.Black;

                        node.Parent.Parent.Color = Trees.NodeColor.Red;

                        node = node.Parent.Parent;
                    }
                    else if (object.ReferenceEquals(node, node.Parent.LeftChild))
                    {
                        node = node.Parent;

                        RigthRotate(node);
                    }
                    else
                    {
                        node.Parent.Color = Trees.NodeColor.Black;

                        node.Parent.Parent.Color = Trees.NodeColor.Red;

                        LeftRotate(node.Parent.Parent);
                    }
                }
                if (node.Parent == null)
                {
                    break;
                }
            }

            this.Root.Color = Trees.NodeColor.Black;
        }