2012-01-26 7 views
3

アプレットを複製しようとしていますが、練習の一部としてhereが見つかりました。アプレットはFortuneのアルゴリズムを使用して両方を生成しています。 VoronoiダイアグラムとDelaunay三角測量。私は飛行機内でDelaunay三角測量を生成することに興味があり、増分アルゴリズムを使用することになります。つまり、一度に1ポイントを追加することです。サンプルポイントが追加されるたびに、生成される三角形を表示するつもりです。三角形や円を計算するために使用されるスイングワーカーからアプレットを再描画する

私はSwingWorkerクラスを使用して、アルゴリズムを含むTriangulateクラスのインスタンスを作成しています。私はGUIのスタートボタンがクリックされたときにサンプルポイントのセットを反復する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(); 
      } 
     }); 

は点の集合のDelanuay三角測量を計算三角測量クラスです:

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つの他のクラス

    を持っています
  1. PlanarPoint - y座標のソートを提供するためにComparableを実装するPoint2D.Doubleのサブクラス
  2. Triangle - 三角形の円と円の半径を決定し、点が三角形の外接円の内側にあるかどうかを決定するクラス
  3. Edge - Edgeを2つのPlanarPointをそのクラスとするクラスエンドポイント。
  4. DrawingPanel - クリックイベントでポイントが追加され、画面上に描画されるサーフェスとして機能するクラスです。

    は今、ここに私は

    1. を持っているいくつかの懸念がある点の集合を反復して、三角測量のクラスの関数を呼び出すことにより、三角形と、おそらくcircum-円を表示する良い方法はあります既存の円サークルと三角形を取得する
    2. 上記のコードスニペットでは、JApplet/JFrameを継承するクラスにペイントするので、ウィンドウのサイズが変更されるたびに描画された三角形が描画されるため、すべての図面をDrawingPanelクラスに制限する必要があります失われている?私が従うことができるデザインパターンはありますか?
    3. ポイントの集合のDTを計算する時間が時間のかかる作業であるという事実を除いて、SwingWorkerを使用して別のスレッドがここで正当化されますか?私は、任意の詳細を見逃している場合は

、私は

おかげで、 Chaitanya

+2

*「アプレットを再描画する」* BTW - 経験豊富なアプレット開発者として、ポイントとヒントを提供します。要点は、私がアプレットで新しい機能をテストすることは決してありません。アプレットを実行可能にするのは難しいですが、開発中にフレーム内のアプレットの要点を設計し、その作業UIをアプレットに最後の瞬間に転送する方が迅速です。これは多くの場合、コードの一行しか必要としない、結合されたアプレット/アプリケーションハイブリッドを開発することによって達成される。 –

+2

ハイブリッド、より簡単な[アニメーション](http://sites.google.com/site/drjohnbmatthews/subway)を参照してください。 – trashgod

+0

@ AndrewThompson、チップのおかげで。私はアプレットを実行可能にするのに問題がありました。 – chaitanya

答えて

5

提案を教えてください:

  • Graphicsオブジェクトを取得するにはgetGraphics()を使用しないでください再描画が実行された場合(コントロールから何かが外れている場合)、取得されたGraphicsオブジェクトは保持されないためです。代わりにBufferedImageに描画し、JPanelまたはJComponentにpaintComponentオーバーライドでBufferedImageを描画させるか、イメージデータを何らかのコレクションに追加して、paintComponentオーバーライドメソッドで画像を描画する情報を使用してCollectionを繰り返し処理します。
  • JFrameやJAppletなどのトップレベルウィンドウに直接描画するのではなく、JComponentから派生するコンポーネント(JComponent自体またはJPanel)に直接描画します。
  • スイングのグラフィックスチュートリアルを読むと、これ以上のことがすべて説明されます。
  • SwingWorkerは、SwingアプリケーションのバックグラウンドでありながらSwingアプリケーションと対話するスレッド(SwingWorkersが作成された状況)を作成する必要があるため、完全に正当です。
+0

getGraphics()を使用すべきでない理由は何ですか? – chaitanya

+0

@chaitanya:上に説明したので私の答えを見てください。 –

+1

答えが終わる前にページをすばやくリフレッシュしたので、最初の箇条書きポイントが表示されました。情報をありがとう、ごめんなさい、ごめんなさい。 – chaitanya