2015-08-27 27 views
0

我沒有使用任何類型的洪水填充算法的經驗。但我給了我最好的一擊。起初,我會在用戶點擊洋紅色的任何地方填充一個像素,然後經過一個循環,在每個洋紅色像素的頂部,左側,底部和右側繪製一個像素。這將需要8秒鐘才能完成特別大面積的填充。於是我又添加了一個循環,它畫出了直線洋紅色的線條,上下左右。這個時間減半了。我讓電腦畫了更多的線......左上,左上,左上,左下左......等等。現在它已經下降到了2秒鐘之間。我還能做些什麼來減少完成填充所需的時間?精煉自定義洪水填充算法(Java)

for(Point p:shiftDownPoints) 
    { 
    //down 
    for(int y = p.y+1; y<SCREEN_DIM.height; y++) 
    { 
     if(capture.getRGB(p.x,y)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x,y,Color.MAGENTA.getRGB()); 
    } 
    //up 
    for(int y = p.y-1; y>0; y--) 
    { 
     if(capture.getRGB(p.x,y)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x,y,Color.MAGENTA.getRGB()); 
    } 
    //right 
    for(int x = p.x+1; x<SCREEN_DIM.width; x++) 
    { 
     if(capture.getRGB(x,p.y)==Color.BLACK.getRGB())break; 
     else capture.setRGB(x,p.y,Color.MAGENTA.getRGB()); 
    } 
    //left 
    for(int x = p.x-1; x>0; x--) 
    { 
     if(capture.getRGB(x,p.y)==Color.BLACK.getRGB())break; 
     else capture.setRGB(x,p.y,Color.MAGENTA.getRGB()); 
    } 
    //down-right 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x+i,p.y+i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x+i,p.y+i,Color.MAGENTA.getRGB()); 
    } 
    //down-left 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x-i,p.y+i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x-i,p.y+i,Color.MAGENTA.getRGB()); 
    } 
    //up-left 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x-i,p.y-i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x-i,p.y-i,Color.MAGENTA.getRGB()); 
    } 
    //up-right 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x+i,p.y-i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x+i,p.y-i,Color.MAGENTA.getRGB()); 
    } 
    //up-up-left 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x-i,p.y-i*2)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x-i,p.y-i*2,Color.MAGENTA.getRGB()); 
    } 
    //up-left-left 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x-i*2,p.y-i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x-i*2,p.y-i,Color.MAGENTA.getRGB()); 
    } 
    //down-left-left 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x-i*2,p.y+i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x-i*2,p.y+i,Color.MAGENTA.getRGB()); 
    } 
    //down-down-left 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x-i,p.y+i*2)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x-i,p.y+i*2,Color.MAGENTA.getRGB()); 
    } 
    //down-down-right 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x+i,p.y+i*2)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x+i,p.y+i*2,Color.MAGENTA.getRGB()); 
    } 
    //down-right-right 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x+i*2,p.y+i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x+i*2,p.y+i,Color.MAGENTA.getRGB()); 
    } 
    //up-right-right 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x+i*2,p.y-i)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x+i*2,p.y-i,Color.MAGENTA.getRGB()); 
    } 
    //up-up-right 
    for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++) 
    { 
     if(capture.getRGB(p.x+i,p.y-i*2)==Color.BLACK.getRGB())break; 
     else capture.setRGB(p.x+i,p.y-i*2,Color.MAGENTA.getRGB()); 
    } 
    } 

    while(pixelsDrawn) 
    { 
    pixelsDrawn=false; 
    for(int x = 0; x<SCREEN_DIM.width; x++) 
     for(int y = 0; y<SCREEN_DIM.height; y++) 
     { 
      if(capture.getRGB(x,y)==Color.MAGENTA.getRGB()) 
      { 
       if(capture.getRGB(x-1,y)!=Color.MAGENTA.getRGB() 
       &&capture.getRGB(x-1,y)!=Color.BLACK.getRGB()) 
       { 
       capture.setRGB(x-1,y,Color.MAGENTA.getRGB()); 
       pixelsDrawn = true; 
       } 
       if(capture.getRGB(x+1,y)!=Color.MAGENTA.getRGB() 
       &&capture.getRGB(x+1,y)!=Color.BLACK.getRGB()) 
       { 
       capture.setRGB(x+1,y,Color.MAGENTA.getRGB()); 
       pixelsDrawn = true; 
       } 
       if(capture.getRGB(x,y-1)!=Color.MAGENTA.getRGB() 
       &&capture.getRGB(x,y-1)!=Color.BLACK.getRGB()) 
       { 
       capture.setRGB(x,y-1,Color.MAGENTA.getRGB()); 
       pixelsDrawn = true; 
       } 
       if(capture.getRGB(x,y+1)!=Color.MAGENTA.getRGB() 
       &&capture.getRGB(x,y+1)!=Color.BLACK.getRGB()) 
       { 
       capture.setRGB(x,y+1,Color.MAGENTA.getRGB()); 
       pixelsDrawn = true; 
       } 
      } 
     } 
    } 
