Exemple #1
0
 /// <summary>
 ///   Checks whether the specified circle intersects the passed line.
 /// </summary>
 /// <param name="circle">
 ///   Circle to check.
 /// </param>
 /// <param name="line">
 ///   Line to check.
 /// </param>
 /// <param name="first">
 ///   First intersection point, if found.
 /// </param>
 /// <param name="second">
 ///   Second intersection point, if found.
 /// </param>
 /// <returns>
 ///   <c>true</c>, if circle and line intersect each other, and <c>false</c> otherwise.
 /// </returns>
 public static bool Intersects(
     this CircleF circle,
     LineSegment2F line,
     out Vector2F?first,
     out Vector2F?second)
 {
     return(line.Intersects(circle, out first, out second));
 }
Exemple #2
0
        /// <summary>
        ///   Checks whether this polygon fully contains the passed line segment.
        /// </summary>
        /// <param name="lineSegment">Line segment to check.</param>
        /// <returns>
        ///   <c>true</c>, if this polygon fully contains <paramref name="lineSegment" />, and
        ///   <c>false</c> otherwise.
        /// </returns>
        public bool Contains(LineSegment2F lineSegment)
        {
            // Check whether any of the edges intersect with the line.
            if (this.Edges.Any(edge => lineSegment.Intersects(edge)))
            {
                return(false);
            }

            // Check whether the line endpoints are inside the polygon.
            return(this.Contains(lineSegment.P) && this.Contains(lineSegment.Q));
        }
Exemple #3
0
        /// <summary>
        ///   Checks whether the specified line intersects the passed circle.
        /// </summary>
        /// <remarks>
        ///   See http://devmag.org.za/2009/04/17/basic-collision-detection-in-2d-part-2/ for details.
        /// </remarks>
        /// <param name="line">
        ///   Line to check.
        /// </param>
        /// <param name="circle">
        ///   Circle to check.
        /// </param>
        /// <param name="first">
        ///   First intersection point, if found.
        /// </param>
        /// <param name="second">
        ///   Second intersection point, if found.
        /// </param>
        /// <returns>
        ///   <c>true</c>, if line and circle intersect each other, and <c>false</c> otherwise.
        /// </returns>
        public static bool Intersects(
            this LineSegment2F line,
            CircleF circle,
            out Vector2F?first,
            out Vector2F?second)
        {
            // Transform to local coordinates.
            var localPointA = line.P - circle.Center;
            var localPointB = line.Q - circle.Center;

            // Precalculate this value. We use it often.
            var localPointBMinusA = localPointB - localPointA;

            var a     = (localPointBMinusA.X) * (localPointBMinusA.X) + (localPointBMinusA.Y) * (localPointBMinusA.Y);
            var b     = 2 * ((localPointBMinusA.X * localPointA.X) + (localPointBMinusA.Y * localPointA.Y));
            var c     = (localPointA.X * localPointA.X) + (localPointA.Y * localPointA.Y) - (circle.Radius * circle.Radius);
            var delta = b * b - (4 * a * c);

            if (delta < 0)
            {
                // No intersection.
                first  = null;
                second = null;
                return(false);
            }

            if (delta > 0)
            {
                // Two intersections.
                var squareRootDelta = MathF.Sqrt(delta);

                var u1 = (-b + squareRootDelta) / (2 * a);
                var u2 = (-b - squareRootDelta) / (2 * a);

                // Use line point instead of local point because we want our answer in global space, not the circle's local space.
                first  = line.P + (u1 * localPointBMinusA);
                second = line.P + (u2 * localPointBMinusA);
                return(true);
            }

            // One intersection.
            var u = -b / (2 * a);

            first  = line.P + (u * localPointBMinusA);
            second = null;
            return(true);
        }
        /// <summary>
        ///   Checks whether the specified rectangle intersects the passed circle.
        /// </summary>
        /// <param name="rectangle">
        ///   Rectangle to check.
        /// </param>
        /// <param name="circle">
        ///   Circle to check.
        /// </param>
        /// <returns>
        ///   <c>true</c>, if rectangle and circle intersect each other, and <c>false</c> otherwise.
        /// </returns>
        public static bool Intersects(this RectangleF rectangle, CircleF circle)
        {
            // Check if rectangle contains center.
            if (rectangle.Contains(circle.Center))
            {
                return(true);
            }

            // Check each edge.
            var topLeft     = new Vector2F(rectangle.X, rectangle.Y);
            var bottomLeft  = new Vector2F(rectangle.X, rectangle.MaxY);
            var topRight    = new Vector2F(rectangle.MaxX, rectangle.Y);
            var bottomRight = new Vector2F(rectangle.MaxX, rectangle.MaxY);

            var left   = new LineSegment2F(topLeft, bottomLeft);
            var right  = new LineSegment2F(topRight, bottomRight);
            var top    = new LineSegment2F(topLeft, topRight);
            var bottom = new LineSegment2F(bottomLeft, bottomRight);

            return(left.Intersects(circle) || right.Intersects(circle) || top.Intersects(circle) ||
                   bottom.Intersects(circle));
        }
