/// <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)); }
/// <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)); }
/// <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)); }
/// <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); } }
/// <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); }
/// <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); }
/// <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)); }