#region CPL License /* Nuclex Framework Copyright (C) 2002-2011 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; namespace Nuclex.Game.Space { /// Two-dimensional bounding rectangle public struct BoundingRectangle { /// Initializes a new two-dimensional bounding rectangle /// X coordinate of the rectangle's left border /// Y coordinate of the rectangle's upper border /// X coordinate of the rectangle's right border /// Y coordinate of the rectangle's lower border public BoundingRectangle(float minX, float minY, float maxX, float maxY) : this(new Vector2(minX, minY), new Vector2(maxX, maxY)) { } /// Initializes a new two-dimensional bounding rectangle /// Lesser coordinates of the bounding rectangle /// Greater coordinates of the bounding rectangle public BoundingRectangle(Vector2 min, Vector2 max) { this.Min = min; this.Max = max; } /// /// Determines the containment type of a point to the bounding rectangle /// /// Point that will be checked for containment /// The containment type of the point in the rectangle public void Contains(ref Vector2 point, out ContainmentType result) { result = containsPoint(ref point) ? ContainmentType.Contains : ContainmentType.Disjoint; } /// Determines whether the bounding rectangle contains a point /// Point that will be checked for containment /// True if the bounding rectangle contains the point public bool Contains(Vector2 point) { return containsPoint(ref point); } /// /// Determines the containment type of another rectangle to the bounding rectangle /// /// Rectangle that will be checked for containment /// /// The containment type of the other rectangle in the rectangle /// public void Contains(ref BoundingRectangle rectangle, out ContainmentType result) { bool outside = (rectangle.Max.X <= this.Min.X) || (rectangle.Min.X > this.Max.X) || (rectangle.Max.Y <= this.Min.Y) || (rectangle.Min.Y > this.Max.Y); if(outside) { result = ContainmentType.Disjoint; return; } bool contained = (rectangle.Min.X >= this.Min.X) && (rectangle.Max.X < this.Max.X) && (rectangle.Min.Y >= this.Min.Y) && (rectangle.Max.Y < this.Max.Y); if(contained) { result = ContainmentType.Contains; return; } result = ContainmentType.Intersects; return; } /// /// Determines whether the bounding rectangle contains another rectangle /// /// Rectangle that will be checked for containment /// True if the other rectangle is contained in the rectangle public bool Contains(BoundingRectangle rectangle) { return (rectangle.Min.X >= this.Min.X) && (rectangle.Max.X < this.Max.X) && (rectangle.Min.Y >= this.Min.Y) && (rectangle.Max.Y < this.Max.Y); } /// /// Builds the smallest bounding rectangle that contains the two /// specified bounding rectangle. /// /// One of the bounding rectangles to contain /// One of the bounding rectangles to contain /// The resulting merged bounding rectangle public static BoundingRectangle CreateMerged( BoundingRectangle original, BoundingRectangle additional ) { BoundingRectangle result; CreateMerged(ref original, ref additional, out result); return result; } /// /// Builds the smallest bounding rectangle that contains the two /// specified bounding rectangles. /// /// One of the bounding rectangles to contain /// One of the bounding rectangles to contain /// The resulting merged bounding rectangle public static void CreateMerged( ref BoundingRectangle original, ref BoundingRectangle additional, out BoundingRectangle result ) { result = new BoundingRectangle(); result.Min = Vector2.Min(original.Min, additional.Min); result.Max = Vector2.Max(original.Max, additional.Max); } /// /// Determines whether the rectangle intersects with another rectangle /// /// /// Other rectangle that will be checked for intersection /// /// True if the rectangles intersect public bool Intersects(BoundingRectangle other) { return intersectsRectangle(ref other); } /// /// Determines whether the rectangle intersects with another rectangle /// /// /// Other rectangle that will be checked for intersection /// /// /// Will be set to true if the rectangles intersects, otherwise false /// public void Intersects(ref BoundingRectangle other, out bool result) { result = intersectsRectangle(ref other); } /// Determines whether another object is an identical bounding rectangle /// Other object that will be compared /// True if the other object is identical to the bounding rectangle public override bool Equals(object otherObject) { if(otherObject is BoundingRectangle) { return Equals((BoundingRectangle)otherObject); } else { return false; } } /// Determines whether another object is an identical bounding rectangle /// Other rectangle that will be compared /// True if the other rectangle is identical to the bounding rectangle public bool Equals(BoundingRectangle other) { return (this.Min.X == other.Min.X) && (this.Min.Y == other.Min.Y) && (this.Max.X == other.Max.X) && (this.Max.Y == other.Max.Y); } /// Checks two bounding rectangles for inequality /// First bounding rectangle that will be compared /// Second bounding rectangle that will be compared /// True if the rectangles are different public static bool operator !=(BoundingRectangle first, BoundingRectangle second) { return !(first == second); } /// Checks two bounding rectangles for equality /// First bounding rectangle that will be compared /// Second bounding rectangle that will be compared /// True if both rectangles are equal public static bool operator ==(BoundingRectangle first, BoundingRectangle second) { return first.Equals(second); } /// Gets a hash code for the bounding rectangle /// The hash code of the bounding rectangle public override int GetHashCode() { return this.Min.GetHashCode() ^ this.Max.GetHashCode(); } /// Converts the bounding rectangle into a human-readable string /// A human readable string describing the bounding rectangle public override string ToString() { string min = this.Min.ToString(); string max = this.Max.ToString(); StringBuilder builder = new StringBuilder(5 + min.Length + 5 + max.Length + 1); builder.Append("{Min:"); builder.Append(min); builder.Append(" Max:"); builder.Append(max); builder.Append('}'); return builder.ToString(); } /// Whether the bounding rectangle contains the specified point /// Point that is checked for containment /// True if the point is contained in the bounding rectangle private bool containsPoint(ref Vector2 point) { return (point.X >= Min.X) && (point.Y >= Min.Y) && (point.X < Max.X) && (point.Y < Max.Y); } /// Whether the bounding rectangle intersects with another rectangle /// /// Other rectangle that will be checked for intersection /// /// True if the rectangles intersect each other private bool intersectsRectangle(ref BoundingRectangle rectangle) { return (rectangle.Max.X >= this.Min.X) && (rectangle.Max.Y >= this.Min.Y) && (rectangle.Min.X < this.Max.X) && (rectangle.Min.Y < this.Max.Y); } /// Coordinates of the lesser side of the bounding rectangle public Vector2 Min; /// Coordinates of the greater side of the bounding rectangle public Vector2 Max; } } // namespace Nuclex.Game.Space