This is kind of a follow-up question to a question I asked over here regarding how to paint an applet/window while using SwingWorker
In this particular instance, I am using a divide and conquer algorithm proposed by Guibas and stolfi to compute a Delaunay triangulation of a set of points say P.
The algorithm is as follows: 1. If sizeof(p)==2, add an edge; return 2. If sizeof(p)==3, add a counter-clockwise oriented triangle; return 3. if sizeof(p) > 3, divide(p) into left and right halves. Triangulate the individual halves merge the halves together
I have a triangulation class whose triangulate method (as shown in the code block) will implement the divide and conquer algorithm (according to the pseudo-code provided by Guibas and Stolfi)
public QuadEdge[] partition(List<PlanarPoint> list) {
QuadEdge[] convexHullEdges = new QuadEdge[2];
if (list.size() == 2) {
//Add edge
} else if (list.size() == 3) {
//Add a counter-clockwise oriented triangle
} else if (list.size() > 3) {
List<PlanarPoint> leftHalf = new ArrayList<PlanarPoint>();
List<PlanarPoint> rightHalf = new ArrayList<PlanarPoint>();
//Divide the list of points into 2 halves
QuadEdge[] leftDelaunay = triangulate(leftHalf);
QuadEdge ldo = leftDelaunay[0];
QuadEdge ldi = leftDelaunay[1];
QuadEdge[] rightDelaunay = triangulate(rightHalf);
QuadEdge rdi = rightDelaunay[0];
QuadEdge rdo = rightDelaunay[1];
// Merge the two halves
merge(ldo,ldi,rdi,rdo);
}
return convexHullEdges;
}
I have a DrawingPanel which acts as a Canvas class and paints the triangles,points on the drawing surface.
I am using a SwingWorker in my main Triangulate class to call the triangulate method.
Here's the code for the SwingWorker:
private class GuibasStolfiWorker extends
SwingWorker<List<QuadEdge>, PlanarPoint> {
@Override
protected List<QuadEdge> doInBackground() throws Exception {
// retrieve the points added by the user on the drawing surface
List<PlanarPoint> list = drawingPanel.pointsList();
Trinagulation dt = new Triangulation(list);
dt.preprocess(); // removes duplicate points
dt.triangulate();// calls the recursive divide and conquer algorithm
return dt.edgeList(); //returns the list of edges which form the final triangulation.
}
protected void process(List<PlanarPoint> chunks) {
drawingPanel.repaint();
}
public void done() {
try {
List<QuadEdge> triangles = get();
drawingPanel.setTrianglesList(triangles);
drawingPanel.repaint();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}
};
Now, I would like to animate this triangulation, by showing the triangulation appearing after the recursive call to the triangulate and then the merge function.
Does anybody have some pointers which will help me implement the solution?
I thought about using the publish and process method in the SwingWorker class, but then figured out that would be redundant since the divide and conquer algorithm directly comes up with the final triangulation.
Thanks in advance.
Comments are on the right track. I would try to have the partition()
method report each triangle that it calculates (each time it is passsed 3 points) back to the SwingWorker, and which will then publish()
the triangle. Something like this:
public interface TriangleListener {
public void reportTriangle(final QuadEdge triangle);
}
public QuadEdge[] partition(List<PlanarPoint> list, TriangleListener listener) {
QuadEdge[] convexHullEdges = new QuadEdge[2];
if (list.size() == 2) {
//Add edge
} else if (list.size() == 3) {
//Add a counter-clockwise oriented triangle
listener.reportTriangle(new QuadEdge(list));
}
...
}
private class GuibasStolfiWorker extends
SwingWorker<Void, QuadEdge> implements TriangleListener
{
...
protected void process(List<QuadEdge> chunks) {
drawingPanel.addTrianglesToList(chunks);
drawingPanel.repaint();
}
public void done() {
// Nothing to do - panel has all triangles already
}
@Override
public void reportTriangle(final QuadEdge triangle) {
publish(triangle);
}
}
public interface TriangleLsitener {
public void reportTriangle(final QuadEdge triangle);
}
Sorry if I didn't get the nuances right - I'm assuming a QuadEdge
is a triangle, and all that...
And definitely take @kleopatra's advice into account - perhaps the constructor of your SwingWorker could take the List<PlanarPoint>
rather than getting from the panel in doInBackground()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With