+0

通常它的工作原理是,您只需檢查剛剛更改的像素旁邊的像素,而不是重複檢查整個圖像。 – immibis

+0

immibis,如果這是一個答案,我會投它爲最好的。感謝那!這是一個「哦,是的!」有時候我讀了你的評論,現在我把它降到半秒鐘。再次感謝! – user3376587

回答

0

感謝immibis的建議,我把我的洪水補給降到了半秒。在這個新代碼中,我讓計算機沿着輪廓的邊緣去創建一個多邊形,然後使用圖形中的fillPolygon。

for(Point p:iterablePoints) 
    { 
    int dir = 2; //0:right, 1:down, 2:left, 3:up 
    int xPos = p.x; 
    int yPos = 0; 
    Polygon poly = new Polygon(); 
    for(int y = p.y; y>0; y--) 
    { 
     if(capture.getRGB(p.x,y-1)==Color.BLACK.getRGB()) 
     { 
      yPos = y; 
      break; 
     } 
    } 
    Vector<Point> tempRecord = new Vector<Point>(); 
    boolean run = true; 
    while(run) 
    {    
     if(dir==0&&capture.getRGB(xPos+1,yPos)==Color.BLACK.getRGB())dir--; 
     else if(dir==1&&capture.getRGB(xPos,yPos+1)==Color.BLACK.getRGB())dir--; 
     else if(dir==2&&capture.getRGB(xPos-1,yPos)==Color.BLACK.getRGB())dir--; 
     else if(dir==3&&capture.getRGB(xPos,yPos-1)==Color.BLACK.getRGB())dir--; 
     else 
     { 
      if(dir==0)xPos++; 
      if(dir==1)yPos++; 
      if(dir==2)xPos--; 
      if(dir==3)yPos--; 

      dir++; 

      tempRecord.add(new Point(xPos,yPos)); 
      if(tempRecord.size()>1)if(tempRecord.get(0)==tempRecord.get(1))tempRecord.remove(tempRecord.firstElement()); 
      else startPoint = tempRecord.get(0); 
      if(startPoint!=null)if(startPoint.x==xPos&&startPoint.y==yPos) run=false; 
      poly.addPoint(xPos,yPos);capture.setRGB(xPos,yPos,Color.MAGENTA.getRGB()); 
     } 
     if(dir==4)dir=0; 
     if(dir==-1)dir=3; 
    } 
    Graphics cg = capture.getGraphics(); 
    cg.setColor(Color.MAGENTA); 
    cg.fillPolygon(poly); 
    cg.dispose(); 
    } 
-1

討論洪水填充算法可能需要一整堂課。我認爲你應該諮詢This Link,因爲它可以解釋所有問題,逐像素如何與算法一起繪製(高效)。希望這可以幫助。