import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* @author wgq
* @date 2024-01-18 15:03
*/
public class Main {
protected RTreeBean<Point> troopTreeMap = new RTreeBean<>();
public static void main(String[] args) {
new Main().frame();
}
BufferedImage image = null;
public void frame() {
JFrame frame = new JFrame("Half Circle Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
JButton but = new JButton("确定");
JTextField txt = new JTextField(20);
JPanel panel = new JPanel();
panel.add(new JLabel("x:y"));
panel.add(txt);
panel.add(but);
but.addActionListener(e -> {
String[] split = txt.getText().split(":");
resetImage(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
frame.repaint();
});
frame.add(panel, BorderLayout.NORTH);
frame.add(new MyPanel(), BorderLayout.CENTER);
frame.setSize(950, 1000);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
resetImage(25, 15);
frame.repaint();
}
private void resetImage(int rx, int rz) {
int size = 30;
int width = 30;
troopTreeMap = new RTreeBean<>();
image = new BufferedImage(size * width, size * width, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.setColor(Color.BLACK);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
troopTreeMap.add(i, j, new Point(i, j));
g.drawRect(i * width, j * width, width, width);
}
}
int x = 15;
int z = 15;
int range = 10;
double span = 120;// 角度
List<Point> result = null;
result = rectCell(x, z, range);
g.setColor(Color.gray);
for (Point p : result) {
g.fillRect(p.x * width, p.z * width, width, width);
}
result = ovalCell(x, z, range);
g.setColor(Color.BLUE);
for (Point p : result) {
g.fillRect(p.x * width, p.z * width, width, width);
}
System.out.println("x = " + x + " z = " + z + " rx = " + rx + " rz = " + rz + " calcAngle = " + getDistance(x, z, rx, rz));
result = semicircleCell(x, z, rx, rz, range, span);
g.setColor(Color.GREEN);
for (Point p : result) {
g.fillRect(p.x * width, p.z * width, width, width);
}
g.setColor(Color.RED);
g.fillRect(x * width, z * width, width, width);
g.setColor(Color.CYAN);
g.fillRect(rx * width, rz * width, width, width);
g.setColor(Color.BLACK);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
g.drawRect(i * width, j * width, width, width);
g.drawString(String.valueOf(i), i * width + 2, j * width + width / 2);
g.drawString(String.valueOf(j), i * width + width / 2, j * width + width - 2);
}
}
g.drawRect(1, 1, size * width - 2, size * width - 2);
g.setColor(Color.RED);
g.drawOval((x - range) * width, (x - range) * width, (range * 2 + 1) * width, (range * 2 + 1) * width);
}
public List<Point> rectCell(float x, float z, int range) {
float xMin = x - range;
float xMax = x + range;
float yMin = z - range;
float yMax = z + range;
return troopTreeMap.query(xMin, xMax, yMin, yMax);
}
// 圆形
public List<Point> ovalCell(float x, float z, int range) {
List<Point> list = rectCell(x, z, range);
if (Objects.isNull(list)) {
return Collections.emptyList();
}
for (int i = 0; i < list.size(); i++) {
Point cell = list.get(i);
float cx = cell.getX();
float cz = cell.getZ();
double val = getDistance(x, 0, z, cx, 0, cz);
if (val > range) {
list.remove(cell);
i--;
}
}
return list;
}
public List<Point> semicircleCell(int x, int z, int rx, int rz, int range, double span) {
List<Point> list = ovalCell(x, z, range);
// 把绝对坐标换成相对坐标
List<Point> pointList = new ArrayList<>();
for (Point p : list) {
Point point = new Point(p.x - x, p.z - z);
pointList.add(point);
}
rx = rx - x;
rz = rz - z;
// 计算两点连线相对于正x轴的角度(弧度)
double dis = getDistance(rx, rz);
// 过滤半圆
for (int i = 0; i < pointList.size(); i++) {
Point cell = pointList.get(i);
float cx = cell.getX();
float cz = cell.getZ();
// 计算两点连线相对于正x轴的角度(弧度)
double degrees = getDistance(cx, cz);
System.out.println("cx = " + cx + " cz = " + cz + " " + (cx + x) + "/" + (cz + z) + " degrees = " + degrees + " == " + (dis - degrees));
if (degrees == dis) {
continue;
}
if (dis + span / 2 >= 360 && degrees < span / 2) {
degrees += 360;
} else if (degrees + span / 2 >= 360 && dis <= span / 2) {
degrees -= 360;
}
if (Math.abs(dis - degrees) > span / 2) {
pointList.remove(cell);
i--;
}
}
for (Point p : pointList) {
p.setX(p.x + x);
p.setZ(p.z + z);
}
return pointList;
}
public static double getDistance(double x1, double y1, double x2, double y2) {
double dx = x2 - x1;
double dy = y2 - y1;
double radians = Math.atan2(dy, dx);
double degrees = Math.toDegrees(radians);
if (degrees < 0) {
degrees += 360;
}
return degrees;
}
public static double getDistance(double x2, double y2) {
double radians = Math.atan2(y2, x2);
double degrees = Math.toDegrees(radians);
if (degrees < 0) {
degrees += 360;
}
return degrees;
}
public static double getDistance(float x1, float y1, float z1, float x2, float y2, float z2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1));
}
public static class Point {
int x;
int z;
public Point(int x, int z) {
this.x = x;
this.z = z;
}
public int getX() {
return x;
}
public int getZ() {
return z;
}
public void setX(int x) {
this.x = x;
}
public void setZ(int z) {
this.z = z;
}
}
public class MyPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image, 0, 0, null);
}
}
}
JAVA 圆中 任意一点 和 角度 计算 哪些点满足
最新推荐文章于 2024-07-27 17:56:15 发布