/// <summary> /// Picks the next best box to add to one of the given nodes. /// </summary> /// <param name="nodeBoxes"></param> /// <param name="boxes"></param> /// <param name="nodeBoxIndex"></param> /// <returns></returns> protected static int PickNext(BoxF2D[] nodeBoxes, IList <BoxF2D> boxes, out int nodeBoxIndex) { double difference = double.MinValue; nodeBoxIndex = 0; int pickedIdx = -1; for (int idx = 0; idx < boxes.Count; idx++) { BoxF2D item = boxes[idx]; double d1 = item.Union(nodeBoxes[0]).Surface - item.Surface; double d2 = item.Union(nodeBoxes[1]).Surface - item.Surface; double localDifference = System.Math.Abs(d1 - d2); if (difference < localDifference) { difference = localDifference; if (d1 == d2) { nodeBoxIndex = (nodeBoxes[0].Surface < nodeBoxes[1].Surface) ? 0 : 1; } else { nodeBoxIndex = (d1 < d2) ? 0 : 1; } pickedIdx = idx; } } return(pickedIdx); }
public void BoxF2DOverlapsTest() { var rect1 = new BoxF2D(0, 0, 2, 2); var rect2 = new BoxF2D(3, 2, 5, 4); Assert.IsFalse(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(0, 0, 2, 2); rect2 = new BoxF2D(2, 0, 4, 2); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(0, 0, 2, 2); rect2 = new BoxF2D(1, 1, 3, 3); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(1, 0, 2, 3); rect2 = new BoxF2D(0, 1, 3, 2); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(0, 0, 3, 3); rect2 = new BoxF2D(1, 1, 2, 2); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); }
/// <summary> /// Removes the given item but does not re-balance the tree. /// </summary> /// <param name="node">The node to begin the search for the item.</param> /// <param name="box">The box of the item.</param> /// <param name="item">The item to remove.</param> private static bool RemoveSimple(Node node, BoxF2D box, T item) { if (node.Children is List <Node> ) { var children = (node.Children as List <Node>); for (int idx = 0; idx < children.Count; idx++) { if (box.Overlaps(node.Boxes[idx])) { if (RTreeMemoryIndex <T> .RemoveSimple(node.Children[idx] as Node, box, item)) { // if sucessfull stop the search. return(true); } } } } else { var children = (node.Children as List <T>); if (children != null) { // the children are of the data type. return(children.Remove(item)); } } return(false); }
public void BoxF2DUnionTest() { var testDataList = new List <BoxF2D>(); for (int idx = 0; idx < 10000; idx++) { double x1 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(1.0); double x2 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(1.0); double y1 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(1.0); double y2 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(1.0); testDataList.Add(new BoxF2D(x1, y1, x2, y2)); } BoxF2D box = testDataList[0]; foreach (BoxF2D rectangleF2D in testDataList) { box = box.Union(rectangleF2D); } foreach (BoxF2D rectangleF2D in testDataList) { box.IsInside(rectangleF2D); } }
/// <summary> /// Removes the given item when it is contained in the given box. /// </summary> /// <param name="box"></param> /// <param name="item"></param> public void Remove(BoxF2D box, T item) { if (RTreeMemoryIndex <T> .RemoveSimple(_root, box, item)) { _count--; } }
public void RTreeMemoryIndexAddTests() { // build test-data. var testDataList = new List<KeyValuePair<BoxF2D, DataTestClass>>(); const int count = 10000; var randomGenerator = new RandomGenerator(66707770); // make this deterministic for (int idx = 0; idx < count; idx++) { double x1 = randomGenerator.Generate(1.0); double x2 = randomGenerator.Generate(1.0); double y1 = randomGenerator.Generate(1.0); double y2 = randomGenerator.Generate(1.0); var box = new BoxF2D(new PointF2D(x1, y1), new PointF2D(x2, y2)); var testData = new DataTestClass(); testData.Data = idx.ToString(System.Globalization.CultureInfo.InvariantCulture); testDataList.Add(new KeyValuePair<BoxF2D, DataTestClass>( box, testData)); } // create the index and reference index. var index = new RTreeMemoryIndex<DataTestClass>(); var reference = new ReferenceImplementation<DataTestClass>(); // add all the data. for (int idx = 0; idx < count; idx++) { var keyValuePair = testDataList[idx]; index.Add(keyValuePair.Key, keyValuePair.Value); reference.Add(keyValuePair.Key, keyValuePair.Value); //Assert.AreEqual(reference.Count(), index.Count()); } //Assert.AreEqual(count, index.Count()); // generate random boxes and compare results. for (int idx = 0; idx < 200; idx++) { double x1 = randomGenerator.Generate(1.0); double x2 = randomGenerator.Generate(1.0); double y1 = randomGenerator.Generate(1.0); double y2 = randomGenerator.Generate(1.0); var box = new BoxF2D(new PointF2D(x1, y1), new PointF2D(x2, y2)); var resultIndex = new HashSet<DataTestClass>(index.Get(box)); var resultReference = new HashSet<DataTestClass>(reference.Get(box)); foreach (var data in resultIndex) { Assert.IsTrue(resultReference.Contains(data)); } foreach (var data in resultReference) { Assert.IsTrue(resultIndex.Contains(data)); } } }
/// <summary> /// Adds all the data in the given node and inside the given bounding box to the given data list. /// </summary> /// <param name="data"></param> /// <param name="node"></param> /// <param name="box"></param> public void AddInsideAtNode(IList <TDataType> data, QuadTreeNode node, BoxF2D box) { if (box.Overlaps(_bounds)) { // ok there is an overlap. if (_depth > 0) { if (_minMin != null) { _minMin.AddInsideAtNode(data, node, box); } if (_minMax != null) { _minMax.AddInsideAtNode(data, node, box); } if (_maxMin != null) { _maxMin.AddInsideAtNode(data, node, box); } if (_maxMax != null) { _maxMax.AddInsideAtNode(data, node, box); } } else { foreach (KeyValuePair <TPointType, TDataType> data_pair in _data) { if (box.IsInside(data_pair.Key)) { data.Add(data_pair.Value); } } } } }
public IEnumerable <T> Get(BoxF2D box) { HashSet <T> result = new HashSet <T>(); RTreeMemoryIndex <T> .Get(this._root, box, result); return((IEnumerable <T>)result); }
public void Remove(BoxF2D box, T item) { if (!RTreeMemoryIndex <T> .RemoveSimple(this._root, box, item)) { return; } this._count = this._count - 1; }
/// <summary> /// Queries this index and returns all objects with overlapping bounding boxes. /// </summary> /// <param name="box"></param> /// <returns></returns> public IEnumerable <T> Get(BoxF2D box) { var result = new HashSet <T>(); RTreeMemoryIndex <T> .Get(_root, box, result); return(result); }
/// <summary> /// Try and find matching lines. /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <returns></returns> private MatchPosition FindMatch(ILocatedObjectIndex <PointF2D, Scene2D.ScenePoints> linesIndex, Dictionary <Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, float epsilon, out Scene2D.ScenePoints found) { // build box. var box = new BoxF2D(x, y); box = box.ResizeWith(epsilon * 1.1); // get all geometries in this box. var potentialMatches = linesIndex.GetInside(box); // find a match in the potential matches list. PointF2D first = new PointF2D(x[0], y[0]); PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]); MatchPosition position = MatchPosition.None; found = null; foreach (var line in potentialMatches) { // check first. PointF2D potentialFirst = new PointF2D(line.X[0], line.Y[0]); PointF2D potentialLast = new PointF2D(line.X[line.X.Length - 1], line.Y[line.Y.Length - 1]); if (first.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.FirstFirst; } else if (last.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.LastFirst; } else if (first.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.FirstLast; } else if (last.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.LastLast; } Scene2DStylesSet styleValue; if (position != MatchPosition.None && lines.TryGetValue(line, out styleValue) && styleValue.Equals(style)) { break; } else { position = MatchPosition.None; found = null; } } return(position); }
public BoxF2D GetBox() { BoxF2D boxF2D = this.Boxes[0]; for (int index = 1; index < this.Boxes.Count; ++index) { boxF2D = boxF2D.Union(this.Boxes[index]); } return(boxF2D); }
/// <summary> /// Returns the bounding box for this node. /// </summary> /// <returns></returns> public BoxF2D GetBox() { BoxF2D box = this.Boxes[0]; for (int idx = 1; idx < this.Boxes.Count; idx++) { box = box.Union(this.Boxes[idx]); } return(box); }
/// <summary> /// Returns true if the given rectangle overlaps with this view. /// </summary> /// <returns><c>true</c>, if with rectangle overlaps, <c>false</c> otherwise.</returns> /// <param name="left">Left.</param> /// <param name="top">Top.</param> /// <param name="right">Right.</param> /// <param name="bottom">Bottom.</param> public bool OverlapsWithBox(double left, double top, double right, double bottom) { BoxF2D box = new BoxF2D(left, top, right, bottom); if (box.Overlaps(_rectangle.BoundingBox)) { return(_rectangle.Overlaps(box)); } return(false); }
public IEnumerable <TDataType> GetInside(BoxF2D box) { if (this._root == null) { return((IEnumerable <TDataType>) new List <TDataType>()); } List <TDataType> dataTypeList = new List <TDataType>(); this._root.AddInsideAtNode((IList <TDataType>)dataTypeList, this._root, box); return((IEnumerable <TDataType>)dataTypeList); }
/// <summary> /// Calculates the simplification surface condition. /// </summary> /// <returns><c>true</c>, if simplification surface was calculated, <c>false</c> otherwise.</returns> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> private bool CalculateSimplificationSurfaceCondition(float zoomFactor, double[] x, double[] y) { BoxF2D rectangle = new BoxF2D(x, y); float epsilon = (1.0f / zoomFactor) * 10; if (rectangle.Delta[0] < epsilon && rectangle.Delta[1] < epsilon) { return(false); } return(true); }
public QuadTreeNode(int dept, BoxF2D bounds) { this._depth = dept; this._bounds = new BoxF2D(new PointF2D(bounds.Max[0], bounds.Max[1]), new PointF2D(bounds.Min[0], bounds.Min[1])); this._middle0 = (bounds.Min[0] + bounds.Max[0]) / 2.0; this._middle1 = (bounds.Min[1] + bounds.Max[1]) / 2.0; if (this._depth != 0) { return; } this._data = new List <KeyValuePair <TPointType, TDataType> >(); }
public QuadTreeNode(bool min0, bool min1, QuadTree <TPointType, TDataType> .QuadTreeNode node) { this._depth = node.Depth + 1; double num1 = node.Max0 - node.Min0; double num2 = node.Max1 - node.Min1; double x1; double x2; double y1; double y2; if (min0) { x1 = node.Min0 - num1; x2 = node.Max0; if (min1) { y1 = node.Min1 - num2; y2 = node.Max1; this._maxMax = node; } else { y1 = node.Min1; y2 = node.Max1 + num2; this._maxMin = node; } } else { if (min1) { y1 = node.Min1 - num2; y2 = node.Max1; this._minMax = node; } else { y1 = node.Min1; y2 = node.Max1 + num2; this._minMin = node; } x1 = node.Min0; x2 = node.Max0 + num1; } this._middle0 = (x1 + x2) / 2.0; this._middle1 = (y1 + y2) / 2.0; this._bounds = new BoxF2D(new PointF2D(x2, y2), new PointF2D(x1, y1)); if (this._depth != 0) { return; } this._data = new List <KeyValuePair <TPointType, TDataType> >(); }
public QuadTreeNode(int dept, double min0, double min1, double max0, double max1) { this._depth = dept; this._bounds = new BoxF2D(new PointF2D(max0, max1), new PointF2D(min0, min1)); this._middle0 = (min0 + max0) / 2.0; this._middle1 = (min1 + max1) / 2.0; if (this._depth != 0) { return; } this._data = new List <KeyValuePair <TPointType, TDataType> >(); }
/// <summary> /// Queries this index and returns all objects with overlapping bounding boxes. /// </summary> /// <param name="box"></param> /// <returns></returns> public IEnumerable <T> Get(BoxF2D box) { var result = new HashSet <T>(); foreach (var entry in _list) { if (entry.Key.Overlaps(box)) { result.Add(entry.Value); } } return(result); }
/// <summary> /// Returns all data inside the given box. /// </summary> /// <param name="box"></param> /// <returns></returns> public IEnumerable <DataType> GetInside(BoxF2D box) { HashSet <DataType> dataset = new HashSet <DataType>(); foreach (KeyValuePair <PointType, DataType> data in _data) { if (box.Contains(data.Key)) { dataset.Add(data.Value); } } return(dataset); }
public IEnumerable <DataType> GetInside(BoxF2D box) { HashSet <DataType> dataTypeSet = new HashSet <DataType>(); foreach (KeyValuePair <PointType, DataType> keyValuePair in this._data) { if (box.Contains((PointF2D)keyValuePair.Key)) { dataTypeSet.Add(keyValuePair.Value); } } return((IEnumerable <DataType>)dataTypeSet); }
/// <summary> /// Returns all data inside the given bounding box. /// </summary> /// <param name="box"></param> /// <returns></returns> public IEnumerable <TDataType> GetInside(BoxF2D box) { if (_root == null) { // this can only mean not data was added yet to this index. // return an empty enumerable. return(new List <TDataType>()); } // there is data! var data = new List <TDataType>(); _root.AddInsideAtNode(data, _root, box); return(data); }
public void TestRectangleF2DOuterBox() { double delta = 0.00001; // this should create the exact same rectangle as in the other tests. RectangleF2D rectangle = RectangleF2D.FromBoundsAndCenter(System.Math.Sqrt(2) * 2, System.Math.Sqrt(2) * 2, 3, 1, 45); // get the box and tests it's bounds. BoxF2D box = rectangle.BoundingBox; Assert.AreEqual(1, box.Min[0], delta); Assert.AreEqual(-1, box.Min[1], delta); Assert.AreEqual(5, box.Max[0], delta); Assert.AreEqual(3, box.Max[1], delta); }
/// <summary> /// Choose the child to best place the given box. /// </summary> /// <param name="box"></param> /// <param name="node"></param> /// <returns></returns> private static Node ChooseLeaf(Node node, BoxF2D box) { if (box == null) { throw new ArgumentNullException("box"); } if (node == null) { throw new ArgumentNullException("node"); } // keep looping until a leaf is found. while (node.Children is List <Node> ) { // choose the best leaf. Node bestChild = null; BoxF2D bestBox = null; double bestIncrease = double.MaxValue; var children = node.Children as List <Node>; // cast just once. for (int idx = 0; idx < node.Boxes.Count; idx++) { BoxF2D union = node.Boxes[idx].Union(box); double increase = union.Surface - node.Boxes[idx].Surface; // calculates the increase. if (bestIncrease > increase) { // the increase for this child is smaller. bestIncrease = increase; bestChild = children[idx]; bestBox = node.Boxes[idx]; } else if (bestBox != null && bestIncrease == increase) { // the increase is indentical, choose the smalles child. if (node.Boxes[idx].Surface < bestBox.Surface) { bestChild = children[idx]; bestBox = node.Boxes[idx]; } } } if (bestChild == null) { throw new Exception("Finding best child failed!"); } node = bestChild; } return(node); }
public IEnumerable <T> Get(BoxF2D box) { HashSet <T> result = new HashSet <T>(); long ticks1 = DateTime.Now.Ticks; this._stream.Seek(0L, SeekOrigin.Begin); this._serializer.Search(this._stream, box, result); long ticks2 = DateTime.Now.Ticks; Log.TraceEvent("RTreeStreamIndex", TraceEventType.Verbose, string.Format("Deserialized {0} objects in {1}ms.", new object[2] { (object)result.Count, (object)new TimeSpan(ticks2 - ticks1).TotalMilliseconds })); return((IEnumerable <T>)result); }
public void Add(BoxF2D box, T item) { this._count = this._count + 1; if (this._root == null) { this._root = new RTreeMemoryIndex <T> .Node(); this._root.Boxes = new List <BoxF2D>(); this._root.Children = (IList) new List <T>(); } RTreeMemoryIndex <T> .Node node = RTreeMemoryIndex <T> .Add(RTreeMemoryIndex <T> .ChooseLeaf(this._root, box), box, item, this._minLeafSize, this._maxLeafSize); if (node == null) { return; } this._root = node; }
/// <summary> /// Returns the data that has overlapping bounding boxes with the given box. /// </summary> /// <param name="box"></param> /// <returns></returns> public IEnumerable <T> Get(BoxF2D box) { var results = new HashSet <T>(); // move to the start. long ticksBefore = DateTime.Now.Ticks; _stream.Seek(0, SeekOrigin.Begin); _serializer.Search(_stream, box, results); long ticksAfter = DateTime.Now.Ticks; OsmSharp.Logging.Log.TraceEvent("RTreeStreamIndex", TraceEventType.Verbose, string.Format("Deserialized {0} objects in {1}ms.", results.Count, (new TimeSpan(ticksAfter - ticksBefore).TotalMilliseconds))); return(results); }
public void TestBoxF2DLineEnumeration() { var rect1 = new BoxF2D(0, 0, 2, 2); List <LineF2D> lines = new List <LineF2D>(rect1 as IEnumerable <LineF2D>); Assert.AreEqual(4, lines.Count); Assert.IsTrue(lines[0].IsSegment); Assert.IsTrue(lines[1].IsSegment); Assert.IsTrue(lines[2].IsSegment); Assert.IsTrue(lines[3].IsSegment); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[0] && x.Point2 == rect1.Corners[1]) || (x.Point2 == rect1.Corners[0] && x.Point1 == rect1.Corners[1]))); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[1] && x.Point2 == rect1.Corners[2]) || (x.Point2 == rect1.Corners[2] && x.Point1 == rect1.Corners[1]))); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[2] && x.Point2 == rect1.Corners[3]) || (x.Point2 == rect1.Corners[3] && x.Point1 == rect1.Corners[2]))); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[3] && x.Point2 == rect1.Corners[0]) || (x.Point2 == rect1.Corners[0] && x.Point1 == rect1.Corners[3]))); }
/// <summary> /// Adds a new item with the corresponding box. /// </summary> /// <param name="box"></param> /// <param name="item"></param> public void Add(BoxF2D box, T item) { _count++; if (_root == null) { // create the root. _root = new Node(); _root.Boxes = new List <BoxF2D>(); _root.Children = new List <T>(); } // add new data. Node leaf = RTreeMemoryIndex <T> .ChooseLeaf(_root, box); Node newRoot = RTreeMemoryIndex <T> .Add(leaf, box, item, _minLeafSize, _maxLeafSize); if (newRoot != null) { // there should be a new root. _root = newRoot; } }
/// <summary> /// Creates a quad tree with given bounds. /// </summary> /// <param name="dept"></param> /// <param name="min0"></param> /// <param name="min1"></param> /// <param name="max0"></param> /// <param name="max1"></param> public QuadTreeNode(int dept, double min0, double min1, double max0, double max1) { _depth = dept; _bounds = new BoxF2D(new PointF2D(max0, max1), new PointF2D(min0, min1)); //_max_1 = max_1; // max y = top. //_max_0 = max_0; // max x = right. //_min_0 = min_0; // min y = bottom. //_min_1 = min_1; // min x = left. // calculate the middles. _middle0 = (min0 + max0) / 2.0; _middle1 = (min1 + max1) / 2.0; if (_depth == 0) { _data = new List <KeyValuePair <TPointType, TDataType> >(); } }
/// <summary> /// Calculates the simplification surface condition. /// </summary> /// <returns><c>true</c>, if simplification surface was calculated, <c>false</c> otherwise.</returns> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> private bool CalculateSimplificationSurfaceCondition(float zoomFactor, double[] x, double[] y) { BoxF2D rectangle = new BoxF2D(x, y); float epsilon = this.CalculateSimplificationEpsilon(zoomFactor); //(1.0f / zoomFactor); if (rectangle.Delta[0] < epsilon && rectangle.Delta[1] < epsilon) { return false; } return true; }
/// <summary> /// Try and find matching lines. /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <returns></returns> private MatchPosition FindMatch(ILocatedObjectIndex<PointF2D, Scene2D.ScenePoints> linesIndex, Dictionary<Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, float epsilon, out Scene2D.ScenePoints found) { // build box. var box = new BoxF2D(x, y); box = box.ResizeWith(epsilon * 1.1); // get all geometries in this box. var potentialMatches = linesIndex.GetInside(box); // find a match in the potential matches list. PointF2D first = new PointF2D(x[0], y[0]); PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]); MatchPosition position = MatchPosition.None; found = null; foreach (var line in potentialMatches) { // check first. PointF2D potentialFirst = new PointF2D(line.X[0], line.Y[0]); PointF2D potentialLast = new PointF2D(line.X[line.X.Length - 1], line.Y[line.Y.Length - 1]); if (first.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.FirstFirst; } else if (last.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.LastFirst; } else if (first.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.FirstLast; } else if (last.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.LastLast; } Scene2DStylesSet styleValue; if (position != MatchPosition.None && lines.TryGetValue(line, out styleValue) && styleValue.Equals(style)) { break; } else { position = MatchPosition.None; found = null; } } return position; }
public void TestBoxF2DLineEnumeration() { var rect1 = new BoxF2D(0, 0, 2, 2); List<LineF2D> lines = new List<LineF2D>(rect1 as IEnumerable<LineF2D>); Assert.AreEqual(4, lines.Count); Assert.IsTrue(lines[0].IsSegment); Assert.IsTrue(lines[1].IsSegment); Assert.IsTrue(lines[2].IsSegment); Assert.IsTrue(lines[3].IsSegment); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[0] && x.Point2 == rect1.Corners[1]) || (x.Point2 == rect1.Corners[0] && x.Point1 == rect1.Corners[1]))); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[1] && x.Point2 == rect1.Corners[2]) || (x.Point2 == rect1.Corners[2] && x.Point1 == rect1.Corners[1]))); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[2] && x.Point2 == rect1.Corners[3]) || (x.Point2 == rect1.Corners[3] && x.Point1 == rect1.Corners[2]))); Assert.IsTrue(lines.Exists(x => (x.Point1 == rect1.Corners[3] && x.Point2 == rect1.Corners[0]) || (x.Point2 == rect1.Corners[0] && x.Point1 == rect1.Corners[3]))); }
public void RTreeMemoryIndexEnumerationTests() { // create the index. var index = new RTreeMemoryIndex<DataTestClass>(); // build test-data. var testDataList = new HashSet<DataTestClass>(); const int count = 10000; var randomGenerator = new RandomGenerator(66707770); // make this deterministic for (int idx = 0; idx < count; idx++) { double x1 = randomGenerator.Generate(1.0); double x2 = randomGenerator.Generate(1.0); double y1 = randomGenerator.Generate(1.0); double y2 = randomGenerator.Generate(1.0); var box = new BoxF2D(new PointF2D(x1, y1), new PointF2D(x2, y2)); var testData = new DataTestClass(); testData.Data = idx.ToString(System.Globalization.CultureInfo.InvariantCulture); testDataList.Add(testData); index.Add(box, testData); } // compare and check if all data gets enumerated. HashSet<DataTestClass> reference = new HashSet<DataTestClass>(); foreach (DataTestClass dataTestClass in index) { reference.Add(dataTestClass); Assert.IsTrue(testDataList.Contains(dataTestClass)); } Assert.AreEqual(testDataList.Count, reference.Count); Assert.AreEqual(testDataList.Count, index.Count); }
public void RTreeMemoryIndexSmall1Tests() { var rect1 = new BoxF2D(0, 0, 2, 2); var rect2 = new BoxF2D(4, 0, 6, 2); var rect3 = new BoxF2D(0, 4, 2, 6); var rect4 = new BoxF2D(4, 4, 6, 6); var rect5 = new BoxF2D(1, 1, 3, 3); // create the index and reference index. var index = new RTreeMemoryIndex<string>(4, 1); // add data. index.Add(rect1, rect1.ToString() + "1"); index.Add(rect1, rect1.ToString() + "2"); index.Add(rect1, rect1.ToString() + "3"); index.Add(rect1, rect1.ToString() + "4"); index.Add(rect2, rect2.ToString() + "1"); index.Add(rect2, rect2.ToString() + "2"); index.Add(rect2, rect2.ToString() + "3"); index.Add(rect2, rect2.ToString() + "4"); index.Add(rect3, rect3.ToString() + "1"); index.Add(rect3, rect3.ToString() + "2"); index.Add(rect3, rect3.ToString() + "3"); index.Add(rect3, rect3.ToString() + "4"); index.Add(rect4, rect4.ToString() + "1"); index.Add(rect4, rect4.ToString() + "2"); index.Add(rect4, rect4.ToString() + "3"); index.Add(rect4, rect4.ToString() + "4"); index.Add(rect5, rect5.ToString()); // some simple queries. var result = new HashSet<string>( index.Get(rect4)); Assert.AreEqual(4, result.Count); Assert.IsTrue(result.Contains(rect4.ToString() + "1")); Assert.IsTrue(result.Contains(rect4.ToString() + "2")); Assert.IsTrue(result.Contains(rect4.ToString() + "3")); Assert.IsTrue(result.Contains(rect4.ToString() + "4")); result = new HashSet<string>( index.Get(rect3)); Assert.AreEqual(4, result.Count); Assert.IsTrue(result.Contains(rect3.ToString() + "1")); Assert.IsTrue(result.Contains(rect3.ToString() + "2")); Assert.IsTrue(result.Contains(rect3.ToString() + "3")); Assert.IsTrue(result.Contains(rect3.ToString() + "4")); result = new HashSet<string>( index.Get(rect2)); Assert.AreEqual(4, result.Count); Assert.IsTrue(result.Contains(rect2.ToString() + "1")); Assert.IsTrue(result.Contains(rect2.ToString() + "2")); Assert.IsTrue(result.Contains(rect2.ToString() + "3")); Assert.IsTrue(result.Contains(rect2.ToString() + "4")); result = new HashSet<string>( index.Get(rect1)); Assert.AreEqual(5, result.Count); Assert.IsTrue(result.Contains(rect1.ToString() + "1")); Assert.IsTrue(result.Contains(rect1.ToString() + "2")); Assert.IsTrue(result.Contains(rect1.ToString() + "3")); Assert.IsTrue(result.Contains(rect1.ToString() + "4")); Assert.IsTrue(result.Contains(rect5.ToString())); }
/// <summary> /// Returns true if this rectangle overlaps with the given box. /// </summary> /// <param name="box">Box.</param> public bool Overlaps(BoxF2D box) { // Yes, I know this code can be shorter but it would turn into a mess! if (box.Contains (this.BottomLeft) || box.Contains (this.BottomRight) || box.Contains (this.TopLeft) || box.Contains (this.TopRight)) { return true; } if (this.Contains (box.Corners [0]) || this.Contains (box.Corners [2]) || this.Contains (box.Corners [3]) || this.Contains (box.Corners [0])) { return true; } List<LineF2D> lines = new List<LineF2D> (); lines.Add(new LineF2D(this.BottomLeft, this.BottomRight, true)); lines.Add(new LineF2D(this.BottomRight, this.TopRight, true)); lines.Add(new LineF2D(this.TopRight, this.TopLeft, true)); lines.Add(new LineF2D(this.TopLeft, this.BottomLeft, true)); foreach (LineF2D line in (box as IEnumerable<LineF2D>)) { foreach (LineF2D otherLine in lines) { if (line.Intersects (otherLine)) { return true; } } } return false; }
/// <summary> /// Returns true if the given rectangle overlaps with this view. /// </summary> /// <returns><c>true</c>, if with rectangle overlaps, <c>false</c> otherwise.</returns> /// <param name="left">Left.</param> /// <param name="top">Top.</param> /// <param name="right">Right.</param> /// <param name="bottom">Bottom.</param> public bool OverlapsWithBox(double left, double top, double right, double bottom) { BoxF2D box = new BoxF2D (left, top, right, bottom); if (box.Overlaps (_rectangle.BoundingBox)) { return _rectangle.Overlaps (box); } return false; }