java - 如何从圆中的x和y坐标中找到扇区
问题描述
请注意,我将使用的大多数数字只是示例,因为它需要是动态的
我正在尝试使用 UTF Full Block 图标 (= █) 创建一个具有动态高度、宽度和圆形扇区的圆圈(然后将这些用于居中的 Minecraft 全息图中,因此没有一堆空间可以将其居中) .
假设我有一个 25x25(直径为 25)的圆,有 12 个(几乎相等)扇区,每个扇区都会有不同的颜色,圆的中心是 (0, 0)。我如何能够将这个圆圈“划分”为扇区并将扇区 ID(例如 0-11)放在坐标上?
下面是我目前使用的代码,getSectionNumber 方法根本不起作用,可能可以忽略:
public class HologramCircle {
private final int height;
private final int width;
public HologramCircle(final int height, final int width) {
this.height = height;
this.width = width;
}
public List<String> getLines() {
final float width_r = (float) width / 2;
final float height_r = (float) height / 2;
final float ratio = width_r / height_r;
final double maxblocks_x;
final double maxblocks_y;
if ((width_r * 2) % 2 == 0) {
maxblocks_x = Math.ceil(width_r - .5) * 2 + 1;
} else {
maxblocks_x = Math.ceil(width_r) * 2;
}
if ((height_r * 2) % 2 == 0) {
maxblocks_y = Math.ceil(height_r - .5) * 2 + 1;
} else {
maxblocks_y = Math.ceil(height_r) * 2;
}
final List<String> lines = Lists.newArrayList();
for (double y = -maxblocks_y / 2 + 1; y <= maxblocks_y / 2 - 1; y++) {
final StringBuilder line = new StringBuilder();
for (double x = -maxblocks_x / 2 + 1; x <= maxblocks_x / 2 - 1; x++) {
if (shouldBeFilled(x, y, width_r, ratio)) {
System.out.println(
String.format("Section id for x: %s and y: %s is %s", x, y, getSectorNumber(x, y, width_r, 12))
);
line.append("█");
}
}
lines.add(line.toString());
}
return lines;
}
private int getSectorNumber(final double x, final double y, final double radius, final int sectorAmount) {
final double degreesPerSector = 360 / sectorAmount;
final double rad = Math.atan2(y, x);
final double degrees = rad * (180 / Math.PI);
System.out.println("rad: " + rad + ", degrees: " + degrees);
for (int i = 0; i < sectorAmount; i++) {
final double startDegrees = degreesPerSector * i;
final double endDegrees = startDegrees + degreesPerSector;
if (degrees >= startDegrees && degrees <= endDegrees) {
return i;
}
}
return -1;
}
private double distance(final double x, final double y, final double ratio) {
return Math.sqrt((Math.pow(y * ratio, 2)) + Math.pow(x, 2));
}
private boolean shouldBeFilled(final double x, final double y, final double radius, final float ratio) {
return distance(x, y, ratio) <= radius;
}
我的解决方案:
我在 getSectionNumber 中的代码已经朝着正确的方向发展,我最终只是添加了 180°,所以它在 0-360 的范围内。这是我最终得到的代码:
package com.dbsoftwares.dangerwheel.hologram;
import com.google.common.collect.Lists;
import net.md_5.bungee.api.ChatColor;
import java.util.List;
public class HologramCircle {
private final int height;
private final int width;
public HologramCircle(final int height, final int width) {
this.height = height;
this.width = width;
}
public List<String> getLines() {
final float width_r = (float) width / 2;
final float height_r = (float) height / 2;
final float ratio = width_r / height_r;
final double maxblocks_x;
final double maxblocks_y;
if ((width_r * 2) % 2 == 0) {
maxblocks_x = Math.ceil(width_r - .5) * 2 + 1;
} else {
maxblocks_x = Math.ceil(width_r) * 2;
}
if ((height_r * 2) % 2 == 0) {
maxblocks_y = Math.ceil(height_r - .5) * 2 + 1;
} else {
maxblocks_y = Math.ceil(height_r) * 2;
}
final List<String> lines = Lists.newArrayList();
for (double y = -maxblocks_y / 2 + 1; y <= maxblocks_y / 2 - 1; y++) {
final StringBuilder line = new StringBuilder();
for (double x = -maxblocks_x / 2 + 1; x <= maxblocks_x / 2 - 1; x++) {
if (shouldBeFilled(x, y, width_r, ratio)) {
final int sector = getSectorNumber(x, y, 12);
line.append(ChatColor.values()[sector].toString());
line.append("█");
}
}
lines.add(line.toString());
}
return lines;
}
private int getSectorNumber(final double x, final double y, final int sectorAmount) {
final double degreesPerSector = 360 / sectorAmount;
final double rad = Math.atan2(y, x);
final double degrees = rad * (180 / Math.PI) + 180;
for (int i = 0; i < sectorAmount; i++) {
final double startDegrees = degreesPerSector * i;
final double endDegrees = startDegrees + degreesPerSector;
if (degrees >= startDegrees && degrees <= endDegrees) {
return i;
}
}
return -1;
}
private double distance(final double x, final double y, final double ratio) {
return Math.sqrt((Math.pow(y * ratio, 2)) + Math.pow(x, 2));
}
private boolean shouldBeFilled(final double x, final double y, final double radius, final float ratio) {
return distance(x, y, ratio) <= radius;
}
}
解决方案
推荐阅读
- homestead - fwrite(): XX 字节写入失败,errno=5 输入/输出错误
- node.js - 如何防止 MVC 架构中出现上帝模型类?
- clojure - 在 Clojure 字符串中执行函数?
- python - Python - 如何提高字符串到浮点数的转换速度
- python - 未找到模块错误:mybinder 交互式笔记本
- android - 我在 Android Studio 中看不到组模板
- typescript - 如何在带有多个变量的 console.log 中使用单引号
- htmx - htmx:hx-target:交换 html 与整页重新加载
- python - WSL 上的安装?
- c# - 我无法从 MemoryCache 中获取价值