/// <summary> /// Gets a <see cref="RectangleF"/> structure that contains the union of two <see cref="RectangleF"/> structures. /// </summary> /// <param name="a">The first <see cref="RectangleF"/> to union.</param> /// <param name="b">The second <see cref="RectangleF"/> to union.</param> /// <returns>A <see cref="RectangleF"/> structure that bounds the union of the two <see cref="RectangleF"/> structures.</returns> public static RectangleF Union(RectangleF a, RectangleF b) => new RectangleF(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Max(a.X + a.Width, b.X + b.Width), Math.Max(a.Y + a.Height, b.Y + b.Height));
/// <summary> /// Creates a new instance of the <see cref="Camera"/> class from the specified <see cref="TrackObject"/> and <see cref="TriggerBounds"/>. /// </summary> /// <param name="trackObject">An <see cref="ITrackableObject"/> to follow.</param> /// <param name="triggerBounds">A <see cref="RectangleF"/> that represents how close to the edge of the screen an <see cref="ITrackableObject"/> must be to trigger panning.</param> public Camera(ITrackableObject trackObject, RectangleF triggerBounds) { if (trackObject == null || trackObject == this) { throw new ArgumentException($"The {nameof(trackObject)} must not be null or this instance."); } TrackObject = trackObject; TriggerBounds = triggerBounds; trackObject.TrackableObjectChanged += trackObject_TrackableObjectChanged; }
/// <summary> /// Determines if any corner of the provided <see cref="RectangleF"/> overlaps this <see cref="RectangleF"/>. /// </summary> /// <param name="rect">The <see cref="RectangleF"/> to test.</param> /// <returns>True if the <see cref="RectangleF"/> intersects this one, false otherwise.</returns> public bool IntersectsWith(RectangleF rect) => Contains(rect.Top, rect.Left) || Contains(rect.Top, rect.Right) || Contains(rect.Bottom, rect.Left) || Contains(rect.Bottom, rect.Right);
/// <summary> /// Creates a new <see cref="RectangleF"/> which is the area that overlaps the provided <see cref="RectangleF"/> objects. /// </summary> /// <param name="a">The first <see cref="RectangleF"/> to intersect.</param> /// <param name="b">The second <see cref="RectangleF"/> to intersect.</param> /// <returns>A new <see cref="RectangleF"/> representing the overlap covered by the two <see cref="RectangleF"/> objects.</returns> public static RectangleF Intersect(RectangleF a, RectangleF b) { if (!a.IntersectsWith(b)) { return Empty; } bool aConBTL = a.Contains(b.Top, b.Left); bool aConBTR = a.Contains(b.Top, b.Right); bool aConBBL = a.Contains(b.Bottom, b.Left); bool aConBBR = a.Contains(b.Bottom, b.Right); bool bConATL = b.Contains(a.Top, a.Left); if (aConBTL) { if (aConBTR) { if (aConBBL) { return new RectangleF(b.Location, b.Size); } else { return new RectangleF(b.Location, new SizeF(b.Width, a.Bottom - b.Top)); } } else { if (aConBBL) { return new RectangleF(b.Location, new SizeF(a.Right - b.Left, b.Height)); } else { return new RectangleF(b.Location, new SizeF(a.Right - b.Left, a.Bottom - b.Top)); } } } if (aConBTR) { if (aConBBR) { return new RectangleF(b.Location, new SizeF(b.Right - a.Left, b.Height)); } else { return new RectangleF(b.Location, new SizeF(b.Right - a.Left, a.Bottom - b.Top)); } } if (aConBBL) { if (aConBBR) { return new RectangleF(a.Location, new SizeF(b.Width, b.Bottom - a.Top)); } else { return new RectangleF(new PointF(b.Left, a.Top), new SizeF(a.Right - b.Left, b.Bottom - a.Top)); } } if (aConBBR) { return new RectangleF(a.Location, new SizeF(b.Right - a.Left, b.Bottom - a.Top)); } else { if (bConATL) { return new RectangleF(a.Location, a.Size); } } return Empty; }
/// <summary> /// Creates a new <see cref="RectangleF"/> which is the area that overlaps this and the provided <see cref="RectangleF"/> objects. /// </summary> /// <param name="rect">The <see cref="RectangleF"/> to intersect this <see cref="RectangleF"/>.</param> /// <returns>A new <see cref="RectangleF"/> representing the overlap covered by the two <see cref="RectangleF"/> objects.</returns> public RectangleF Intersect(RectangleF rect) => Intersect(this, rect);
/// <summary> /// Increases the <see cref="Size"/> of the <see cref="Rectangle"/> by the specified values. /// </summary> /// <param name="rect">The <see cref="RectangleF"/> to modify.</param> /// <param name="width">The <see cref="SizeF.Width"/> to increase the <see cref="RectangleF"/> by.</param> /// <param name="height">The <see cref="SizeF.Height"/> to increase the <see cref="RectangleF"/> by.</param> /// <returns>A new <see cref="RectangleF"/> with the increased <see cref="Size"/>.</returns> public static RectangleF Inflate(RectangleF rect, float width, float height) => rect.Inflate(width, height);
/// <summary> /// Determines if a <see cref="RectangleF"/> is entirely contained within this <see cref="RectangleF"/>. /// </summary> /// <param name="rect">The <see cref="RectangleF"/> to test.</param> /// <returns>True if rect is entirely contained within this <see cref="RectangleF"/>.</returns> public bool Contains(RectangleF rect) => Contains(rect.Top, rect.Left) && Contains(rect.Top, rect.Right) && Contains(rect.Bottom, rect.Left) && Contains(rect.Bottom, rect.Right);