Files
purpur-base/src/main/java/games/dmg/spigotbase/BaseBorderGeometry.java
T
dmg 26aeb8c416
Release / release (push) Successful in 2m18s
CI / build (push) Successful in 1m1s
feat(border): add base boundary particles
2026-08-10 22:12:16 -04:00

59 lines
2.0 KiB
Java

package games.dmg.spigotbase;
import java.util.ArrayList;
import java.util.List;
final class BaseBorderGeometry {
static final int MAX_PARTICLES = 64;
static final double VISIBILITY_DISTANCE = 32.0;
private static final double PARTICLE_SPACING = 1.0;
private BaseBorderGeometry() {
}
static List<Point> visiblePoints(
double centerX,
double centerZ,
int radius,
double playerX,
double playerZ
) {
if (radius <= 0) {
throw new IllegalArgumentException("border radius must be positive");
}
double playerRadius = Math.hypot(playerX - centerX, playerZ - centerZ);
if (Math.abs(playerRadius - radius) > VISIBILITY_DISTANCE) {
return List.of();
}
double circumference = 2.0 * Math.PI * radius;
int count = Math.min(MAX_PARTICLES, Math.max(1, (int) Math.ceil(
circumference / PARTICLE_SPACING
)));
double centerAngle = Math.atan2(playerZ - centerZ, playerX - centerX);
double angleStep = circumference <= MAX_PARTICLES * PARTICLE_SPACING
? 2.0 * Math.PI / count
: PARTICLE_SPACING / radius;
double startAngle = circumference <= MAX_PARTICLES * PARTICLE_SPACING
? 0.0
: centerAngle - angleStep * (count - 1) / 2.0;
List<Point> points = new ArrayList<>(count);
double visibilitySquared = VISIBILITY_DISTANCE * VISIBILITY_DISTANCE;
for (int index = 0; index < count; index++) {
double angle = startAngle + angleStep * index;
double x = centerX + radius * Math.cos(angle);
double z = centerZ + radius * Math.sin(angle);
double deltaX = x - playerX;
double deltaZ = z - playerZ;
if (deltaX * deltaX + deltaZ * deltaZ <= visibilitySquared) {
points.add(new Point(x, z));
}
}
return List.copyOf(points);
}
record Point(double x, double z) {
}
}