Java 实现:查找最短无遮挡线段
下面是一个可能的 Java 实现:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class ShortestLine implements ActionListener {
private JFrame frame;
private JPanel panel;
private JButton generateButton;
private JLabel shortestLineLabel;
private ArrayList<Line> lines;
private ArrayList<Line> interferenceLines;
private Line shortestLine;
public static void main(String[] args) {
ShortestLine shortestLine = new ShortestLine();
shortestLine.createGUI();
}
public void createGUI() {
frame = new JFrame('Shortest Line');
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(new BorderLayout());
generateButton = new JButton('Generate Lines');
generateButton.addActionListener(this);
shortestLineLabel = new JLabel();
panel.add(generateButton, BorderLayout.NORTH);
panel.add(shortestLineLabel, BorderLayout.CENTER);
frame.getContentPane().add(panel);
frame.setSize(800, 600);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == generateButton) {
generateLines();
findShortestLine();
panel.repaint();
}
}
public void generateLines() {
lines = new ArrayList<>();
interferenceLines = new ArrayList<>();
Random random = new Random();
int n = random.nextInt(31) + 10; // 10 <= n <= 40
for (int i = 0; i < n; i++) {
int x1 = random.nextInt(700) + 50;
int y1 = random.nextInt(500) + 50;
int x2 = random.nextInt(700) + 50;
int y2 = random.nextInt(500) + 50;
Line line = new Line(x1, y1, x2, y2);
lines.add(line);
if (random.nextBoolean()) {
int xi = random.nextInt(700) + 50;
int yi = random.nextInt(500) + 50;
Line interferenceLine = new Line(x1, y1, xi, yi);
interferenceLines.add(interferenceLine);
}
}
}
public void findShortestLine() {
shortestLine = null;
double shortestDistance = Double.MAX_VALUE;
for (Line line : lines) {
boolean isInterfered = false;
for (Line interferenceLine : interferenceLines) {
if (line.intersects(interferenceLine)) {
isInterfered = true;
break;
}
}
if (!isInterfered) {
double distance = line.distance();
if (distance < shortestDistance) {
shortestDistance = distance;
shortestLine = line;
}
}
}
if (shortestLine != null) {
shortestLine.setBold(true);
shortestLineLabel.setText('Shortest line: ' + shortestLine.toString());
} else {
shortestLineLabel.setText('No shortest line found.');
}
}
class Line {
private int x1, y1, x2, y2;
private boolean isBold;
public Line(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.isBold = false;
}
public void setBold(boolean isBold) {
this.isBold = isBold;
}
public boolean intersects(Line line) {
int x3 = line.x1;
int y3 = line.y1;
int x4 = line.x2;
int y4 = line.y2;
int d1 = direction(x3, y3, x4, y4, x1, y1);
int d2 = direction(x3, y3, x4, y4, x2, y2);
int d3 = direction(x1, y1, x2, y2, x3, y3);
int d4 = direction(x1, y1, x2, y2, x4, y4);
return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0));
}
private int direction(int x1, int y1, int x2, int y2, int x3, int y3) {
return (x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1);
}
public double distance() {
return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
}
public void draw(Graphics2D g2) {
if (isBold) {
g2.setStroke(new BasicStroke(3));
} else {
g2.setStroke(new BasicStroke(1));
}
g2.drawLine(x1, y1, x2, y2);
}
public String toString() {
return '(' + x1 + ', ' + y1 + ') to (' + x2 + ', ' + y2 + ')';
}
}
class DrawingPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Line line : lines) {
line.draw(g2);
}
for (Line interferenceLine : interferenceLines) {
g2.setColor(Color.RED);
interferenceLine.draw(g2);
}
if (shortestLine != null) {
g2.setColor(Color.BLUE);
shortestLine.draw(g2);
}
}
}
}
这个程序创建了一个图形用户界面,包含一个按钮和一个标签。点击按钮后,将随机生成线段和干扰线段,并找出不被干扰的最短线段。生成的线段和最短线段将显示在绘图面板上,并加粗标出最短线段。如果不存在不被干扰的最短线段,则标签将显示'不存在'。
原文地址: https://www.cveoy.top/t/topic/o2jM 著作权归作者所有。请勿转载和采集!