using System; using Chernobyl.Mathematics.Vectors; namespace Chernobyl.Mathematics.Measures { /// /// A type that is used to contain the location of a cell in a 2D grid. /// public struct RowColumn { /// /// Initializes a new instance of the struct. /// /// The X index location where -N is the left most /// cell and N is the right most. /// The Y index location where -N is the bottom most /// cell and N is the top most. public RowColumn(int row, int column) { _row = row; _column = column; } /// /// The X index location where -N is the left most cell and N is the /// right most. /// public int Row { get { return _row; } } /// /// The Y index location where -N is the bottom most cell and N is the /// top most. /// public int Column { get { return _column; } } /// /// Returns the center point of this cell based on the size of a single /// cell within a uniform grid. /// /// The width () and height /// () of a single cell in the uniform grid. /// The center position of the cell. /// Thrown if either width /// () or height () of a /// are less than or equal to zero. public Vector2 GetCenter(Vector2 cellSize) { if (cellSize.X <= 0) throw new ArgumentOutOfRangeException("cellSize", cellSize.X, "The width of the cell cannot be less than or equal to 0."); if (cellSize.Y <= 0) throw new ArgumentOutOfRangeException("cellSize", cellSize.Y, "The height of the cell cannot be less than or equal to 0."); float halfWidth = cellSize.X * .5f; float halfHeight = cellSize.Y * .5f; return new Vector2(cellSize.Y * (Column + 1.0f) - halfHeight, cellSize.X * (Row + 1.0f) - halfWidth); } /// /// Returns the index location of a cell based on a (X, Y) position and /// the size of each cell in a uniform grid. /// /// The width () and height /// () of a single cell in the uniform grid. /// A point that intersects the cell to retrieve. /// The index location of the cell which touches /// . /// Thrown if either width /// () or height () of a /// are less than or equal to zero. public static RowColumn FromPosition(Vector2 cellSize, Vector2 position) { if(cellSize.X <= 0) throw new ArgumentOutOfRangeException("cellSize", cellSize.X, "The width of the cell cannot be less than or equal to 0."); if(cellSize.Y <= 0) throw new ArgumentOutOfRangeException("cellSize", cellSize.Y, "The height of the cell cannot be less than or equal to 0."); return new RowColumn((int)(position.Y / cellSize.Y), (int)(position.X / cellSize.X)); } /// /// Checks if two are equal to each other. /// /// The left side of the operation. /// The right side of the operation. /// True if the two are equal, false if otherwise. public static bool operator ==(RowColumn left, RowColumn right) { return left.Equals(right); } /// /// Checks if two are equal to each other. /// /// The left side of the operation. /// The right side of the operation. /// True if the two are different, false if otherwise. public static bool operator !=(RowColumn left, RowColumn right) { return !(left == right); } /// /// Gets the hash code of the Radian. /// /// The hash code of the number. public override int GetHashCode() { return Row.GetHashCode() ^ Column.GetHashCode(); } /// /// Indicates whether the current object is equal to another object of /// the same type. /// /// An object to compare with this object. /// True if the current object is equal to the /// parameter; otherwise, false. /// public bool Equals(RowColumn other) { return (Row == other.Row && Column == other.Column); } /// /// Checks this for equality with object passed in. /// /// The object to compare to. /// True if the object is equal to this , /// false if otherwise. public override bool Equals(object obj) { return (obj is RowColumn && Equals((RowColumn)obj)); } /// /// Returns a that represents this instance in the /// form: "(Row, Column)". /// /// A that represents this instance. public override string ToString() { return String.Format("({0}, {1})", Row, Column); } /// /// The backing field to . /// int _row; /// /// The backing field to . /// int _column; } }