下面是一个可能的 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);
            }
        }
    }
}

这个程序创建了一个图形用户界面,包含一个按钮和一个标签。点击按钮后,将随机生成线段和干扰线段,并找出不被干扰的最短线段。生成的线段和最短线段将显示在绘图面板上,并加粗标出最短线段。如果不存在不被干扰的最短线段,则标签将显示'不存在'。

Java 实现:查找最短无遮挡线段

原文地址: https://www.cveoy.top/t/topic/o2jM 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录