public void IntersectsWithLine() { Assert.IsTrue(rectD.IntersectsWith(new LineD(1, 2, 5, 7))); Assert.IsTrue(rectD.IntersectsWith(new LineD(3, 1, 3, 8))); Assert.IsTrue(rectD.IntersectsWith(new LineD(0, 4, 6, 4))); Assert.IsFalse(rectD.IntersectsWith(new LineD(0, 1, 0, 8))); Assert.IsFalse(rectD.IntersectsWith(new LineD(0, 1, 6, 1))); Assert.IsFalse(rectD.IntersectsWith(new LineD(-2, 3, 2, -3))); Assert.IsTrue(rectF.IntersectsWith(new LineF(1, 2, 5, 7))); Assert.IsTrue(rectF.IntersectsWith(new LineF(3, 1, 3, 8))); Assert.IsTrue(rectF.IntersectsWith(new LineF(0, 4, 6, 4))); Assert.IsFalse(rectF.IntersectsWith(new LineF(0, 1, 0, 8))); Assert.IsFalse(rectF.IntersectsWith(new LineF(0, 1, 6, 1))); Assert.IsFalse(rectF.IntersectsWith(new LineF(-2, 3, 2, -3))); }
/// <summary> /// Clips the edge list for the Delaunay triangulation to the specified bounds.</summary> /// <param name="bounds"> /// A <see cref="RectD"/> that indicates the clipping bounds for all <see /// cref="DelaunayEdges"/>.</param> /// <returns> /// An <see cref="Array"/> containing all <see cref="DelaunayEdges"/> which intersect the /// specified <paramref name="bounds"/>, as defined below.</returns> /// <remarks><para> /// <b>ClipDelaunayEdges</b> returns all <see cref="DelaunayEdges"/> whose corresponding /// <see cref="VoronoiEdges"/> element fulfils two conditions: /// </para><list type="bullet"><item> /// <see cref="VoronoiEdge.Site1"/> and <see cref="VoronoiEdge.Site2"/> both fall within the /// specified <paramref name="bounds"/>. /// </item><item> /// The line segment indicated by <see cref="VoronoiEdge.Vertex1"/> and <see /// cref="VoronoiEdge.Vertex2"/> intersects the specified <paramref name="bounds"/>. /// </item></list><para> /// In other words, <b>ClipDelaunayEdges</b> selects those <see cref="DelaunayEdges"/> that /// fall entirely within <paramref name="bounds"/>, and which connect two <see /// cref="VoronoiRegions"/> that share a common border within <paramref name="bounds"/>. /// </para></remarks> public LineD[] ClipDelaunayEdges(RectD bounds) { List <LineD> delaunayEdges = new List <LineD>(VoronoiEdges.Length); foreach (VoronoiEdge edge in VoronoiEdges) { PointD s1 = GeneratorSites[edge.Site1]; PointD s2 = GeneratorSites[edge.Site2]; if (bounds.Contains(s1) && bounds.Contains(s2)) { PointD v1 = VoronoiVertices[edge.Vertex1]; PointD v2 = VoronoiVertices[edge.Vertex2]; if (bounds.IntersectsWith(new LineD(v1, v2))) { delaunayEdges.Add(new LineD(s1, s2)); } } } return(delaunayEdges.ToArray()); }
/// <summary> /// Finds all key-and-value pairs within the specified key range that are stored in the <see /// cref="QuadTreeNode{TValue}"/> or its child nodes.</summary> /// <param name="range"> /// A <see cref="RectD"/> indicating the key range to search. This argument must intersect /// with <see cref="Bounds"/>, and it must be a square if <paramref name="useCircle"/> is /// <c>true</c>.</param> /// <param name="useCircle"> /// <c>true</c> to search only the circle inscribed within <paramref name="range"/>; /// <c>false</c> to search the entire <paramref name="range"/>.</param> /// <param name="output"> /// A <see cref="Dictionary{PointD, TValue}"/> to which any elements are added whose key /// lies within the specified <paramref name="range"/>.</param> internal void FindRange(ref RectD range, bool useCircle, Dictionary <PointD, TValue> output) { Debug.Assert(Bounds.IntersectsWith(range)); if (_data != null) { if (useCircle) { double radius = range.Width / 2; double x = range.X + radius, y = range.Y + radius; foreach (var pair in _data) { if (range.Contains(pair.Key)) { double dx = pair.Key.X - x, dy = pair.Key.Y - y; if (dx * dx + dy * dy <= radius * radius) { output.Add(pair.Key, pair.Value); } } } } else { foreach (var pair in _data) { if (range.Contains(pair.Key)) { output.Add(pair.Key, pair.Value); } } } return; } bool topRange = (range.Top < Center.Y); bool bottomRange = (range.Bottom >= Center.Y); bool leftRange = (range.Left < Center.X); bool rightRange = (range.Right >= Center.X); if (topRange) { if (leftRange && _topLeft != null) { _topLeft.FindRange(ref range, useCircle, output); } if (rightRange && _topRight != null) { _topRight.FindRange(ref range, useCircle, output); } } if (bottomRange) { if (leftRange && _bottomLeft != null) { _bottomLeft.FindRange(ref range, useCircle, output); } if (rightRange && _bottomRight != null) { _bottomRight.FindRange(ref range, useCircle, output); } } }