private bool InterceptWithCircle(Circle2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var middlepointDistance = LineSegment2.CalcLenght(this.MiddlePoint, other.MiddlePoint); var radiusSum = this.Radius + other.Radius; return(!(middlepointDistance > (radiusSum + tolerance))); }
/// <summary> /// Checks if the given 4 vertices form a rectangle /// </summary> /// <param name="vertices"></param> /// <returns></returns> public static bool IsRectangle(Vector2[] vertices, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { if (vertices == null) { throw new ArgumentNullException("vertices"); } if (vertices.Count() != 4) { throw new ArgumentException("You must submit 4 vertices!"); } var topLine = new LineSegment2(vertices[0], vertices[1]).ToVector(); var rightLine = new LineSegment2(vertices[1], vertices[2]).ToVector(); var bottomLine = new LineSegment2(vertices[2], vertices[3]).ToVector(); var leftLine = new LineSegment2(vertices[3], vertices[0]).ToVector(); // Check that two lines have equal length if (Math.Abs(topLine.Length - bottomLine.Length) < tolerance && Math.Abs(rightLine.Length - leftLine.Length) < tolerance) { // Now ensure that the lines are orthogonal on each other bool isRect = topLine.IsPerpendicularTo(rightLine, tolerance); isRect &= rightLine.IsPerpendicularTo(bottomLine, tolerance); isRect &= bottomLine.IsPerpendicularTo(leftLine, tolerance); return(isRect); } return(false); }
/// <summary> /// Arc-Line Interception /// </summary> /// <param name="uLine">Line to check</param> /// <param name="tolerance"></param> /// <returns>Returns the interception Point(s) if the Objects collide</returns> private List <Vector2> InterceptLine(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List <Vector2>(); // Stretch the line on both ends by tolerance // TODO Is this still necessary?? var strechtedLine = (uLine.Clone() as LineSegment2); strechtedLine.Stretch(tolerance, Direction.LEFT); strechtedLine.Stretch(tolerance, Direction.RIGHT); uLine = strechtedLine; // Intersect with a circle and test inter points if they lie on our arc var circle = new Circle2(this.MiddlePoint, this.Radius); foreach (var possiblePnt in circle.Intersect(uLine, tolerance)) { if (this.Contains(possiblePnt, tolerance)) { intersections.Add(possiblePnt); } } return(intersections); }
/// <summary> /// Checks if a Point lies in a circle /// (This is a strictly static method for performance reasons) /// </summary> /// <param name="middlePoint"></param> /// <param name="radius"></param> /// <param name="checkPoint"></param> /// <param name="tolerance"></param> /// <returns></returns> public static bool Contains(Vector2 middlePoint, double radius, Vector2 checkPoint, double tolerance) { var len = LineSegment2.CalcLenght(middlePoint, checkPoint); var dist = radius - (len - tolerance); return(dist >= 0); }
/// <summary> /// Calculates the interception point of two Lines. /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns>Returns a Point if func succeeds. If there is no interception, empty point is returned.</returns> public Vector2? IntersectLine(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { double interPntX = 0; double interPntY = 0; if (other == null || this.IsParallelTo(other, tolerance)) { return null; // Lines are parralell } //intercept of two endless lines if (!this.IsVertical && !other.IsVertical) { // both NOT vertical interPntX = ((-1 * (this.YMovement - other.YMovement)) / (this.Slope - other.Slope)); interPntY = (this.Slope * interPntX + this.YMovement); } else if (this.IsVertical) { // this vertical (so it must lie on this.X) interPntX = this.Start.X; interPntY = (other.Slope * interPntX + other.YMovement); } else if (other.IsVertical) { // Line2 vertical (so it must lie on Line2.X) interPntX = other.Start.X; interPntY = (this.Slope * interPntX + this.YMovement); } var interPnt = new Vector2(interPntX, interPntY); //check if computed intercept lies on our line. if (this.Contains(interPnt, tolerance) && other.Contains(interPnt, tolerance)) { return interPnt; }else return null; }
public static VisualLine Create(LineSegment2 line, Pen pen = null) { return new VisualLine(line) { Pen = pen }; }
public void Slope(string sp, string ep, double expected) { var spv = Vector2.Parse(sp); var epv = Vector2.Parse(ep); var l1 = new LineSegment2(spv, epv); Assert.AreEqual(expected, l1.Slope); }
public void Lenght(string sp, string ep, double expected) { var spv = Vector2.Parse(sp); var epv = Vector2.Parse(ep); var l1 = new LineSegment2(spv, epv); Assert.AreEqual(l1.Length, expected); }
/// <summary> /// Checks if a Rectangle collides with the Arc. /// </summary> /// <param name="rect">Rectangle to check</param> /// <returns>On collision, true is returned, false otherwise</returns> private bool InterceptRectWith(AARectangle rect, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var borderLines = LineSegment2.FromRectangle(rect); //get 4 borderlines from rect if (borderLines != null) { return(InterceptLinesWith(borderLines, tolerance)); } return(false); }
public void Constructor(string sp, string ep) { var spv = Vector2.Parse(sp); var epv = Vector2.Parse(ep); var l1 = new LineSegment2(spv, epv); Assert.AreEqual(l1.Start, spv); Assert.AreEqual(l1.End, epv); }
/// <summary>Checks if a Rectangle collides with the Arc. /// /// </summary> /// <param name="rect">Rectangle to check</param> /// <returns>On collision, a List of interception Points is returned</returns> private List <Vector2> InterceptRect(AARectangle rect, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List <Vector2>(); var borderLines = LineSegment2.FromRectangle(rect); //get 4 borderlines from rect if (borderLines != null) { intersections.AddRange(InterceptLines(borderLines, tolerance)); } return(intersections); }
/// <summary> /// Polygon - Line intersection /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns></returns> private IEnumerable <Vector2> InterceptLine(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List <Vector2>(); var thisLines = ToLines(); foreach (var line in thisLines) { var intersection = other.Intersect(line); intersections.AddRange(intersection); } return(intersections); }
private bool HasCollision(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { // Test each line if it has a collision var lines = ToLines(); foreach (var line in lines) { if (other.HasCollision(line, tolerance)) { return(true); // We have a collision and can stop } } return(false); }
/// <summary> /// Gets all border lines of this polygon including the closing line /// </summary> /// <returns></returns> public LineSegment2[] ToLines() { var lines = new LineSegment2[_vertices.Count]; if (_vertices.Count > 1) { for (int i = 0; i < _vertices.Count; i++) { lines[i] = new LineSegment2( _vertices[i], _vertices[(i + 1) % _vertices.Count] // next vertex, cycle on end to the beginning ); } } return(lines); }
public void ToLinesTest() { var rect = new RectangleAA2(new Vector2(10,10), new SizeD(20,20)); var lines = rect.ToLines(); var bottom = new LineSegment2(new Vector2(10, 10), new Vector2(30, 10)); var top = new LineSegment2(new Vector2(30, 30), new Vector2(10, 30)); var right = new LineSegment2(new Vector2(30, 10), new Vector2(30, 30)); var left = new LineSegment2(new Vector2(10, 30), new Vector2(10, 10)); Assert.True((from l in lines where l.Equals(bottom) select l).Any()); Assert.True((from l in lines where l.Equals(top) select l).Any()); Assert.True((from l in lines where l.Equals(right) select l).Any()); Assert.True((from l in lines where l.Equals(left) select l).Any()); }
/// <summary> /// Checks if this line segment properly intresects another line semgent. /// The intersection between two line segments is considered proper if they intersect in a single point in the interior of both segments (e.g. the intersection is a single point and is not equal to any of the endpoints). /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns></returns> public bool IsIntersectionProper(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { // If the lines are parallel, there cant be a proper intersection if (this.IsParallelTo(other, tolerance)) return false; var intersectionPoint = IntersectLine(other, tolerance); if (intersectionPoint.HasValue) { // This intersection point must now lie on the interior of both lines, i.e. not on any endpoint of both lines. var point = intersectionPoint.Value; if (this.Start.Equals(point, tolerance) || this.End.Equals(point, tolerance) || other.Start.Equals(point, tolerance) || other.End.Equals(point, tolerance)) { return false; // The intersection is on the line start/end point - thus they only meet. } return true; } return false; }
/// <summary> /// Does a Point lie on the Arc line? /// </summary> /// <param name="point"></param> /// <param name="tolerance"></param> /// <returns></returns> public bool Contains(Vector2 point, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { bool conatins = false; // First, the distance from middlepoint to our Point must be equal to the radius: var distance = LineSegment2.CalcLenght(this.MiddlePoint, point); if (Math.Abs(distance - this.Radius) < tolerance) { // If this is true, we only need to check if we are in the arc angle var bowMiddle = this.GetPointOnArc(this.Angle / 2); var l1 = new LineSegment2(this.Location, bowMiddle); var l2 = new LineSegment2(this.GetPointOnArc(this.Angle), bowMiddle); var intersection = new LineSegment2(this.MiddlePoint, point); conatins = intersection.IntersectLine(l1, tolerance).HasValue || intersection.IntersectLine(l2, tolerance).HasValue; } return(conatins); }
private IEnumerable <Vector2> InterceptCircle(Circle2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var interceptions = new List <Vector2>(); if (InterceptWithCircle(other, tolerance)) { var middlepointDistance = LineSegment2.CalcLenght(this.MiddlePoint, other.MiddlePoint); if (middlepointDistance < Math.Abs(this.Radius + other.Radius)) { // circle is contained in other } else if (middlepointDistance == 0 && (this.Radius == other.Radius)) { // circle are concident -> infinite numbers of intersections } else { interceptions.AddRange(IntersectCircle(this, other)); } } return(interceptions); }
/// <summary> /// Calculates the interception point of two Lines. /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns>Returns a Point if func succeeds. If there is no interception, empty point is returned.</returns> public Vector2?IntersectLine(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { double interPntX = 0; double interPntY = 0; if (other == null || this.IsParallelTo(other, tolerance)) { return(null); // Lines are parralell } //intercept of two endless lines if (!this.IsVertical && !other.IsVertical) // both NOT vertical { interPntX = ((-1 * (this.YMovement - other.YMovement)) / (this.Slope - other.Slope)); interPntY = (this.Slope * interPntX + this.YMovement); } else if (this.IsVertical) // this vertical (so it must lie on this.X) { interPntX = this.Start.X; interPntY = (other.Slope * interPntX + other.YMovement); } else if (other.IsVertical) // Line2 vertical (so it must lie on Line2.X) { interPntX = other.Start.X; interPntY = (this.Slope * interPntX + this.YMovement); } var interPnt = new Vector2(interPntX, interPntY); //check if computed intercept lies on our line. if (this.Contains(interPnt, tolerance) && other.Contains(interPnt, tolerance)) { return(interPnt); } else { return(null); } }
/// <summary> /// Checks if this line segment properly intresects another line semgent. /// The intersection between two line segments is considered proper if they intersect in a single point in the interior of both segments (e.g. the intersection is a single point and is not equal to any of the endpoints). /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns></returns> public bool IsIntersectionProper(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { // If the lines are parallel, there cant be a proper intersection if (this.IsParallelTo(other, tolerance)) { return(false); } var intersectionPoint = IntersectLine(other, tolerance); if (intersectionPoint.HasValue) { // This intersection point must now lie on the interior of both lines, i.e. not on any endpoint of both lines. var point = intersectionPoint.Value; if (this.Start.Equals(point, tolerance) || this.End.Equals(point, tolerance) || other.Start.Equals(point, tolerance) || other.End.Equals(point, tolerance)) { return(false); // The intersection is on the line start/end point - thus they only meet. } return(true); } return(false); }
public LineSegment2[] ToLines() { return(LineSegment2.FromRectangle(ToAARectangle())); }
/// <summary> /// Circle-Line Interception /// </summary> /// <param name="uLine"></param> /// <returns>Returns all intersection points</returns> private List <Vector2> InterceptLine(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List <Vector2>(); Vector2 p1, p2; var location = this.Location; // we assume that the circle Middlepoint is NULL/NULL // So we move the Line with the delta to NULL var helperLine = new LineSegment2(uLine.Start - location, uLine.End - location); // line var q = helperLine.YMovement; var m = helperLine.Slope; if (!helperLine.IsVertical) { // The slope is defined as the Line isn't vertical var discriminant = (Math.Pow(m, 2) + 1) * Math.Pow(this.Radius, 2) - Math.Pow(q, 2); if (discriminant > 0) { // only positive discriminants for f() -> sqrt(discriminant) results are defined in |R var p1X = (Math.Sqrt(discriminant) - m * (q)) / (Math.Pow(m, 2) + 1); var p1Y = m * p1X + q; var p2X = (-1 * (Math.Sqrt(discriminant) + m * q)) / (Math.Pow(m, 2) + 1); var p2Y = m * p2X + q; p1 = new Vector2(p1X, p1Y); p2 = new Vector2(p2X, p2Y); if (helperLine.Contains(p1, tolerance)) { intersections.Add(p1 + location); } if ((p1.X != p2.X) || (p1.Y != p2.Y)) { if (helperLine.Contains(p2, tolerance)) { intersections.Add(p2 + location); } } } } else { // undefined slope, so we have to deal with it directly var p1X = this.Location.X + helperLine.Start.X; var p1Y = Math.Sqrt(Math.Pow(this.Radius, 2) - Math.Pow(p1X, 2)); p1 = new Vector2(p1X, p1Y); p2 = new Vector2(p1.X, -p1.Y); if (helperLine.Contains(p1, tolerance)) { intersections.Add(p1 + location); } if (helperLine.Contains(p2, tolerance)) { intersections.Add(p2 + location); } } return(intersections); }
/// <summary> /// Does a Point lie on the Arc line? /// </summary> /// <param name="point"></param> /// <param name="tolerance"></param> /// <returns></returns> public bool Contains(Vector2 point, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { bool conatins = false; // First, the distance from middlepoint to our Point must be equal to the radius: var distance = LineSegment2.CalcLenght(this.MiddlePoint, point); if (Math.Abs(distance - this.Radius) < tolerance) { // If this is true, we only need to check if we are in the arc angle var bowMiddle = this.GetPointOnArc(this.Angle/2); var l1 = new LineSegment2(this.Location, bowMiddle); var l2 = new LineSegment2(this.GetPointOnArc(this.Angle), bowMiddle); var intersection = new LineSegment2(this.MiddlePoint, point); conatins = intersection.IntersectLine(l1, tolerance).HasValue || intersection.IntersectLine(l2, tolerance).HasValue; } return conatins; }
/// <summary> /// Arc-Line Interception /// </summary> /// <param name="uLine">Line to check</param> /// <param name="tolerance"></param> /// <returns>Returns the interception Point(s) if the Objects collide</returns> private List<Vector2> InterceptLine(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List<Vector2>(); // Stretch the line on both ends by tolerance // TODO Is this still necessary?? var strechtedLine = (uLine.Clone() as LineSegment2); strechtedLine.Stretch(tolerance, Direction.LEFT); strechtedLine.Stretch(tolerance, Direction.RIGHT); uLine = strechtedLine; // Intersect with a circle and test inter points if they lie on our arc var circle = new Circle2(this.MiddlePoint, this.Radius); foreach (var possiblePnt in circle.Intersect(uLine, tolerance)) { if (this.Contains(possiblePnt, tolerance)) { intersections.Add(possiblePnt); } } return intersections; }
public void IsVertical(string sp, string ep, bool expected) { var spv = Vector2.Parse(sp); var epv = Vector2.Parse(ep); var l1 = new LineSegment2(spv, epv); Assert.AreEqual(expected, l1.IsVertical); }
/// <summary> /// Arc - Line Collision /// </summary> /// <param name="uLine">Line to check</param> /// <returns>Returns true, if the objects collide, false otherwise</returns> private bool InterceptLineWith(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { return InterceptLine(uLine, tolerance).Any(); }
/// <summary>Circle-Line Interception /// Does the Line intercept with the Circle? /// </summary> /// <param name="uLine"></param> /// <returns></returns> private bool InterceptLineWith(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = InterceptLine(uLine, tolerance); return(intersections.Any()); }
/// <summary> /// Returns a signed angle /// </summary> /// <param name="direction"></param> /// <param name="next"></param> /// <returns></returns> public static Angle GetSignedAngleBetween(LineSegment2 direction, Vector2 next) { var angle = next.GetAngleTo(direction.ToVector()); return angle * (direction.IsLeft(next) ? 1 : -1); }
/// <summary> /// Gets all border lines of this polygon including the closing line /// </summary> /// <returns></returns> public LineSegment2[] ToLines() { var lines = new LineSegment2[_vertices.Count]; if(_vertices.Count > 1) { for (int i = 0; i < _vertices.Count; i++) { lines[i] = new LineSegment2( _vertices[i], _vertices[(i + 1) % _vertices.Count] // next vertex, cycle on end to the beginning ); } } return lines; }
/// <summary> /// Returns true if one of the given lines intersects with this polygons border lines. /// </summary> /// <param name="otherLines"></param> /// <param name="tolerance"></param> /// <returns></returns> private bool HasIntersection(LineSegment2[] otherLines, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var myLines = this.ToLines(); foreach (var myLine in myLines) { foreach (var other in otherLines) { if (myLine.IntersectLine(other, tolerance).HasValue) return true; } } return false; }
/// <summary>Circle-Line Interception /// Does the Line intercept with the Circle? /// </summary> /// <param name="uLine"></param> /// <returns></returns> private bool InterceptLineWith(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = InterceptLine(uLine, tolerance); return intersections.Any(); }
/// <summary> /// Circle-Line Interception /// </summary> /// <param name="uLine"></param> /// <returns>Returns all intersection points</returns> private List<Vector2> InterceptLine(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List<Vector2>(); Vector2 p1, p2; var location = this.Location; // we assume that the circle Middlepoint is NULL/NULL // So we move the Line with the delta to NULL var helperLine = new LineSegment2(uLine.Start - location, uLine.End - location); // line var q = helperLine.YMovement; var m = helperLine.Slope; if (!helperLine.IsVertical) { // The slope is defined as the Line isn't vertical var discriminant = (Math.Pow(m, 2) + 1) * Math.Pow(this.Radius, 2) - Math.Pow(q, 2); if (discriminant > 0) { // only positive discriminants for f() -> sqrt(discriminant) results are defined in |R var p1X = (Math.Sqrt(discriminant) - m * (q)) / (Math.Pow(m, 2) + 1); var p1Y = m * p1X + q; var p2X = (-1 * (Math.Sqrt(discriminant) + m * q)) / (Math.Pow(m, 2) + 1); var p2Y = m * p2X + q; p1 = new Vector2(p1X, p1Y); p2 = new Vector2(p2X, p2Y); if (helperLine.Contains(p1, tolerance)) { intersections.Add(p1 + location); } if ((p1.X != p2.X) || (p1.Y != p2.Y)) { if (helperLine.Contains(p2, tolerance)) { intersections.Add(p2 + location); } } } } else { // undefined slope, so we have to deal with it directly var p1X = this.Location.X + helperLine.Start.X; var p1Y = Math.Sqrt(Math.Pow(this.Radius, 2) - Math.Pow(p1X, 2)); p1 = new Vector2(p1X, p1Y); p2 = new Vector2(p1.X, -p1.Y); if (helperLine.Contains(p1, tolerance)) { intersections.Add(p1 + location); } if (helperLine.Contains(p2, tolerance)) { intersections.Add(p2 + location); } } return intersections; }
/// <summary> /// Polygon - Line intersection /// </summary> /// <param name="other"></param> /// <param name="tolerance"></param> /// <returns></returns> private IEnumerable<Vector2> InterceptLine(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { var intersections = new List<Vector2>(); var thisLines = ToLines(); foreach (var line in thisLines) { var intersection = other.Intersect(line); intersections.AddRange(intersection); } return intersections; }
/// <summary> /// Checks if the given 4 vertices form a rectangle /// </summary> /// <param name="vertices"></param> /// <returns></returns> public static bool IsRectangle(Vector2[] vertices, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { if (vertices == null) throw new ArgumentNullException("vertices"); if (vertices.Count() != 4) throw new ArgumentException("You must submit 4 vertices!"); var topLine = new LineSegment2(vertices[0], vertices[1]).ToVector(); var rightLine = new LineSegment2(vertices[1], vertices[2]).ToVector(); var bottomLine = new LineSegment2(vertices[2], vertices[3]).ToVector(); var leftLine = new LineSegment2(vertices[3], vertices[0]).ToVector(); // Check that two lines have equal length if (Math.Abs(topLine.Length - bottomLine.Length) < tolerance && Math.Abs(rightLine.Length - leftLine.Length) < tolerance) { // Now ensure that the lines are orthogonal on each other bool isRect = topLine.IsPerpendicularTo(rightLine, tolerance); isRect &= rightLine.IsPerpendicularTo(bottomLine, tolerance); isRect &= bottomLine.IsPerpendicularTo(leftLine, tolerance); return isRect; } return false; }
private bool HasCollision(LineSegment2 other, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { // Test each line if it has a collision var lines = ToLines(); foreach (var line in lines) { if (other.HasCollision(line, tolerance)) { return true; // We have a collision and can stop } } return false; }
/// <summary> /// Arc - Line Collision /// </summary> /// <param name="uLine">Line to check</param> /// <returns>Returns true, if the objects collide, false otherwise</returns> private bool InterceptLineWith(LineSegment2 uLine, double tolerance = GeometrySettings.DEFAULT_TOLERANCE) { return(InterceptLine(uLine, tolerance).Any()); }
public VisualLine(LineSegment2 line) { _line = line; }