etk/src/org/atriasoft/etk/math/Vector2i.java

348 lines
8.7 KiB
Java

package org.atriasoft.etk.math;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.umd.cs.findbugs.annotations.CheckReturnValue;
public record Vector2i(
int x,
int y) {
final static Logger LOGGER = LoggerFactory.getLogger(Vector2i.class);
public static Vector2i valueOf(String value) throws NumberFormatException {
int val1 = 0;
int val2 = 0;
// copy to permit to modify it :
while (value.length() > 0 && value.charAt(0) == '(') {
value = value.substring(1);
}
while (value.length() > 0 && value.charAt(0) == ')') {
value = value.substring(0, value.length() - 1);
}
final String[] values = value.split(",| ");
if (values.length > 2) {
LOGGER.error("Can not parse Vector2i with more than 2 values: '" + value + "'");
}
if (values.length == 1) {
// no coma ...
// in every case, we parse the first element :
val1 = Integer.valueOf(values[0]);
val2 = val1;
} else {
val1 = Integer.valueOf(values[0]);
val2 = Integer.valueOf(values[1]);
}
return new Vector2i(val1, val2);
}
/*
* **************************************************** Constructor
*****************************************************/
public Vector2i() {
this(0, 0);
}
public Vector2i(final int x, final int y) {
this.x = x;
this.y = y;
}
public static Vector2i max(final Vector2i obj1, final Vector2i obj2) {
return new Vector2i(Math.max(obj1.x, obj2.x), Math.max(obj1.y, obj2.y));
}
public static Vector2i min(final Vector2i obj1, final Vector2i obj2) {
return new Vector2i(Math.min(obj1.x, obj2.x), Math.min(obj1.y, obj2.y));
}
/**
* Return a vector will the absolute values of each element
* @return New vector containing the value
*/
@CheckReturnValue
public Vector2i absolute() {
return new Vector2i(Math.abs(this.x), Math.abs(this.y));
}
@CheckReturnValue
public Vector2i add(final int val) {
return new Vector2i(this.x + val, this.y + val);
}
@CheckReturnValue
public Vector2i add(final Vector2i obj) {
return new Vector2i(this.x + obj.x, this.y + obj.y);
}
@CheckReturnValue
public Vector2i add(final int xxx, final int yyy) {
return new Vector2i(this.x + xxx, this.y + yyy);
}
/**
* Return the axis with the largest ABSOLUTE value
* @return values 0,1 for x or y
*/
@CheckReturnValue
public int closestAxis() {
return absolute().maxAxis();
}
/**
* Return the cross product / determinant
* @param obj The other vector in the cross product
* @return cross product value
*/
@CheckReturnValue
public int cross(final Vector2i obj) {
return this.x * obj.y - this.y * obj.x;
}
/**
* Decrementation of this vector (-1 of 2 elements)
*/
@CheckReturnValue
public Vector2i decrement() {
return new Vector2i(this.x - 1, this.y - 1);
}
@CheckReturnValue
public Vector2i devide(final int val) {
return new Vector2i(this.x / val, this.y / val);
}
@CheckReturnValue
public Vector2i devide(final Vector2i obj) {
return new Vector2i(this.x / obj.x, this.y / obj.y);
}
/**
* Return the distance between the ends of this and another vector This
* is symantically treating the vector like a point
* @param obj The other vector to compare distance
* @return the distance of the 2 points
*/
@CheckReturnValue
public int distance(final Vector2i obj) {
return (int) Math.sqrt(distance2(obj));
}
/**
* Return the distance squared between the ends of this and another
* vector This is symantically treating the vector like a point
* @param obj The other vector to compare distance
* @return the square distance of the 2 points
*/
@CheckReturnValue
public int distance2(final Vector2i obj) {
final int deltaX = obj.x - this.x;
final int deltaY = obj.y - this.y;
return deltaX * deltaX + deltaY * deltaY;
}
/**
* Return the dot product
* @param obj The other vector in the dot product
* @return Dot product value
*/
@CheckReturnValue
public int dot(final Vector2i obj) {
return this.x * obj.x + this.y * obj.y;
}
/**
* Return the axis with the smallest ABSOLUTE value
* @return values 0,1 for x, or z
*/
@CheckReturnValue
public int furthestAxis() {
return absolute().minAxis();
}
/**
* Incrementation of this vector (+1 of 2 elements)
*/
@CheckReturnValue
public Vector2i increment() {
return new Vector2i(this.x + 1, this.y + 1);
}
/**
* In-Equality compare operator with an other object.
* @param obj Reference on the comparing object
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
@CheckReturnValue
public boolean isDifferent(final Vector2i obj) {
return (obj.x != this.x || obj.y != this.y);
}
/**
* Equality compare operator with an other object.
* @param obj Reference on the comparing object
* @return true The Objects are identical
* @return false The Objects are NOT identical
*/
@CheckReturnValue
public boolean isEqual(final Vector2i obj) {
return (obj.x == this.x && obj.y == this.y);
}
@CheckReturnValue
public boolean isGreater(final Vector2i obj) {
return (this.x > obj.x && this.y > obj.y);
}
@CheckReturnValue
public boolean isGreaterOrEqual(final Vector2i obj) {
return (this.x >= obj.x && this.y >= obj.y);
}
@CheckReturnValue
public boolean isLower(final Vector2i obj) {
return (this.x < obj.x && this.y < obj.y);
}
@CheckReturnValue
public boolean isLowerOrEqual(final Vector2i obj) {
return (this.x <= obj.x && this.y <= obj.y);
}
/**
* Check if the vector is equal to (0,0)
* @return true The value is equal to (0,0)
* @return false The value is NOT equal to (0,0)
*/
@CheckReturnValue
public boolean isZero() {
return this.x == 0 && this.y == 0;
}
/**
* Get the length of the vector
* @return Length value
*/
@CheckReturnValue
public int length() {
return (int) Math.sqrt(length2());
}
/**
* Get the length of the vector squared
* @return Squared length value.
*/
@CheckReturnValue
public int length2() {
return dot(this);
}
@CheckReturnValue
public Vector2i less(final int val) {
return new Vector2i(this.x - val, this.y - val);
}
@CheckReturnValue
public Vector2i less(final int xxx, final int yyy) {
return new Vector2i(this.x - xxx, this.y - yyy);
}
@CheckReturnValue
public Vector2i less(final Vector2i obj) {
return new Vector2i(this.x - obj.x, this.y - obj.y);
}
/**
* Return the axis with the largest value
* @return values are 0,1 for x or y
*/
@CheckReturnValue
public int maxAxis() {
return this.x < this.y ? 1 : 0;
}
/**
* Return the axis with the smallest value
* @return values are 0,1 for x or y
*/
@CheckReturnValue
public int minAxis() {
return this.x < this.y ? 0 : 1;
}
@CheckReturnValue
public Vector2i multiply(final int val) {
return new Vector2i(this.x * val, this.y * val);
}
@CheckReturnValue
public Vector2i multiply(final Vector2i obj) {
return new Vector2i(this.x * obj.x, this.y * obj.y);
}
/**
* Normalize this vector x^2 + y^2 = 1
* @return New vector containing the value
*/
@CheckReturnValue
public Vector2i normalize() {
return this.devide(length());
}
/**
* Normalize this vector x^2 + y^2 = 1 (check if not deviding by 0, if it
* is the case ==> return (1,0))
* @return Local reference of the vector normalized
*/
@CheckReturnValue
public Vector2i safeNormalize() {
final int tmp = length();
if (tmp != 0) {
return this.devide(length());
}
return new Vector2i(1, 0);
};
@CheckReturnValue
public Vector2i max(final int xxx, final int yyy) {
return new Vector2i(Math.max(this.x, xxx), Math.max(this.y, yyy));
}
@CheckReturnValue
public Vector2i min(final int xxx, final int yyy) {
return new Vector2i(Math.min(this.x, xxx), Math.min(this.y, yyy));
}
/**
* Set 0 value on all the vector
*/
public static final Vector2i ZERO = new Vector2i(0, 0);
public static final Vector2i ONE = new Vector2i(1, 1);
public static final Vector2i VALUE_2 = new Vector2i(2, 2);
public static final Vector2i VALUE_4 = new Vector2i(4, 4);
public static final Vector2i VALUE_8 = new Vector2i(8, 8);
public static final Vector2i VALUE_16 = new Vector2i(16, 16);
public static final Vector2i VALUE_32 = new Vector2i(32, 32);
public static final Vector2i VALUE_64 = new Vector2i(64, 64);
public static final Vector2i VALUE_128 = new Vector2i(128, 128);
public static final Vector2i VALUE_256 = new Vector2i(256, 256);
public static final Vector2i VALUE_512 = new Vector2i(512, 512);
public static final Vector2i VALUE_1024 = new Vector2i(1024, 1024);
@Override
public String toString() {
return "Vector2i(" + this.x + "," + this.y + ")";
}
@CheckReturnValue
public Vector2i withX(final int xxx) {
return new Vector2i(xxx, this.y);
}
@CheckReturnValue
public Vector2i withY(final int yyy) {
return new Vector2i(this.x, yyy);
}
}