2012-03-15 6 views
5

Đây là loại câu hỏi theo dõi cho một câu hỏi tôi hỏi trên here về làm thế nào để vẽ một applet/cửa sổ trong khi sử dụng SwingWorkerhiệu ứng động một thuật toán tam giác đệ quy sử dụng SwingWorker

Trong trường hợp đặc biệt này, tôi đang sử dụng một thuật toán phân chia và chinh phục được đề xuất bởi Guibas và stolfi để tính toán một tam giác Delaunay của một tập hợp các điểm nói P.

Thuật toán như sau: 1. Nếu sizeof (p) == 2, thêm một cạnh; return 2. Nếu sizeof (p) == 3, thêm một tam giác ngược chiều kim đồng hồ; return 3. nếu sizeof (p)> 3, chia (p) thành nửa trái và phải. tra chéo các nửa cá nhân hợp nhất nửa lại với nhau

Tôi có một lớp tam giác có phương pháp (như thể hiện trong khối code) lập lưới tam giác sẽ thực hiện các thuật toán chia để trị (theo giả mã được cung cấp bởi Guibas và 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; 
    } 

Tôi có một DrawingPanel hoạt động như lớp Canvas và vẽ hình tam giác, điểm trên bề mặt bản vẽ.

Tôi đang sử dụng SwingWorker trong lớp Triangulate chính của mình để gọi phương thức tam giác.

Dưới đây là các mã cho 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) { 

      } 
     } 
    }; 

Bây giờ, tôi muốn để animate tam giác này, bằng cách hiển thị các tam giác xuất hiện sau khi cuộc gọi đệ quy để kiểm tra chéo và sau đó là chức năng hợp nhất.

Có ai có một số gợi ý giúp tôi triển khai giải pháp không?

Tôi đã nghĩ về việc sử dụng phương pháp xuất bản và xử lý trong lớp SwingWorker, nhưng sau đó đã tìm ra điều đó sẽ dư thừa vì thuật toán phân chia và chinh phục trực tiếp đi kèm với tam giác cuối cùng.

Xin cảm ơn trước.

+2

không liên quan đến câu hỏi của bạn, chỉ là một phần mềm: không truy cập các thuộc tính ui không đồng bộ trong doInBackground (có thể hoặc không phải là trường hợp của bạn :-) – kleopatra

+1

có thể bị mù, nhưng: có vẻ như bạn không gọi điện thoại xuất bản bất cứ nơi nào trong doInBackground - có nghĩa là quá trình không bao giờ được gọi là ... – kleopatra

+0

@kleopatra Tôi đã thử gọi xuất bản nhưng nó không giúp đỡ. Cảm ơn mẹo truy cập không đồng bộ hóa. Tôi sẽ thay đổi nó. – chaitanya

Trả lời

2

Nhận xét đang đi đúng hướng. Tôi sẽ cố gắng để có phương pháp partition() báo cáo mỗi tam giác mà nó tính toán (mỗi lần nó được vượt qua 3 điểm) trở lại SwingWorker, và sau đó sẽ publish() tam giác. Một cái gì đó như thế này:

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

Xin lỗi nếu tôi đã không nhận được sắc thái đúng - Tôi giả định một QuadEdge là một hình tam giác, và tất cả những gì ...

Và chắc chắn có lời khuyên @ Kleopatra của vào tài khoản - có lẽ nhà xây dựng của SwingWorker của bạn có thể lấy List<PlanarPoint> thay vì nhận được từ bảng điều khiển trong doInBackground().

+0

Sử dụng Trình nghe làm giao diện. Rất thông minh! Tôi se thử no. Cảm ơn vì tiền hỗ trợ! – chaitanya

+0

Chỉ là một câu hỏi, bạn xác định chính xác TriangleListener như thế nào? – chaitanya

+0

OK Tôi đã chỉnh sửa câu trả lời để cho biết cách định nghĩa của TriangleListener ... Chúc may mắn! –