2021-04-29 14:45:18 +00:00
|
|
|
package uulm.teamname.marvelous.gamelibrary;
|
2021-04-29 14:39:10 +00:00
|
|
|
|
|
|
|
import java.io.Serializable;
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
/** Represents a 2d vector of integers.
|
|
|
|
*/
|
|
|
|
public class IntVector2 implements Serializable {
|
|
|
|
private int x;
|
|
|
|
private int y;
|
|
|
|
|
|
|
|
public final static IntVector2 X = new IntVector2(1, 0);
|
|
|
|
public final static IntVector2 Y = new IntVector2(0, 1);
|
|
|
|
public final static IntVector2 Zero = new IntVector2(0, 0);
|
|
|
|
|
|
|
|
private final static float nearZero = 0.000000001f;
|
|
|
|
|
|
|
|
public IntVector2(int x, int y) {
|
|
|
|
set(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2(IntVector2 v) {
|
|
|
|
set(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 copy() {
|
|
|
|
return new IntVector2(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getX() {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getY() {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static float length(int x, int y) {
|
|
|
|
return (float)Math.sqrt(x * x + y * y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float length() {
|
|
|
|
return IntVector2.length(this.x, this.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static float length2(int x, int y) {
|
|
|
|
return x * x + y * y;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float length2 () {
|
|
|
|
return IntVector2.length2(this.x, this.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 set(int x, int y) {
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 set(IntVector2 v) {
|
|
|
|
return set(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 sub(int x, int y) {
|
|
|
|
this.x -= x;
|
|
|
|
this.y -= y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 sub(IntVector2 v) {
|
|
|
|
return sub(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 add(int x, int y) {
|
|
|
|
this.x += x;
|
|
|
|
this.y += y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 add(IntVector2 v) {
|
|
|
|
return add(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static float dot(float x1, float y1, float x2, float y2) {
|
|
|
|
return x1 * x2 + y1 * y2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float dot(float ox, float oy) {
|
|
|
|
return IntVector2.dot(this.x, this.y, ox, oy);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float dot(IntVector2 v) {
|
|
|
|
return dot(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 scale(float x, float y) {
|
|
|
|
this.x *= x;
|
|
|
|
this.y *= y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 scale(float scalar) {
|
|
|
|
return scale(scalar, scalar);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 scale(IntVector2 v) {
|
|
|
|
return scale(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static float distance(int x1, int y1, int x2, int y2) {
|
|
|
|
final float x_d = x2 - x1;
|
|
|
|
final float y_d = y2 - y1;
|
|
|
|
return (float)Math.sqrt(x_d * x_d + y_d * y_d);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distance(int x, int y) {
|
|
|
|
return IntVector2.distance(this.x, this.y, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distance(IntVector2 v) {
|
|
|
|
return distance(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static float distance2(int x1, int y1, int x2, int y2) {
|
|
|
|
final float x_d = x2 - x1;
|
|
|
|
final float y_d = y2 - y1;
|
|
|
|
return x_d * x_d + y_d * y_d;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distance2(int x, int y) {
|
|
|
|
return IntVector2.distance2(this.x, this.y, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float distance2(IntVector2 v) {
|
|
|
|
return distance2(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 setLength(float len) {
|
|
|
|
return setLength2(len * len);
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 setLength2(float len2) {
|
|
|
|
float oldLen2 = length2();
|
|
|
|
return (oldLen2 == 0 || oldLen2 == len2) ? this : scale((float)Math.sqrt(len2 / oldLen2));
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toString() {
|
|
|
|
return "(" + x + "," + y + ")";
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 fromString(String v) throws NumberFormatException {
|
|
|
|
int s = v.indexOf(',', 1);
|
|
|
|
if (s != -1 && v.charAt(0) == '(' && v.charAt(v.length() - 1) == ')') {
|
|
|
|
try {
|
|
|
|
int x = Integer.parseInt(v.substring(1, s));
|
|
|
|
int y = Integer.parseInt(v.substring(s + 1, v.length() - 1));
|
|
|
|
return this.set(x, y);
|
|
|
|
}catch (NumberFormatException ex) {
|
|
|
|
//ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw new NumberFormatException("Malformed IntVector2: " + v);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float cross(float x, float y) {
|
|
|
|
return this.x * y - this.y * x;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float cross(IntVector2 v) {
|
|
|
|
return cross(v.x, v.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isUnit(final float margin) {
|
|
|
|
return Math.abs(length2() - 1f) < margin;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isUnit() {
|
|
|
|
return isUnit(nearZero);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isZero() {
|
|
|
|
return x == 0 && y == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isZero(final float margin) {
|
|
|
|
return length2() < margin;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isOnLine(IntVector2 other, float epsilon) {
|
|
|
|
return Math.abs(x * other.y - y * other.x) <= epsilon;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isOnLine(IntVector2 other) {
|
|
|
|
return isOnLine(other, nearZero);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCollinear(IntVector2 other, float epsilon) {
|
|
|
|
return isOnLine(other, epsilon) && dot(other) > 0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCollinear(IntVector2 other) {
|
|
|
|
return isOnLine(other) && dot(other) > 0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCollinearOpposite(IntVector2 other, float epsilon) {
|
|
|
|
return isOnLine(other, epsilon) && dot(other) < 0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCollinearOpposite(IntVector2 other) {
|
|
|
|
return isOnLine(other) && dot(other) < 0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPerpendicular(IntVector2 vector) {
|
|
|
|
return isPerpendicular(vector,nearZero);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPerpendicular(IntVector2 vector, float epsilon) {
|
|
|
|
return Math.abs(dot(vector)) <= epsilon;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasSameDirection(IntVector2 vector) {
|
|
|
|
return dot(vector) > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasOppositeDirection(IntVector2 vector) {
|
|
|
|
return dot(vector) < 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntVector2 setZero() {
|
|
|
|
this.x = 0;
|
|
|
|
this.y = 0;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
if(this == o) return true;
|
|
|
|
if(o == null || getClass() != o.getClass()) return false;
|
|
|
|
IntVector2 that = (IntVector2) o;
|
|
|
|
return x == that.x && y == that.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return Objects.hash(x, y);
|
|
|
|
}
|
|
|
|
}
|