Я пытаюсь воспроизвести найденный апплет здесь как часть упражнения. Апплет использует алгоритм Fortune для генерации обоих; диаграмма Вороного и триангуляция Делоне. Я просто заинтересован в генерации триангуляции Делоне на плоскости и, следовательно, буду использовать инкрементные алгоритмы, то есть добавлять по 1 точке за раз. Я намереваюсь показать треугольники, генерируемые на каждом этапе, когда добавляется точка выборки.
Я использую класс SwingWorker для создания экземпляра класса Triangulate, который содержит алгоритм. Я вызываю метод triangulate внутри цикла for, который перебирает множество точек выборки при нажатии кнопки запуска в графическом интерфейсе.
Вот код для этого:
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
SwingWorker<List<Triangle>, Triangle> worker = new SwingWorker<List<Triangle>, Triangle>() {
@Override
protected List<Triangle> doInBackground() throws Exception {
Triangulate dt = new Triangulate(drawingPanel.pointsList());
dt.preTriangulate(); //Set-up a bounding triangle and obtain a random permutation of the points
List<PlanarPoint> pointsList = dt.pointsList();
for (int i = 0; i < pointsList.size(); i++) {
PlanarPoint sample = pointsList.get(i);
dt.triangulate(sample);
List<Triangle> list = dt.trianglesList(); //Obtaining the list of triangles at every stage. Good Idea??
for (int j = 0; j < list.size(); j++) {
publish(list.get(j));
}
Thread.sleep(500);
}
dt.removeTriangles(dt.trianglesList()); // Remove all the triangles containing bounding-triangle vertices
return dt.trianglesList();
}
protected void process(List<Triangle> triangles) {
for (Triangle triangle : triangles) {
g = drawingPanel.getGraphics();
PlanarPoint p1 = triangle.getVertex1();
PlanarPoint p2 = triangle.getVertex2();
PlanarPoint p3 = triangle.getVertex3();
g.drawLine((int) Math.ceil(p1.x), (int) Math.ceil(p1.y),
(int) Math.ceil(p2.x), (int) Math.ceil(p2.y));
g.drawLine((int) Math.ceil(p2.x),(int) Math.ceil(p2.y),
(int) Math.ceil(p3.x),(int) Math.ceil(p3.y));
g.drawLine((int) Math.ceil(p3.x),(int) Math.ceil(p3.y),
(int) Math.ceil(p1.x),(int) Math.ceil(p1.y));
}
}
};
worker.execute();
}
});
Вот класс Triangulate, который вычисляет триангуляцию Делануэя для набора точек:
public class Triangulate {
private List<PlanarPoint> pointsList;
private List<Triangle> triangleList;
private Triangle boundingTriangle;
private List<Edge> edgeList;
public Triangulate(List<PlanarPoint> pointsList) {
this.pointsList = pointsList;
this.triangleList = new ArrayList<Triangle>();
this.edgeList = new ArrayList<Edge>();
}
public List<Triangle> trianglesList() {
return triangleList;
}
public List<PlanarPoint> pointsList() {
return pointsList;
}
public void preTriangulate() {
boundingTriangle = getBoundingTriangle(pointsList);
triangleList.add(boundingTriangle);
randomPermutation(pointsList);
}
public void triangulate(PlanarPoint samplePoint) {
// A procedure implementing the Bowyer - Watson algorithm
// to calculate the DT of a set of points in a plane.
}
public void removeTriangles(List<Triangle> trianglesList) {
// A procedure to remove all triangles from the list sharing
// edges with the bounding-triangle
}
private Triangle getBoundingTriangle(List<PlanarPoint> pointsList) {
//Obtains a bounding-triangle for a set of points
}
public void randomPermutation(List<PlanarPoint> pointsList) {
//Obtains a random permutation of a set of points
}
}
У меня есть 3 других класса
- PlanarPoint - подкласс Point2D.Double, который реализует Comparable для обеспечения сортировки на основе y-координат
- Треугольник - класс, который определяет окружность и радиус окружности для треугольника и определяет, находится ли точка внутри окружности треугольника
- Edge - класс, который представляет Edge как класс, имеющий 2 PlanarPoints в качестве конечных точек.
DrawingPanel - класс, который действует как поверхность, на которой точки добавляются при событиях щелчка и рисуются на экране.
Теперь вот несколько проблем, которые у меня есть
- Есть ли лучший способ показать треугольники и, возможно, окружности, путем перебора набора точек и последующего вызова функции класса Triangulate для получения существующих окружностей и треугольников
- Должен ли весь рисунок быть ограниченным классом DrawingPanel, поскольку в приведенных выше фрагментах кода я рисую в классе, расширяющем JApplet / JFrame, и, таким образом, при изменении размера окна нарисованные треугольники теряются? Есть ли шаблон дизайна, которому я могу следовать?
- Оправдано ли использование SwingWorker для порождения другого потока, за исключением того факта, что время вычисления DT набора точек является трудоемкой задачей?
Если я пропустил какие-либо детали, пожалуйста, дайте мне знать
Спасибо,
Chaitanya