59 lines
2.0 KiB
Java
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) {
|
|
}
|
|
}
|