Exemple #5
0
        /// <summary>
        ///   Constructs a new polygon with the specified points.
        /// </summary>
        /// <param name="points">Points making up the new polygon.</param>
        /// <exception cref="ArgumentNullException">
        ///   <paramref name="points"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///   <paramref name="points"/> contains two or less elements.
        /// </exception>
        public Polygon2F(IList <Vector2F> points)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            if (points.Count < 3)
            {
                throw new ArgumentException("Polygon must consist of at least three points.", "points");
            }

            this.points = points;

            // Build edges.
            this.edges = new List <LineSegment2F>();

            for (var i = 0; i < this.points.Count; i++)
            {
                var edge = new LineSegment2F(this.points[i], this.points[(i + 1) % this.points.Count]);
                this.edges.Add(edge);
            }
        }
Exemple #6
0
 /// <summary>
 ///   Checks whether the specified line intersects the passed circle.
 /// </summary>
 /// <param name="line">
 ///   Line to check.
 /// </param>
 /// <param name="circle">
 ///   Circle to check.
 /// </param>
 /// <returns>
 ///   <c>true</c>, if line and circle intersect each other, and <c>false</c> otherwise.
 /// </returns>
 public static bool Intersects(this LineSegment2F line, CircleF circle)
 {
     return(line.GetDistance(circle.Center) < circle.Radius);
 }
Exemple #7
0
        /// <summary>
        ///   Decomposes this polygon into triangles.
        /// </summary>
        /// <remarks>
        ///   See http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf for details.
        /// </remarks>
        /// <returns>Triangles composing this polygon.</returns>
        public List <Polygon2F> Triangulate()
        {
            var triangles = new List <Polygon2F>();
            var vertices  = new List <Vector2F>(this.points);

            if (this.IsClockwise())
            {
                vertices.Reverse();
            }

            // Remove ears one by one.
            var index = 0;

            while (vertices.Count > 3)
            {
                var remainingPolygon = new Polygon2F(vertices);

                // Get three consecutive vertices.
                var u = vertices[(index - 1 + vertices.Count) % vertices.Count];
                var v = vertices[index % vertices.Count];
                var w = vertices[(index + 1) % vertices.Count];

                // Check if middle vertex is convex.
                var vu = u - v;
                var vw = w - v;

                var angle  = Angle.Between(vw, vu);
                var convex = angle < Math.PI;

                if (!convex)
                {
                    ++index;
                    continue;
                }

                // Check if line segment lies completely inside the polygon.
                var uw = new LineSegment2F(u, w);

                if (!remainingPolygon.Contains(uw))
                {
                    ++index;
                    continue;
                }

                // Check if no other vertices of the polygon are contained in the triangle.
                var triangle =
                    new Polygon2F(new[] { new Vector2F(u.X, u.Y), new Vector2F(v.X, v.Y), new Vector2F(w.X, w.Y) });

                var containsOtherVertex =
                    vertices.Where(other => other != u && other != v && other != w)
                    .Any(other => triangle.Contains(other));

                if (containsOtherVertex)
                {
                    ++index;
                    continue;
                }

                // Remove ear.
                vertices.Remove(v);
                triangles.Add(triangle);
            }

            // Add last triangle.
            triangles.Add(new Polygon2F(vertices));
            return(triangles);
        }
Exemple #8
0
 /// <summary>
 ///   Checks whether the specified circle intersects the passed line.
 /// </summary>
 /// <param name="circle">
 ///   Circle to check.
 /// </param>
 /// <param name="line">
 ///   Line to check.
 /// </param>
 /// <returns>
 ///   <c>true</c>, if circle and line intersect each other, and <c>false</c> otherwise.
 /// </returns>
 public static bool Intersects(this CircleF circle, LineSegment2F line)
 {
     return(line.Intersects(circle));
 }