|
|
@ -7,10 +7,8 @@ import java.util.random.RandomGenerator;
|
|
|
|
|
|
|
|
|
|
|
|
import static eu.jonahbauer.raytracing.Main.DEBUG;
|
|
|
|
import static eu.jonahbauer.raytracing.Main.DEBUG;
|
|
|
|
|
|
|
|
|
|
|
|
public record Vec3(double x, double y, double z) {
|
|
|
|
public record Vec3(double x, double y, double z) implements IVec3<Vec3> {
|
|
|
|
public static final Vec3 ZERO = new Vec3(0, 0, 0);
|
|
|
|
public static final Vec3 ZERO = new Vec3(0, 0, 0);
|
|
|
|
public static final Vec3 MAX = new Vec3(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
|
|
|
|
|
|
|
|
public static final Vec3 MIN = new Vec3(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
|
|
|
|
|
|
|
|
public static final Vec3 UNIT_X = new Vec3(1, 0, 0);
|
|
|
|
public static final Vec3 UNIT_X = new Vec3(1, 0, 0);
|
|
|
|
public static final Vec3 UNIT_Y = new Vec3(0, 1, 0);
|
|
|
|
public static final Vec3 UNIT_Y = new Vec3(0, 1, 0);
|
|
|
|
public static final Vec3 UNIT_Z = new Vec3(0, 0, 1);
|
|
|
|
public static final Vec3 UNIT_Z = new Vec3(0, 0, 1);
|
|
|
@ -62,7 +60,7 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
* @return the reflected vector
|
|
|
|
* @return the reflected vector
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static @NotNull Vec3 reflect(@NotNull Vec3 vec, @NotNull Vec3 normal) {
|
|
|
|
public static @NotNull Vec3 reflect(@NotNull Vec3 vec, @NotNull Vec3 normal) {
|
|
|
|
var factor = - 2 * normal.times(vec);
|
|
|
|
var factor = - 2 * normal.dot(vec);
|
|
|
|
return Vec3.fma(factor, normal, vec);
|
|
|
|
return Vec3.fma(factor, normal, vec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -75,7 +73,7 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static @NotNull Optional<Vec3> refract(@NotNull Vec3 vec, @NotNull Vec3 normal, double ri) {
|
|
|
|
public static @NotNull Optional<Vec3> refract(@NotNull Vec3 vec, @NotNull Vec3 normal, double ri) {
|
|
|
|
vec = vec.unit();
|
|
|
|
vec = vec.unit();
|
|
|
|
var cosTheta = Math.min(- vec.times(normal), 1.0);
|
|
|
|
var cosTheta = Math.min(- vec.dot(normal), 1.0);
|
|
|
|
var sinTheta = Math.sqrt(1 - cosTheta * cosTheta);
|
|
|
|
var sinTheta = Math.sqrt(1 - cosTheta * cosTheta);
|
|
|
|
if (ri * sinTheta > 1) return Optional.empty();
|
|
|
|
if (ri * sinTheta > 1) return Optional.empty();
|
|
|
|
|
|
|
|
|
|
|
@ -166,6 +164,10 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
return a.x * b.y * c.z + a.y * b.z * c.x + a.z * b.x * c.y - c.x * b.y * a.z - c.y * b.z * a.x - c.z * b.x * a.y;
|
|
|
|
return a.x * b.y * c.z + a.y * b.z * c.x + a.z * b.x * c.y - c.x * b.y * a.z - c.y * b.z * a.x - c.z * b.x * a.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* Math
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
public @NotNull Vec3 plus(double x, double y, double z) {
|
|
|
|
public @NotNull Vec3 plus(double x, double y, double z) {
|
|
|
|
return new Vec3(this.x + x, this.y + y, this.z + z);
|
|
|
|
return new Vec3(this.x + x, this.y + y, this.z + z);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -179,6 +181,7 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
* @param other a vector
|
|
|
|
* @param other a vector
|
|
|
|
* @return the sum of this and the other vector
|
|
|
|
* @return the sum of this and the other vector
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public @NotNull Vec3 plus(@NotNull Vec3 other) {
|
|
|
|
public @NotNull Vec3 plus(@NotNull Vec3 other) {
|
|
|
|
return new Vec3(this.x + other.x, this.y + other.y, this.z + other.z);
|
|
|
|
return new Vec3(this.x + other.x, this.y + other.y, this.z + other.z);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -188,49 +191,58 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
* @param other a vector
|
|
|
|
* @param other a vector
|
|
|
|
* @return the difference of this and the other vector
|
|
|
|
* @return the difference of this and the other vector
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public @NotNull Vec3 minus(@NotNull Vec3 other) {
|
|
|
|
public @NotNull Vec3 minus(@NotNull Vec3 other) {
|
|
|
|
return new Vec3(this.x - other.x, this.y - other.y, this.z - other.z);
|
|
|
|
return new Vec3(this.x - other.x, this.y - other.y, this.z - other.z);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Computes the scalar product of this and another vector
|
|
|
|
|
|
|
|
* @param other a vector
|
|
|
|
|
|
|
|
* @return the scalar product
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public double times(@NotNull Vec3 other) {
|
|
|
|
|
|
|
|
return this.x * other.x + this.y * other.y + this.z * other.z;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Multiplies this vector with a scalar
|
|
|
|
* Multiplies this vector with a scalar
|
|
|
|
* @param t a scalar
|
|
|
|
* @param t a scalar
|
|
|
|
* @return the product of this vector and the scalar
|
|
|
|
* @return the product of this vector and the scalar
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public @NotNull Vec3 times(double t) {
|
|
|
|
public @NotNull Vec3 times(double t) {
|
|
|
|
return new Vec3(this.x * t, this.y * t, this.z * t);
|
|
|
|
return new Vec3(this.x * t, this.y * t, this.z * t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Negates this vector.
|
|
|
|
* Multiplies this vector with another vector component-wise.
|
|
|
|
* {@return the negated vector}
|
|
|
|
* @param other a vector
|
|
|
|
|
|
|
|
* @return the component-wise product of this vector and the other vector
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public @NotNull Vec3 neg() {
|
|
|
|
@Override
|
|
|
|
return new Vec3(-x, -y, -z);
|
|
|
|
public @NotNull Vec3 times(@NotNull Vec3 other) {
|
|
|
|
|
|
|
|
return new Vec3(this.x * other.x, this.y * other.y, this.z * other.z);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Inverts each component of this vector.
|
|
|
|
* Divides this vector by a scalar
|
|
|
|
* @return the inverted vector.
|
|
|
|
* @param t a scalar
|
|
|
|
|
|
|
|
* @return this vector divided by the scalar
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public @NotNull Vec3 inv() {
|
|
|
|
@Override
|
|
|
|
return new Vec3(1 / x, 1 / y, 1 / z);
|
|
|
|
public @NotNull Vec3 div(double t) {
|
|
|
|
|
|
|
|
return times(1 / t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Computes the cross-product of this and another vector
|
|
|
|
* Computes the scalar product of this and another vector
|
|
|
|
* @param other a vector
|
|
|
|
* @param other a vector
|
|
|
|
* @return the cross-product
|
|
|
|
* @return the scalar product
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
public double dot(@NotNull Vec3 other) {
|
|
|
|
|
|
|
|
return this.x * other.x + this.y * other.y + this.z * other.z;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public @NotNull Vec3 neg() {
|
|
|
|
|
|
|
|
return new Vec3(-x, -y, -z);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public @NotNull Vec3 inv() {
|
|
|
|
|
|
|
|
return new Vec3(1 / x, 1 / y, 1 / z);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public @NotNull Vec3 cross(@NotNull Vec3 other) {
|
|
|
|
public @NotNull Vec3 cross(@NotNull Vec3 other) {
|
|
|
|
return new Vec3(
|
|
|
|
return new Vec3(
|
|
|
|
Math.fma(this.y, other.z, - other.y * this.z),
|
|
|
|
Math.fma(this.y, other.z, - other.y * this.z),
|
|
|
@ -239,15 +251,6 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Divides this vector by a scalar
|
|
|
|
|
|
|
|
* @param t a scalar
|
|
|
|
|
|
|
|
* @return this vector divided by the scalar
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public @NotNull Vec3 div(double t) {
|
|
|
|
|
|
|
|
return new Vec3(this.x / t, this.y / t, this.z / t);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* {@return the squared length of this vector}
|
|
|
|
* {@return the squared length of this vector}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -279,17 +282,28 @@ public record Vec3(double x, double y, double z) {
|
|
|
|
return div(Math.sqrt(squared));
|
|
|
|
return div(Math.sqrt(squared));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/*
|
|
|
|
* {@return the n-th component of this vector}
|
|
|
|
* Accessors
|
|
|
|
* @param axis the component index
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public double get(int axis) {
|
|
|
|
|
|
|
|
return switch (axis) {
|
|
|
|
@Override
|
|
|
|
case 0 -> x;
|
|
|
|
public double component1() {
|
|
|
|
case 1 -> y;
|
|
|
|
return x;
|
|
|
|
case 2 -> z;
|
|
|
|
}
|
|
|
|
default -> throw new IndexOutOfBoundsException(axis);
|
|
|
|
|
|
|
|
};
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public double component2() {
|
|
|
|
|
|
|
|
return y;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public double component3() {
|
|
|
|
|
|
|
|
return z;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public @NotNull Vec3 toVec3() {
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public @NotNull Vec3 withX(double x) {
|
|
|
|
public @NotNull Vec3 withX(double x) {
|
|
|
|