Среда программирования:
IntelliJ IDEA
Статья по теме:
Пример триангуляции многоугольника. Программа получает координаты x, y по щелчку мыши, получает нужные вершины и производит триангуляцию по часовой или против часовой стрелки, в зависимости от входящих значений.
Используется встроенные класс Polygon для хранения и триангуляции многоугольника, результат выдоится на JPanel.
Код программы:
View:
import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.awt.Stroke; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import javax.swing.*; public class View extends JPanel { //Массив для всех точек private ArrayList<Point> points = new ArrayList<>(); //Массив для всех треугольников private ArrayList<Polygon> triangles = new ArrayList<>(); //Линия и ее стиль private Stroke stroke = new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); //Передаем в конструктор размер окна, подключаем мышку public View() { setPreferredSize(new Dimension(600, 480)); MouseHandler mouseHandler = new MouseHandler(); addMouseListener(mouseHandler); addMouseMotionListener(mouseHandler); } //Отрисовка на экране @Override protected void paintComponent(Graphics g) { super.paintComponent(g); drawPolygon((Graphics2D) g); drawTriangles((Graphics2D) g); } //Функция создания линии для многоугольника по 2ум точках и установка цвета для линии private void drawPolygon(Graphics2D g) { g.setStroke(stroke); for (int p = 0; p < points.size(); p++) { // Пробегаемся по всем точкам Point p1 = points.get(p % points.size()); Point p2 = points.get((p + 1) % points.size()); g.setColor(Color.BLUE); g.drawLine(p1.x, p1.y, p2.x, p2.y); //Линия между двумя точками } } //Контур и заполнение треугольников private void drawTriangles(Graphics2D g) { g.setStroke(stroke); //Проход по всем элементам массива треугольников for(int index = 0; index < triangles.size(); index++) { Polygon triangle = triangles.get(index); //Контур g.setColor(Color.BLUE); g.drawPolygon(triangle); //Заливка g.setColor(new Color((int)(Math.random() * 0x1000000))); g.fillPolygon(triangle); } } // Триангуляция многоугольника private void triangulatePolygon() { boolean clockwise = isClockwise(points); int index = 0; while (points.size() > 2) { //Циклическая проверка для триангуляции Point p1 = points.get((index) % points.size()); Point p2 = points.get((index + 1) % points.size()); //Получаем 3 вершины Point p3 = points.get((index + 2) % points.size()); Vec2 v1 = new Vec2(p2.x - p1.x, p2.y - p1.y); Vec2 v2 = new Vec2(p3.x - p1.x, p3.y - p1.y); double cross = v1.cross(v2); //Векторное произведение Polygon triangle = new Polygon(); // Добавляем вершины в треугольник triangle.addPoint(p1.x, p1.y); triangle.addPoint(p2.x, p2.y); triangle.addPoint(p3.x, p3.y); System.out.println("cross = " + cross); //Вывод в консоль значения /*Если значение векторного произведения > 0, то многоугольник строился по часовой стрелке, проверяем на возможность существования треугольника */ if (!clockwise && cross >= 0 && validTriangle(triangle, p1, p2, p3, points)) { points.remove(p2); //Исключаем вершину triangles.add(triangle); //Строим треугольник System.out.println("По часовой"); } else if (clockwise && cross <= 0 && validTriangle(triangle, p1, p2, p3, points)) { points.remove(p2); triangles.add(triangle); System.out.println("Против часовой"); } else { index++; //Для перехода на следующие точки увеличиваем индекс } } if (points.size() < 3) { //Убираем из массива точки, которые уже построились points.clear(); } } //Проверка действительности треугольника public boolean validTriangle(Polygon triangle, Point p1, Point p2, Point p3, List<Point> points) { for (Point p : points) { if (p != p1 && p != p2 && p != p3 && triangle.contains(p)) { return false; } } return true; } // Для проверки оборота, по часовой стрелке если сумма больше или равна 0 public boolean isClockwise(List<Point> points) { int sum = 0; for (int i = 0; i < points.size(); i++) { Point p1 = points.get(i); Point p2 = points.get((i + 1) % points.size()); sum += (p2.x - p1.x) * (p2.y + p1.y); } return sum >= 0; } //Инициализация окна public static void main(String[] args) { View view = new View(); JFrame frame = new JFrame(); frame.add(view); frame.pack(); frame.setLocationRelativeTo(null); frame.setResizable(false); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); view.requestFocus(); } //Обработка мышки private class MouseHandler extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { points.add(new Point(e.getX(), e.getY())); //Добавление в массив точки, получение координат x, y мыши } else if (SwingUtilities.isRightMouseButton(e)) { triangulatePolygon(); // Вызов триангляции } else if (SwingUtilities.isMiddleMouseButton(e)) { triangles.clear(); //Очищаем все элементы массива } repaint(); //Перерисовываем элементы на окне, после каждого действия } } }
Vec2:
public class Vec2 { public double x; public double y; public Vec2(double x, double y) { // конструктор с аргументами x, y this.x = x; this.y = y; } public double cross(Vec2 v) { return x * v.y - y * v.x; } //Векторное произвдение }
Прикрепленный файл | Размер |
---|---|
TrinagulationJava.rar | 12.47 кб |