add 2d primitives
parent
86b6f1891c
commit
b5acbd1b6c
@ -0,0 +1,26 @@
|
||||
package eu.jonahbauer.raytracing.scene.flat;
|
||||
|
||||
import eu.jonahbauer.raytracing.math.BoundingBox;
|
||||
import eu.jonahbauer.raytracing.math.Vec3;
|
||||
import eu.jonahbauer.raytracing.render.material.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public final class Ellipse extends Hittable2D {
|
||||
public Ellipse(@NotNull Vec3 origin, @NotNull Vec3 u, @NotNull Vec3 v, @NotNull Material material) {
|
||||
super(origin, u, v, material);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInterior(double alpha, double beta) {
|
||||
return alpha * alpha + beta * beta < 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<BoundingBox> getBoundingBox() {
|
||||
var a = origin.minus(u).minus(v);
|
||||
var b = origin.plus(u).plus(v);
|
||||
return Optional.of(new BoundingBox(Vec3.min(a, b), Vec3.max(a, b)));
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package eu.jonahbauer.raytracing.scene.flat;
|
||||
|
||||
import eu.jonahbauer.raytracing.math.Range;
|
||||
import eu.jonahbauer.raytracing.math.Ray;
|
||||
import eu.jonahbauer.raytracing.math.Vec3;
|
||||
import eu.jonahbauer.raytracing.render.material.Material;
|
||||
import eu.jonahbauer.raytracing.scene.HitResult;
|
||||
import eu.jonahbauer.raytracing.scene.Hittable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class Hittable2D implements Hittable {
|
||||
protected final @NotNull Vec3 origin;
|
||||
protected final @NotNull Vec3 u;
|
||||
protected final @NotNull Vec3 v;
|
||||
private final @NotNull Material material;
|
||||
|
||||
// internal
|
||||
private final @NotNull Vec3 normal;
|
||||
private final double d;
|
||||
private final @NotNull Vec3 w;
|
||||
|
||||
protected Hittable2D(@NotNull Vec3 origin, @NotNull Vec3 u, @NotNull Vec3 v, @NotNull Material material) {
|
||||
this.origin = Objects.requireNonNull(origin);
|
||||
this.u = Objects.requireNonNull(u);
|
||||
this.v = Objects.requireNonNull(v);
|
||||
this.material = Objects.requireNonNull(material);
|
||||
|
||||
var n = u.cross(v);
|
||||
if (n.squared() < 1e-8) throw new IllegalArgumentException();
|
||||
this.normal = n.unit();
|
||||
this.d = origin.times(normal);
|
||||
this.w = n.div(n.squared());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<HitResult> hit(@NotNull Ray ray, @NotNull Range range) {
|
||||
var denominator = ray.direction().times(normal);
|
||||
if (Math.abs(denominator) < 1e-8) return Optional.empty(); // parallel
|
||||
|
||||
var t = (d - ray.origin().times(normal)) / denominator;
|
||||
if (!range.surrounds(t)) return Optional.empty();
|
||||
|
||||
var position = ray.at(t);
|
||||
var p = position.minus(origin);
|
||||
|
||||
if (!isInterior(p)) return Optional.empty();
|
||||
|
||||
var frontFace = denominator < 0;
|
||||
return Optional.of(new HitResult(t, position, frontFace ? normal : normal.neg(), material, frontFace));
|
||||
}
|
||||
|
||||
protected boolean isInterior(@NotNull Vec3 p) {
|
||||
var alpha = w.times(p.cross(v));
|
||||
var beta = w.times(u.cross(p));
|
||||
return isInterior(alpha, beta);
|
||||
}
|
||||
|
||||
protected boolean isInterior(double alpha, double beta) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package eu.jonahbauer.raytracing.scene.flat;
|
||||
|
||||
import eu.jonahbauer.raytracing.math.BoundingBox;
|
||||
import eu.jonahbauer.raytracing.math.Vec3;
|
||||
import eu.jonahbauer.raytracing.render.material.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public final class Parallelogram extends Hittable2D {
|
||||
|
||||
public Parallelogram(@NotNull Vec3 origin, @NotNull Vec3 u, @NotNull Vec3 v, @NotNull Material material) {
|
||||
super(origin, u, v, material);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInterior(double alpha, double beta) {
|
||||
return 0 <= alpha && alpha < 1 && 0 <= beta && beta < 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<BoundingBox> getBoundingBox() {
|
||||
var a = origin;
|
||||
var b = origin.plus(u).plus(v);
|
||||
return Optional.of(new BoundingBox(Vec3.min(a, b), Vec3.max(a, b)));
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package eu.jonahbauer.raytracing.scene.flat;
|
||||
|
||||
import eu.jonahbauer.raytracing.math.Vec3;
|
||||
import eu.jonahbauer.raytracing.render.material.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class Plane extends Hittable2D {
|
||||
public Plane(@NotNull Vec3 origin, @NotNull Vec3 u, @NotNull Vec3 v, @NotNull Material material) {
|
||||
super(origin, u, v, material);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInterior(@NotNull Vec3 p) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package eu.jonahbauer.raytracing.scene.flat;
|
||||
|
||||
import eu.jonahbauer.raytracing.math.BoundingBox;
|
||||
import eu.jonahbauer.raytracing.math.Vec3;
|
||||
import eu.jonahbauer.raytracing.render.material.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public final class Triangle extends Hittable2D {
|
||||
|
||||
public Triangle(@NotNull Vec3 origin, @NotNull Vec3 u, @NotNull Vec3 v, @NotNull Material material) {
|
||||
super(origin, u, v, material);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInterior(double alpha, double beta) {
|
||||
return 0 <= alpha && 0 <= beta && alpha + beta <= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<BoundingBox> getBoundingBox() {
|
||||
var a = origin;
|
||||
var b = origin.plus(u).plus(v);
|
||||
return Optional.of(new BoundingBox(Vec3.min(a, b), Vec3.max(a, b)));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue