/*license*\
XBN-Java: http://xbnjava.aliteralmind.com
Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
This software is dual-licensed under the:
- Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
- Apache Software License (ASL) version 2.0.
Either license may be applied at your discretion. More information may be found at
- http://en.wikipedia.org/wiki/Multi-licensing.
The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
- LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
- ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
\*license*/
package com.github.xbn.util.matrix;
import com.github.xbn.util.EnumUtil;
/**
* <p>The direction of movement within a two dimensional array, in one of the eight-main directions: up, down, left, right, up-left, up-right, down-left, down-right.</p>
*
* @see VertHorizDirection
* @see BoundedMatrix#getNeighbor(int, int, com.github.xbn.util.matrix.MatrixDirection, int, com.github.xbn.util.matrix.EdgeExceeded) BoundedMatrix#getNeighbor
* @since 0.1.5
* @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://xbnjava.aliteralmind.com">{@code http://xbnjava.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/xbnjava">{@code https://github.com/aliteralmind/xbnjava}</a>
*/
public enum MatrixDirection {
/**
* <p>Up.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code -1}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code 0}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#UP UP}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@code null}</li>
* </ul></p>
*
* @see #DOWN
* @see #LEFT
* @see #RIGHT
* @see #UP_LEFT
* @see #UP_RIGHT
* @see #DOWN_LEFT
* @see #DOWN_RIGHT
* @see #isVertical()
*/
UP(-1, 0, VertHorizDirection.UP, null),
/**
* <p>Down.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code 1}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code 0}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#DOWN DOWN}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@code null}</li>
* </ul></p>
*
* @see #UP
* @see #isDown()
* @see #isVertical()
*/
DOWN(1, 0, VertHorizDirection.DOWN, null),
/**
* <p>Left.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code 0}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code -1}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@code null}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#LEFT LEFT}</li>
* </ul></p>
*
* @see #UP
* @see #isLeft()
* @see #isHorizontal()
*/
LEFT(0, -1, null, VertHorizDirection.LEFT),
/**
* <p>Right.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code 0}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code 1}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@code null}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#RIGHT RIGHT}</li>
* </ul></p>
*
* @see #UP
* @see #isRight()
* @see #isHorizontal()
*/
RIGHT(0, 1, null, VertHorizDirection.RIGHT),
/**
* <p>Diagonal, up and to the left.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code -1}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code -1}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#UP UP}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#LEFT LEFT}</li>
* </ul></p>
*
* @see #UP
* @see #isUpLeft()
* @see #isDiagonal()
*/
UP_LEFT(-1, -1, VertHorizDirection.UP, VertHorizDirection.LEFT),
/**
* <p>Diagonal, up and to the right.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code -1}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code 1}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#UP UP}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#RIGHT RIGHT}</li>
* </ul></p>
*
* @see #UP
* @see #isUpRight()
* @see #isDiagonal()
*/
UP_RIGHT(-1, 1, VertHorizDirection.UP, VertHorizDirection.RIGHT),
/**
* <p>Diagonal, down and to the left.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code 1}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code -1}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#DOWN DOWN}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#LEFT LEFT}</li>
* </ul></p>
*
* @see #UP
* @see #isDownLeft()
* @see #isDiagonal()
*/
DOWN_LEFT(1, -1, VertHorizDirection.DOWN, VertHorizDirection.LEFT),
/**
* <p>Diagonal, down and to the right.</p>
*
* <p>Sets <ul>
* <li>{@link #getVertIncrement() getVertIncrement}{@code ()} to {@code 1}</li>
* <li>{@link #getHorizIncrement() getHorizIncrement}{@code ()} to {@code 1}</li>
* <li>{@link #getVertPortion() getVertPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#DOWN DOWN}</li>
* <li>{@link #getHorizPortion() getHorizPortion}{@code ()} to {@link VertHorizDirection}.{@link VertHorizDirection#RIGHT RIGHT}</li>
* </ul></p>
*
* @see #UP
* @see #isDownRight()
* @see #isDiagonal()
*/
DOWN_RIGHT(1, 1, VertHorizDirection.DOWN, VertHorizDirection.RIGHT);
private final int vertInc;
private final int horizInc;
private final VertHorizDirection vertPortion;
private final VertHorizDirection horizPortion;
/**
* <p>Configure the value.</p>
*
* @param horiz_increment The value to change the horizontal index by, in order to move to the neighbor in the desired direction. Get with {@link #getHorizIncrement()}.
* @param vert_increment The value to change the vertical index by. Get with {@link #getVertIncrement()}.
*/
MatrixDirection(int vert_increment, int horiz_increment,
VertHorizDirection vert_portion, VertHorizDirection horiz_portion) {
vertInc = vert_increment;
horizInc = horiz_increment;
vertPortion = vert_portion;
horizPortion = horiz_portion;
}
/**
* <p>The value to change the vertical index by, in order to move to the neighbor in the desired direction.</p>
*
* @return As documented by each value.
* @see #UP
*/
public int getVertIncrement() {
return vertInc;
}
/**
* <p>The value to change the horizontal index by, in order to move to the neighbor in the desired direction.</p>
*
* @return As documented by each value.
* @see #UP
*/
public int getHorizIncrement() {
return horizInc;
}
/**
* <p>The value to change the vertical index by, in order to move to the neighbor in the desired direction.</p>
*
* @return As documented by each value.
* @see #UP
*/
public VertHorizDirection getVertPortion() {
return vertPortion;
}
/**
* <p>The horizontal "part" of the current direction.</p>
*
* @return As documented by {@linkplain #UP each value}. Examples: <ul>
* <li>{@link #UP} returns <code>null</code></li>
* <li>{@link #LEFT} returns {@link VertHorizDirection}.{@link VertHorizDirection#LEFT LEFT}</li>
* <li>{@link #DOWN_RIGHT} returns {@link VertHorizDirection}.{@link VertHorizDirection#RIGHT RIGHT}</li>
* </ul>
*/
public VertHorizDirection getHorizPortion() {
return horizPortion;
}
/**
* <p>Is this direction {@code UP}?.</p>
*
* @return <code>this == {@link #UP}</code>
*
* @see #isDown()
* @see #isLeft()
* @see #isRight()
* @see #isUpLeft()
* @see #isUpRight()
* @see #isDownLeft()
* @see #isDownRight()
*/
public final boolean isUp() {
return this == UP;
}
/**
* <p>Is this direction {@code DOWN}?.</p>
*
* @return <code>this == {@link #DOWN}</code>
* @see #isUp()
*/
public final boolean isDown() {
return this == DOWN;
}
/**
* <p>Is this direction {@code RIGHT}?.</p>
*
* @return <code>this == {@link #RIGHT}</code>
* @see #isUp()
* @see #isHorizontal()
*/
public final boolean isRight() {
return this == RIGHT;
}
/**
* <p>Is this direction {@code LEFT}?.</p>
*
* @return <code>this == {@link #LEFT}</code>
* @see #isUp()
*/
public final boolean isLeft() {
return this == LEFT;
}
/**
* <p>Is this direction {@code DOWN_RIGHT}?.</p>
*
* @return <code>this == {@link #DOWN_RIGHT}</code>
* @see #isUp()
*/
public final boolean isDownRight() {
return this == DOWN_RIGHT;
}
/**
* <p>Is this direction {@code DOWN_LEFT}?.</p>
*
* @return <code>this == {@link #DOWN_LEFT}</code>
* @see #isUp()
*/
public final boolean isDownLeft() {
return this == DOWN_LEFT;
}
/**
* <p>Is this direction {@code UP_RIGHT}?.</p>
*
* @return <code>this == {@link #UP_RIGHT}</code>
* @see #isUp()
*/
public final boolean isUpRight() {
return this == UP_RIGHT;
}
/**
* <p>Is this direction {@code UP_LEFT}?.</p>
*
* @return <code>this == {@link #UP_LEFT}</code>
* @see #isUp()
*/
public final boolean isUpLeft() {
return this == UP_LEFT;
}
/**
* Get the opposite direction.
* @return <ul>
* <li>{@link #UP} is the opposite of {@link #DOWN}</li>
* <li>{@link #LEFT} is the opposite of {@link #RIGHT}</li>
* <li>{@link #UP_LEFT} is the opposite of {@link #DOWN_RIGHT}</li>
* <li>{@link #DOWN_LEFT} is the opposite of {@link #UP_RIGHT}</li>
* </ul>
* @see VertHorizDirection#getPerpendicularTowardsZero()
*/
public final MatrixDirection getOpposite() {
switch(this) {
case UP: return DOWN;
case DOWN: return UP;
case LEFT: return RIGHT;
case RIGHT: return LEFT;
case UP_LEFT: return DOWN_RIGHT;
case UP_RIGHT: return DOWN_LEFT;
case DOWN_LEFT: return UP_RIGHT;
case DOWN_RIGHT: return UP_LEFT;
default: throw new IllegalStateException("Unknown MatrixDirection value: " + this);
}
}
/**
* <p>Is this direction {@code UP}? or a diagonal containing up?.</p>
*
* @return <code>({@link #getVertPortion() getVertPortion}{@code ()} == {@link VertHorizDirection}.{@link VertHorizDirection#UP UP})</code>
*
* @see #hasDown()
* @see #hasLeft()
* @see #hasRight()
*/
public final boolean hasUp() {
return (getVertPortion() == VertHorizDirection.UP);
}
/**
* <p>Is this direction {@code DOWN}, or a diagonal containing down?.</p>
*
* @return <code>({@link #getVertPortion() getVertPortion}{@code ()} == {@link VertHorizDirection}.{@link VertHorizDirection#DOWN DOWN})</code>
* @see #hasUp()
*/
public final boolean hasDown() {
return (getVertPortion() == VertHorizDirection.DOWN);
}
/**
* <p>Is this direction {@code RIGHT}, or a diagonal containing right?.</p>
*
* @return <code>({@link #getHorizPortion() getHorizPortion}{@code ()} == {@link VertHorizDirection}.{@link VertHorizDirection#RIGHT RIGHT})</code>
* @see #hasUp()
* @see #isHorizontal()
* @see #hasHorizontal()
*/
public final boolean hasRight() {
return (getHorizPortion() == VertHorizDirection.RIGHT);
}
/**
* <p>Is this direction {@code LEFT}, or a diagonal containing left?.</p>
*
* @return <code>({@link #getHorizPortion() getHorizPortion}{@code ()} == {@link VertHorizDirection}.{@link VertHorizDirection#LEFT LEFT})</code>
* @see #hasUp()
*/
public final boolean hasLeft() {
return (getHorizPortion() == VertHorizDirection.LEFT);
}
/**
* Is this diagonal <i>or</i> vertical?.
* @return <code>({@link #hasUp}() || {@link #hasDown}())</code>
* @see #hasVertical()
*/
public final boolean hasVertical() {
return (hasUp() || hasDown());
}
/**
* Is this diagonal <i>or</i> horizontal?.
* @return <code>({@link #hasRight}() || {@link #hasLeft}())</code>
* @see #hasVertical()
*/
public final boolean hasHorizontal() {
return (hasRight() || hasLeft());
}
/**
* Is <i><code>this</code></i> direction up or down?.
* @return <code>({@link #isUp() isUp}{@code ()} || {@link #isDown() isDown}{@code ()}</code>
* @see #isHorizontal()
*/
public final boolean isVertical() {
return (isUp() || isDown());
}
/**
* Is <i><code>this</code></i> direction left or right?.
* @return <code>({@link #isLeft() isLeft}{@code ()} || {@link #isRight() isRight}{@code ()}</code>
* @see #isVertical()
* @see #isVertOrHoriz()
* @see #isDiagonal()
*/
public final boolean isHorizontal() {
return (isLeft() || isRight());
}
/**
* Is <i><code>this</code></i> direction up, down, left, or right?.
* @return <code>({@link #isVertical() isVertical}{@code ()} || {@link #isHorizontal() isHorizontal}{@code ()}</code>
*/
public final boolean isVertOrHoriz() {
return (isVertical() || isHorizontal());
}
/**
* Is <i><code>this</code></i> <i>not</i> vertical or horizontal?.
* @return <code>!({@link #isVertical() isVertical}{@code ()} || {@link #isHorizontal() isHorizontal}{@code ()}</code>
*/
public final boolean isDiagonal() {
return !(isVertical() || isHorizontal());
}
/**
* <p>If an <code>MatrixDirection</code> is not a required value, crash.</p>
*
* <p>Equal to
* <br/> <code>{@link com.github.xbn.util.EnumUtil EnumUtil}.{@link com.github.xbn.util.EnumUtil#crashIfNotRequiredValue(Enum, Enum, String, Object) crashIfNotRequiredValue}(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo)</code></p>
* @see #crashIfForbiddenValue(MatrixDirection, String, Object) crashIfForbiddenValue(ert,s,o)
*/
public void crashIfNotRequiredValue(MatrixDirection e_rqd, String s_thisEnumsVarNm, Object o_xtraInfo) {
EnumUtil.crashIfNotRequiredValue(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo);
}
/**
* <p>If an <code>MatrixDirection</code> is a forbidden value, crash.</p>
*
* <p>Equal to
* <br/> <code>{@link com.github.xbn.util.EnumUtil EnumUtil}.{@link com.github.xbn.util.EnumUtil#crashIfForbiddenValue(Enum, Enum, String, Object) crashIfForbiddenValue}(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo)</code></p>
* @see #crashIfNotRequiredValue(MatrixDirection, String, Object) crashIfNotRequiredValue(ert,s,o)
*/
public void crashIfForbiddenValue(MatrixDirection e_rqd, String s_thisEnumsVarNm, Object o_xtraInfo) {
EnumUtil.crashIfForbiddenValue(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo);
}
};