2016-08-16 5 views
0

(これに新しく、基本的なペイントアプリケーションで遊んでいる)Iveはflood-fillをコードする詳細な手順を見つけましたが、新しくなったので、そのすべてのビットを理解することは非常に難しく、コピーする代わりに、私自身の簡単な(小規模な)洪水氾濫を​​試みてください。描画されたパス間にFillpathをマウス入力で使用します。

fillpathをflood-fillとして使用できますか?私はパスを描き、私のマウスを使ってx、y、画面上を決定し、グラフィックパスに境界線(描画されたパスからの点)があるかどうかを調べ、もしそうなら、

これは私が思いついたものですが、明らかにそれはうまくいかないので、どうすればこの問題を解決できますか?

namespace WindowsFormsApplication3 
{ 
public partial class Form1 : Form 
{ 
    Graphics g; 
    readonly Pen pen = new Pen(Color.Navy, 2); 
    Point oldCoords; 
    GraphicsPath graphicsPaths = new GraphicsPath(); 
    bool spaceFound = false; 


    public Form1() 
    { 
     InitializeComponent(); 
     g = panel1.CreateGraphics(); 
    } 

    private void panel1_MouseDown(object sender, MouseEventArgs e) 
    { 
     Point mousePt = new Point(e.X, e.Y); 

     if (e.Button == MouseButtons.Right &&    
       graphicsPaths.IsVisible(mousePt)) 
     { 
      spaceFound = true; 
     } 
    } 

    private void panel1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      if (oldCoords.IsEmpty) 
       graphicsPaths.StartFigure(); 
      else 
      { 
       graphicsPaths.AddLine(oldCoords, new Point(e.X, e.Y)); 
       g.DrawPath(pen, graphicsPaths); 
      } 
      oldCoords = new Point(e.X, e.Y); 
     } 
     else 
      oldCoords = Point.Empty; 
    } 

    private void panel1_MouseUp(object sender, MouseEventArgs e) 
    { 

    } 

    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     g.DrawPath(pen, graphicsPaths); 

     if(spaceFound == true) 
     { 
      g.FillPath(Brushes.AliceBlue, graphicsPaths); 
     } 
    } 
    } 

}

答えて

1

はい、これはかなり可能です。 Windingpath.FillModeを設定

  • :もちろん、あなたがあなたのコード内のいくつかの問題を修正する必要が

    ...もっと満たされた形状を可能にするためにMouseUpイベントにList<GraphicsPath>にパスを保存したいです

  • 決して
  • キャッシュ Graphics object
  • 決して使用control.CreateGraphics()
  • たぶん、あなた:0
  • は、最後の点ここで実際に適用される場合があります

を存続あなたはに描画をしたくない場合を除き、Paintイベントに描くだけPensまたはBrushes

  • をキャッシュしないでください。 現在図面のアウトラインを表示したままにしますか?その場合、その場合は、MouseMoveに描画することができ、Graphicsオブジェクトがオンザフライで作成されます。 、

    Point oldCoords; 
    GraphicsPath graphicsPaths = new GraphicsPath() { FillMode = FillMode.Winding }; 
    bool spaceFound = false; 
    
    private void drawPanel1_MouseDown(object sender, MouseEventArgs e) 
    { 
        if (e.Button == MouseButtons.Right && graphicsPaths.IsVisible(e.Location)) 
        { 
         spaceFound = true; 
         drawPanel1.Invalidate(); 
        } 
    } 
    
    private void drawPanel1_MouseMove(object sender, MouseEventArgs e) 
    { 
        if (e.Button == MouseButtons.Left) 
        { 
         if (oldCoords.IsEmpty) graphicsPaths.StartFigure(); 
         else 
         { 
          graphicsPaths.AddLine(oldCoords, new Point(e.X, e.Y)); 
          drawPanel1.Invalidate(); 
         } 
         oldCoords = new Point(e.X, e.Y); 
        } 
        else oldCoords = Point.Empty; 
    } 
    
    private void drawPanel1_Paint(object sender, PaintEventArgs e) 
    { 
        using (Pen pen = new Pen(Color.Black, 2f)) 
         e.Graphics.DrawPath(pen, graphicsPaths); 
    
        if (spaceFound == true) 
        { 
         e.Graphics.FillPath(Brushes.AliceBlue, graphicsPaths); 
        } 
    } 
    

    それは常に全体のパスを記入します。すなわち、それはではなく、真のFLOODFILLの方法であなたのパスを記入すること:

    ここenter image description here

    が修正バージョンです真のフラッドフィルのためには、クリック位置から始まるすべての隣接ピクセルを実際に通過するコードが必要です。

    実際のfloodfillの例はherehere

  • +0

    です。これはすごくクールですが、あなたは多くを知っているようです、ありがとうございます。私はしようとすると、リストにパスを格納するfigueアウト私はそれの中に別の色の塗りつぶしで複数の図形を持つことができます。あなたは昨日私の素晴らしい例を見せました。 –

    +0

    あなたのパスを埋めるが、真のフラッドフィルの方法ではないことに注意してください。あなたがクリックした最も内側のセグメントだけでなく、常にパス全体を塗りつぶします。真のfloodfillでは、クリック位置から始まるすべての隣接ピクセルを実際に通過するより複雑なコードが必要です。 – TaW

    +0

    だから私はできませんリストに塗りつぶしを保存し、そのリストを新しいリストに格納して、最初のリストをクリアするなどします。新しい図形を埋めることができるようにするには? –

    関連する問題