/// <summary>Returns the average of the closest points between 'lhs' and 'rhs'.</summary> public static v2 ClosestPoint(BRect lhs, BRect rhs) { v2 pt0, pt1; ClosestPoint(lhs, rhs, out pt0, out pt1); return((pt0 + pt1) * 0.5f); }
/// <summary>Return the closest point on 'rect' to 'pt'</summary> public static v2 ClosestPoint(BRect rect, v2 pt) { v2 lower = rect.Lower; v2 upper = rect.Upper; v2 closest; if (rect.IsWithin(pt)) { // if pt.x/pt.y > rect.sizeX/rect.sizeY then the point // is closer to the Y edge of the rectangle if (Math_.Abs(pt.x * rect.SizeY) > Math_.Abs(pt.y * rect.SizeX)) { closest = new v2(pt.x, Math_.Sign(pt.y) * rect.SizeY); } else { closest = new v2(Math_.Sign(pt.x) * rect.SizeX, pt.y); } } else { closest = new v2( Math_.Clamp(pt.x, lower.x, upper.x), Math_.Clamp(pt.y, lower.y, upper.y)); } return(closest); }
/// <summary> /// Returns the closest points between 'lhs' and 'rhs'. /// If 'lhs' and 'rhs' overlap, returns the points of deepest penetration.</summary> public static void ClosestPoint(BRect lhs, BRect rhs, out v2 pt0, out v2 pt1) { pt0 = lhs.Centre; pt1 = rhs.Centre; if (rhs.Centre.x > lhs.Centre.x) { pt0.x += lhs.Radius.x; pt1.x += rhs.Radius.x; } if (rhs.Centre.x < lhs.Centre.x) { pt0.x -= lhs.Radius.x; pt1.x -= rhs.Radius.x; } if (rhs.Centre.y > lhs.Centre.y) { pt0.y += lhs.Radius.y; pt1.y += rhs.Radius.y; } if (rhs.Centre.y < lhs.Centre.y) { pt0.y -= lhs.Radius.y; pt1.y -= rhs.Radius.y; } }
/// <summary>Returns the squared distance from 'point' to 'brect'</summary> public static float DistanceSq(v2 point, BRect brect) { float dist_sq = 0.0f; v2 lower = brect.Lower; v2 upper = brect.Upper; if (point.x < lower.x) { dist_sq += Math_.Sqr(lower.x - point.x); } else if (point.x > upper.x) { dist_sq += Math_.Sqr(point.x - upper.x); } if (point.y < lower.y) { dist_sq += Math_.Sqr(lower.y - point.y); } else if (point.y > upper.y) { dist_sq += Math_.Sqr(point.y - upper.y); } return(dist_sq); }
/// <summary>Returns true if 'rhs' intersects with this bounding rectangle</summary> public static bool IsIntersection(BRect lhs, BRect rhs) { return (Math.Abs(lhs.m_centre.x - rhs.m_centre.x) <= (lhs.m_radius.x + rhs.m_radius.x) && Math.Abs(lhs.m_centre.y - rhs.m_centre.y) <= (lhs.m_radius.y + rhs.m_radius.y)); }
/// <summary>Returns true if 'brect' is within this bounding rectangle (within 'tol'erance)</summary> public bool IsWithin(BRect bbox, float tol = 0f) { return (Math.Abs(bbox.m_centre.x - m_centre.x) <= (m_radius.x - bbox.m_radius.x + tol) && Math.Abs(bbox.m_centre.y - m_centre.y) <= (m_radius.y - bbox.m_radius.y + tol)); }