#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