// http://stackoverflow.com/a/100165/925777 public static bool Intersects(Segment2D segment, RectangleF rectangle) { float minX = Math.Min(segment.Start.X, segment.End.X); float maxX = Math.Max(segment.Start.X, segment.End.X); if (maxX > rectangle.Right) { maxX = rectangle.Right; } if (minX < rectangle.Left) { minX = rectangle.Left; } if (minX > maxX) { return false; } float minY = Math.Min(segment.Start.Y, segment.End.Y); float maxY = Math.Max(segment.Start.Y, segment.End.Y); float dx = segment.End.X - segment.Start.X; if (Math.Abs(dx) > 0.0000001f) { float a = (segment.End.Y - segment.Start.Y) / dx; float b = segment.Start.Y - a * segment.Start.X; minY = a * minX + b; maxY = a * maxX + b; } if (minY > maxY) { float tmp = maxY; maxY = minY; minY = tmp; } if (maxY > rectangle.Bottom) { maxY = rectangle.Bottom; } if (minY < rectangle.Top) { minY = rectangle.Top; } if (minY > maxY) { return false; } return true; }
public static float MinimumDistance(Segment2D segment, Vector2 point) { Vector2 minimumDistancePoint; return Segment2D.MinimumDistance(segment, point, out minimumDistancePoint); }
public static bool Intersects(Segment2D segment1, Segment2D segment2) { Vector2 intersectionPoint; return Segment2D.Intersects(segment1, segment2, out intersectionPoint); }
public static bool Intersects(Segment2D segment1, Segment2D segment2, out Vector2 intersectionPoint) { /* const float Epsilon = 0.00001f; Vector2 cmp = new Vector2(segment2.Start.X - segment1.Start.X, segment2.Start.Y - segment1.Start.Y); Vector2 r = new Vector2(segment1.End.X - segment1.Start.X, segment1.End.Y - segment1.Start.Y); Vector2 s = new Vector2(segment2.End.X - segment2.Start.X, segment2.End.Y - segment2.Start.Y); float cmPxR = cmp.X * r.Y - cmp.Y * r.X; float cmPxS = cmp.X * s.Y - cmp.Y * s.X; float RxS = r.X * s.Y - r.Y * s.X; if (Math.Abs(cmPxR) < Epsilon) { intersectionPoint = Vector2.Zero; return true; } if (Math.Abs(RxS) < Epsilon) { intersectionPoint = default(Vector2); return false; } float rXsR = 1f / RxS; float t = cmPxS * rXsR; float u = cmPxR * rXsR; if (t >= 0f && t <= 1f && u >= 0f && u <= 1f) { intersectionPoint = segment1.Start + r * t; return true; } intersectionPoint = default(Vector2); return false; */ const float Epsilon = 0.00001f; float ua = (segment2.End.X - segment2.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment2.End.Y - segment2.Start.Y) * (segment1.Start.X - segment2.Start.X); float ub = (segment1.End.X - segment1.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment1.End.Y - segment1.Start.Y) * (segment1.Start.X - segment2.Start.X); float denominator = (segment2.End.Y - segment2.Start.Y) * (segment1.End.X - segment1.Start.X) - (segment2.End.X - segment2.Start.X) * (segment1.End.Y - segment1.Start.Y); if (Math.Abs(denominator) <= Epsilon) { if (Math.Abs(ua) <= Epsilon && Math.Abs(ub) <= Epsilon) { intersectionPoint = (segment1.Start + segment1.End + segment2.Start + segment2.End) / 4f; return true; } } else { ua /= denominator; ub /= denominator; if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) { intersectionPoint = new Vector2 { X = segment1.Start.X + ua * (segment1.End.X - segment1.Start.X), Y = segment1.Start.Y + ua * (segment1.End.Y - segment1.Start.Y) }; return true; } } intersectionPoint = default(Vector2); return false; }
public static Segment2D Clamp(Segment2D segment, RectangleF area) { segment.Start = Vector2.Clamp(segment.Start, area.TopLeft, area.BottomRight); segment.End = Vector2.Clamp(segment.End, area.TopLeft, area.BottomRight); return segment; }
public static bool Intersects(Segment2D segment, Circle circle) { return(Segment2D.MinimumDistance(segment, circle.Position) < circle.Radius); }
// public static float MinimumDistance(Segment2D segment, RectangleF rectangle, out Vector2 minimumDistancePoint) // is this correct? i guess so... public static float MaximumDistance(Segment2D segment, Vector2 point) { return(Math.Max(Vector2.Distance(segment.Start, point), Vector2.Distance(segment.End, point))); }
// public static float MinimumDistance(Segment2D segment, RectangleF rectangle, out Vector2 minimumDistancePoint) // is this correct? i guess so... public static float MaximumDistance(Segment2D segment, Vector2 point) { return Math.Max(Vector2.Distance(segment.Start, point), Vector2.Distance(segment.End, point)); }
// http://stackoverflow.com/a/100165/925777 public static bool Intersects(Segment2D segment, RectangleF rectangle) { return(Segment2D.Intersects(segment, rectangle.LeftSegment) || Segment2D.Intersects(segment, rectangle.TopSegment) || Segment2D.Intersects(segment, rectangle.RightSegment) || Segment2D.Intersects(segment, rectangle.BottomSegment) || (rectangle.Contains(segment.Start) && rectangle.Contains(segment.End))); float minX = Math.Min(segment.Start.X, segment.End.X); float maxX = Math.Max(segment.Start.X, segment.End.X); if (maxX > rectangle.Right) { maxX = rectangle.Right; } if (minX < rectangle.Left) { minX = rectangle.Left; } if (minX > maxX) { return(false); } float minY = Math.Min(segment.Start.Y, segment.End.Y); float maxY = Math.Max(segment.Start.Y, segment.End.Y); float dx = segment.End.X - segment.Start.X; if (Math.Abs(dx) > 0.0000001f) { float a = (segment.End.Y - segment.Start.Y) / dx; float b = segment.Start.Y - a * segment.Start.X; minY = a * minX + b; maxY = a * maxX + b; } if (minY > maxY) { float tmp = maxY; maxY = minY; minY = tmp; } if (maxY > rectangle.Bottom) { maxY = rectangle.Bottom; } if (minY < rectangle.Top) { minY = rectangle.Top; } if (minY > maxY) { return(false); } return(true); }
public static float MinimumDistance(Segment2D segment, Vector2f point) { Vector2f minimumDistancePoint; return(Segment2D.MinimumDistance(segment, point, out minimumDistancePoint)); }
public static bool Intersects(Segment2D segment1, Segment2D segment2, out Vector2f intersectionPoint) { /* const float Epsilon = 0.00001f; * * Vector2 cmp = new Vector2(segment2.Start.X - segment1.Start.X, segment2.Start.Y - segment1.Start.Y); * Vector2 rectangle = new Vector2(segment1.End.X - segment1.Start.X, segment1.End.Y - segment1.Start.Y); * Vector2 s = new Vector2(segment2.End.X - segment2.Start.X, segment2.End.Y - segment2.Start.Y); * * float cmPxR = cmp.X * rectangle.Y - cmp.Y * rectangle.X; * float cmPxS = cmp.X * s.Y - cmp.Y * s.X; * float RxS = rectangle.X * s.Y - rectangle.Y * s.X; * * if (Math.Abs(cmPxR) < Epsilon) * { * intersectionPoint = Vector2.Zero; * return true; * } * * if (Math.Abs(RxS) < Epsilon) * { * intersectionPoint = default(Vector2); * return false; * } * * float rXsR = 1f / RxS; * float t = cmPxS * rXsR; * float u = cmPxR * rXsR; * * if (t >= 0f && t <= 1f && u >= 0f && u <= 1f) * { * intersectionPoint = segment1.Start + rectangle * t; * return true; * } * * intersectionPoint = default(Vector2); * return false; */ const float Epsilon = 0.00001f; float ua = (segment2.End.X - segment2.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment2.End.Y - segment2.Start.Y) * (segment1.Start.X - segment2.Start.X); float ub = (segment1.End.X - segment1.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment1.End.Y - segment1.Start.Y) * (segment1.Start.X - segment2.Start.X); float denominator = (segment2.End.Y - segment2.Start.Y) * (segment1.End.X - segment1.Start.X) - (segment2.End.X - segment2.Start.X) * (segment1.End.Y - segment1.Start.Y); if (Math.Abs(denominator) <= Epsilon) { if (Math.Abs(ua) <= Epsilon && Math.Abs(ub) <= Epsilon) { intersectionPoint = (segment1.Start + segment1.End + segment2.Start + segment2.End) / 4f; return(true); } } else { ua /= denominator; ub /= denominator; if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) { intersectionPoint = new Vector2f { X = segment1.Start.X + ua * (segment1.End.X - segment1.Start.X), Y = segment1.Start.Y + ua * (segment1.End.Y - segment1.Start.Y) }; return(true); } } intersectionPoint = default(Vector2); return(false); }
public static bool Intersects(Segment2D segment1, Segment2D segment2) { Vector2f intersectionPoint; return(Segment2D.Intersects(segment1, segment2, out intersectionPoint)); }
public static bool Intersects(Vector2f p1, Vector2f p2, Vector2f p3, Vector2f p4, out Vector2f intersectionPoint) { return(Segment2D.Intersects(new Segment2D(p1, p2), new Segment2D(p3, p4), out intersectionPoint)); }
public static float MinimumDistance(Segment2D segment, Vector2 point, out Vector2 minimumDistancePoint) { // Return minimum distance between line segment vw and point p float lengthSquared = segment.LengthSquared(); // i.e. |w-v|^2 - avoid a sqrt if (lengthSquared == 0.0f) { minimumDistancePoint = segment.Start; return Vector2.Distance(point, segment.Start); // v == w case } // Consider the line extending the segment, parameterized as v + t (w - v). // We find projection of point p onto the line. // It falls where t = [(p-v) . (w-v)] / |w-v|^2 float t = Vector2.Dot(point - segment.Start, segment.End - segment.Start) / lengthSquared; if (t < 0.0) { minimumDistancePoint = segment.Start; return Vector2.Distance(point, segment.Start); // Beyond the 'v' end of the segment } else if (t > 1.0) { minimumDistancePoint = segment.End; return Vector2.Distance(point, segment.End); // Beyond the 'w' end of the segment } Vector2 projection = segment.Start + t * (segment.End - segment.Start); // Projection falls on the segment minimumDistancePoint = projection; return Vector2.Distance(point, projection); }
public bool Contains(Segment2D segment) { return(this.Contains(segment.Start) && this.Contains(segment.End)); }
public static float MinimumDistance(Segment2D segment, Circle circle) { if (Segment2D.Intersects(segment, circle)) { return 0; } // okay this Max *should be* unnecessary, but lets keep it just for sure return FlaiMath.Max(0, Segment2D.MinimumDistance(segment, circle.Position) - circle.Radius); }
public bool Equals(Segment2D other) { return this.Start == other.Start && this.End == other.End; }
// is this accurate? could be... public static float MaximumDistance(Segment2D segment, RectangleF rectangle) { if (Segment2D.Intersects(segment, rectangle)) { return 0; } return FlaiMath.Max( Segment2D.MaximumDistance(segment, rectangle.TopLeft), Segment2D.MaximumDistance(segment, rectangle.TopRight), Segment2D.MaximumDistance(segment, rectangle.BottomLeft), Segment2D.MaximumDistance(segment, rectangle.BottomRight)); }
public static bool Intersects(Segment2D segment, Circle circle) { return Segment2D.MinimumDistance(segment, circle.Position) < circle.Radius; }
public static IEnumerable<Vector2i> GetPointsOnSegment(Segment2D segment) { yield return new Vector2i(segment.Start); if (segment.IsPoint || new Vector2i(segment.Start) == new Vector2i(segment.End)) { yield break; } float slope = segment.Slope; if (float.IsInfinity(slope)) // Segment is straight line in x-axis { int x = (int)segment.Start.X; int start = (int)FlaiMath.Min(segment.Start.Y, segment.End.Y); int end = (int)FlaiMath.Max(segment.Start.Y, segment.End.Y); for (int y = start + 1; y <= end; y++) { yield return new Vector2i(x, y); } } else { Vector2 normalizedStep = Vector2.Normalize(segment.End - segment.Start); float xStep = normalizedStep.X; float yStep = normalizedStep.Y; Vector2i previousCellIndex = Vector2i.One * int.MaxValue; Vector2 currentPosition = segment.Start; while (true) { float nextXDistance = float.MaxValue; if (xStep > 0) { float xDist = FlaiMath.Floor(currentPosition.X + 1) - currentPosition.X; nextXDistance = xDist / xStep; } else if (xStep < 0) { float xDist = FlaiMath.Floor(currentPosition.X) - currentPosition.X; nextXDistance = xDist / xStep; } if (nextXDistance == 0) { nextXDistance = float.MaxValue; } float nextYDistance = float.MaxValue; if (yStep > 0) { float yDist = FlaiMath.Floor(currentPosition.Y + 1) - currentPosition.Y; nextYDistance = yDist / yStep; } else if (yStep < 0) { float yDist = FlaiMath.Floor(currentPosition.Y) - currentPosition.Y; nextYDistance = yDist / yStep; } if (nextYDistance == 0) { nextYDistance = float.MaxValue; } // Vector2i previousCellIndex = new Vector2i(currentPosition); if (FlaiMath.Distance(nextXDistance, nextYDistance) < 0.0001f) { float newX = xStep > 0 ? (int)currentPosition.X + 1 : FlaiMath.Decrement((int)currentPosition.X); float newY = yStep > 0 ? (int)currentPosition.Y + 1 : FlaiMath.Decrement((int)currentPosition.Y); currentPosition = new Vector2(newX, newY); } else if (nextXDistance < nextYDistance) { if (xStep > 0) { currentPosition = new Vector2((int)currentPosition.X + 1, currentPosition.Y + normalizedStep.Y * nextXDistance); } else { currentPosition = new Vector2(FlaiMath.Decrement((int)currentPosition.X), currentPosition.Y + normalizedStep.Y * nextXDistance); } } else { if (yStep > 0) { currentPosition = new Vector2(currentPosition.X + normalizedStep.X * nextYDistance, (int)currentPosition.Y + 1); } else { currentPosition = new Vector2(currentPosition.X + normalizedStep.X * nextYDistance, FlaiMath.Decrement((int)currentPosition.Y)); } } currentPosition = Vector2.Clamp(currentPosition, Vector2.Min(segment.Start, segment.End), Vector2.Max(segment.Start, segment.End)); Vector2i currentCellIndex = new Vector2i(currentPosition); yield return currentCellIndex; if (currentCellIndex == new Vector2i(segment.End) || Vector2.Distance(segment.Start, currentPosition) > Vector2.Distance(segment.Start, segment.End) || currentCellIndex == previousCellIndex) { yield break; } previousCellIndex = currentCellIndex; } } }
public bool Equals(Segment2D other) { return(this.Start == other.Start && this.End == other.End); }