Пример #1
0
        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)));
        }
Пример #2
0
        /// <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());
        }
Пример #3
0
        /// <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);
                }
            }
        }