/// <summary> /// 指定境界ボリュームと接触する葉ノードを反復処理する列挙子の取得 /// </summary> /// <param name="volume">境界ボリューム</param> /// <returns>列挙子</returns> public IEnumerable <LeafNode> QueryLeaves(volume volume) { Stack <Node> stack = new Stack <Node>(256); stack.Push(_Root); while (stack.Count != 0) { var node = stack.Pop(); if (node == null) { continue; } if (volume.Intersects(node.Volume)) { var leaf = node.AsLeaf; if (leaf != null) { yield return(leaf); } else { var branch = node.AsBranch; stack.Push(branch.Child1); stack.Push(branch.Child2); } } } }
/// <summary> /// ツリーに指定境界ボリュームの葉ノードを追加する /// </summary> /// <param name="volume">境界ボリューム</param> /// <param name="data">葉ノードに保持するデータ</param> /// <returns>葉ノード</returns> public Node Add(volume volume, T data) { var leaf = new LeafNode(null, volume, data); InsertLeaf(_Root, leaf); _Count++; return(leaf); }
public bool Intersects(volume range) { if (Max.X < range.Min.X || range.Max.X < Min.X) { return(false); } if (Max.Y < range.Min.Y || range.Max.Y < Min.Y) { return(false); } return(true); }
/// <summary> /// 指定された範囲に対応するセル範囲を取得する /// </summary> /// <param name="range">範囲</param> /// <returns>セル範囲</returns> rangei CellRange(range range) { var s = _TransformScale; var t = _TransformTranslate; range.Min.AddSelf(t); range.Min.MulSelf(s); range.Max.AddSelf(t); range.Max.MulSelf(s); var cr = new rangei(range); cr.Min.ElementWiseMaxSelf(0); cr.Max.ElementWiseMinSelf(_CellMax); return(cr); }
/// <summary> /// コンストラクタ、管理する範囲と分割数を指定して初期化する /// </summary> /// <param name="range">管理する範囲</param> /// <param name="division">分割数</param> public GridSpace2f(range range, vectori division) { var size = range.Size; if (size.HasZero) { throw new InvalidOperationException("\"range\" must be non zero size."); } if (division.HasZero) { throw new InvalidOperationException("\"division\" must be non zero."); } var divisionf = new vector(division); _Range = range; _Division = division; _CellMax = division - 1; _Cells = new List <T> [division.Y * division.X]; _CellExtent = size / (divisionf * 2); _TransformScale = divisionf / size; _TransformTranslate = -range.Min; _InvTransformScale = size / divisionf; }
static element Proximity(volume a, volume b) { var d = (a.Min + a.Max) - (b.Min + b.Max); return(d.Sum()); }
static int Select(volume o, volume a, volume b) { return(Proximity(o, a) < Proximity(o, b) ? 0 : 1); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="parent">親ノード</param> /// <param name="volume">境界ボリューム</param> /// <param name="data">データ</param> public Node(BranchNode parent, volume volume) { this.Volume = volume; this.Parent = parent; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="parent">親ノード</param> /// <param name="volume">境界ボリューム</param> /// <param name="data">データ</param> public LeafNode(BranchNode parent, volume volume, T data) : base(parent, volume) { this.Value = data; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="parent">親ノード</param> /// <param name="volume">境界ボリューム</param> public BranchNode(BranchNode parent, volume volume) : base(parent, volume) { }
public void MergeSelf(volume range) { Min.ElementWiseMinSelf(range.Min); Max.ElementWiseMaxSelf(range.Max); }
public volume Merge(volume range) { return(new volume(vector.ElementWiseMin(Min, range.Min), vector.ElementWiseMax(Max, range.Max))); }
public bool Contains(volume range) { return(Min <= range.Min && range.Max <= Max); }