Vector2.java
package org.hammer.audio.geometry;
/** Immutable two-dimensional vector in meters for reusable geometry and localization APIs. */
public record Vector2(double x, double y) {
/** Zero vector. */
public static final Vector2 ZERO = new Vector2(0.0, 0.0);
/** Create a vector and reject NaN or infinite coordinates. */
public Vector2 {
if (!Double.isFinite(x) || !Double.isFinite(y)) {
throw new IllegalArgumentException("coordinates must be finite");
}
}
/** Return this vector plus {@code other}. */
public Vector2 plus(Vector2 other) {
return new Vector2(x + other.x, y + other.y);
}
/** Return this vector minus {@code other}. */
public Vector2 minus(Vector2 other) {
return new Vector2(x - other.x, y - other.y);
}
/** Return this vector multiplied by {@code scalar}. */
public Vector2 scale(double scalar) {
if (!Double.isFinite(scalar)) {
throw new IllegalArgumentException("scalar must be finite");
}
return new Vector2(x * scalar, y * scalar);
}
/** Dot product with {@code other}. */
public double dot(Vector2 other) {
return x * other.x + y * other.y;
}
/** Euclidean length in meters. */
public double length() {
return Math.hypot(x, y);
}
/** Distance to {@code other} in meters. */
public double distanceTo(Vector2 other) {
return minus(other).length();
}
/** Unit vector in the same direction, or zero for the zero vector. */
public Vector2 normalized() {
double len = length();
return len > 0.0 ? scale(1.0 / len) : ZERO;
}
}