2012-03-15 6 views
5

Это своего рода последующего вопроса на вопрос, я спросил над here о том, как рисовать апплет/окно при использовании SwingWorkerоживляющего алгоритм рекурсивного триангуляции с помощью SwingWorker

В данном конкретном случае, я использую алгоритм разделения и покорения, предложенный Guibas и stolfi для вычисления триангуляции Delaunay множества точек, скажем P.

Алгоритм выглядит следующим образом: 1. Если sizeof (p) == 2, добавьте ребро; return 2. Если sizeof (p) == 3, добавьте ориентированный против часовой стрелки треугольник; return 3. Если sizeof (p)> 3, разделите (p) на левую и правую половинки. Triangulate отдельные половинки объединить половинки вместе

У меня есть триангуляции класс, метод (как показано в блоке кода) Triangulate будет осуществлять разделяй и властвуй алгоритм (в соответствии с псевдо-код, предоставленный 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, который действует как класс холста и красок треугольники, точки на поверхности рисования.

Я использую 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, но потом выяснил, что это будет избыточно, так как алгоритм divide и conquer напрямую встречается с окончательной триангуляцией.

Заранее спасибо.

+2

не имеет отношения к вашему вопросу, просто будьте осторожны: не обращайтесь к несинхронизированным свойствам ui в doInBackground (как может и не быть в вашем случае :-) – kleopatra

+1

может быть слепым, но: похоже, вы не звоните в редакцию где-нибудь в doInBackground - это означает, что процесс никогда не называется ... – kleopatra

+0

@kleopatra Я попытался вызвать публикацию, но это не помогло. Спасибо за несинхронизированный совет. Я изменю его. – chaitanya

ответ

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 мог взять List<PlanarPoint>, а не получать с панели в doInBackground().

+0

Использование прослушивателя в качестве интерфейса. Очень умно! Я попробую. Спасибо за совет! – chaitanya

+0

Вопрос только в том, как именно вы определяете TriangleListener? – chaitanya

+0

OK Я отредактировал ответ, чтобы показать, как определен TriangleListener ... Удачи! –