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; }
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; } } }
private int GetNodeLevel(BalancedKdTreeNode <T> node) { if (object.Equals(null, node.Parent)) { return(0); } else { return(GetNodeLevel(node.Parent) + 1); } }
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); }
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); }
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); }
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); }
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; }