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;
}
}