2012-03-15 58 views
5

這是怎麼樣的一個後續問題的問題,我問過here關於如何同時使用的SwingWorker使用的SwingWorker

在這種特定情況下畫一個小程序/窗口動畫遞歸三角算法,我使用的是由Guibas和stolfi提出的分而治之算法來計算一組點的Delaunay三角剖分,例如P.

該算法如下: 1.如果sizeof(p)== 2,則添加一條邊;返回 2.如果sizeof(p)== 3,則添加一個逆時針方向的三角形;返回 3.如果sizeof(p)> 3, 將(p)分成左右兩半。 三角測量個體半部 半部一起合併

我有一個三角測量類,其三角測量方法(如代碼塊示出)將執行分而治之算法(根據由Guibas和斯托爾菲提供的僞代碼)

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; 
    } 

我有一個DrawingPanel,它作爲一個Canvas類並繪製三角形,繪製表面上的點。

我在我的主Triangulate類中使用SwingWorker來調用triangulate方法。

下面是對的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) { 

      } 
     } 
    }; 

現在,我想這個動畫三角測量,通過顯示遞歸調用三角測量,然後合併功能後出現的三角測量。

有沒有人有一些指標,這將有助於我實施解決方案?

我曾考慮過在SwingWorker類中使用發佈和處理方法,但後來發現這將是多餘的,因爲分而治之算法直接與最終的三角測量相提並論。

在此先感謝。

+2

與您的問題無關,只需注意:不要訪問doInBackground中的不同步ui屬性(可能或不一定是您的情況:-) – kleopatra 2012-03-15 11:36:01

+1

也許是盲目的,但是:看起來您並未調用發佈在任何地方在doInBackground - 這意味着過程永遠不會被稱爲... – kleopatra 2012-03-15 11:38:44

+0

@kleopatra我試圖調用發佈,但它沒有幫助。感謝非同步的訪問提示。我會改變它。 – chaitanya 2012-03-15 14:59:18

回答

2

評論是正確的。我會嘗試讓partition()方法將它計算的每個三角形(每次傳遞3個點)報告給SwingWorker,然後將這個三角形作爲publish()。事情是這樣的:

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); 
} 

很抱歉,如果我沒有得到正確的細微差別 - 我假設一個QuadEdge是一個三角形,這一切...

絕對拿@克列奧帕特拉的意見考慮在內 - 也許你的SwingWorker的構造函數可以採用​​而不是從doInBackground()的面板中獲取。

+0

使用Listener作爲接口。非常聰明!我會嘗試一下。謝謝你的提示! – chaitanya 2012-03-16 00:28:08

+0

只是一個問題,你會如何定義TriangleListener? – chaitanya 2012-03-16 00:44:04

+0

好的,我編輯了答案來顯示TriangleListener是如何定義的......祝你好運! – 2012-03-16 13:46:28