2012-03-03 2 views
0

Unity에서 작동 할 플러드 채우기 알고리즘을 작성하려고했습니다. 아이디어는 사용자가 선택한 색상을 기반으로 검정색 - 흰색 선 그리기의 섹션을 색칠하는 것입니다. 홍수 채우기 알고리즘에 대한 여러 구현을 시도했지만 모두 호출 될 때 단일성이 중단됩니다.Unity 3D - 홍수 채우기/페인트 버킷 알고리즘이 엔진을 계속 충돌합니다.

중요한 프로젝트의 일환으로 도움이 필요하면 큰 도움이됩니다. 코드 개정, 알고리즘 설계, 또는 작업이를 얻을 수있는 다른 방법에 대한 모든 제안을 많이 주시면 감사하겠습니다 :)

코드 :

// FloodFill function 
void FloodFill() 
{ 
    // TEST - colour the clicked pixel 
    //_tex.SetPixel((int)_pixelUV.x, (int)_pixelUV.y, m_fillColour); 
    //_tex.SetPixel(_pixelX, _pixelY, m_fillColour); 


    // FLOOD FILL 
    // ---------- 

    // Create WestEast 
    List<Point> m_WestEast; 

    //get the pixel's colour 
    Color PC = new Color(_tex.GetPixel(m_StartNode.X, m_StartNode.Y).r, _tex.GetPixel(m_StartNode.X, m_StartNode.Y).g, _tex.GetPixel(m_StartNode.X, m_StartNode.Y).b); 

    //Record clicked pixel as point 
    Point node = new Point(m_StartNode.X, m_StartNode.Y); 

    //if the pixel's colour is boundary colour (black), return. 
    if(PC == Color.black) 
    { 
     return; 
    } 

    //else continue 

    // Create a list Q[] 
    m_List = new List<Point>(); 

    //add clicked pixel to Q[] 
    m_List.Add(node); 

    //for each element in Q[] 
    for(int i=0; i<m_List.Count; i++) 
    { 
     //create new WE[] and add Q[n] to it 
     m_WestEast = new List<Point>(); 
     m_WestEast.Add(node); 

     //get pixel 1 to left (w) of Q[n] 
     Point w = new Point(node.X + 1, node.Y); 
     //get colour of w 
     Color wCol = new Color(_tex.GetPixel(w.X, w.Y).r, _tex.GetPixel(w.X, w.Y).g, _tex.GetPixel(w.X, w.Y).b);  

     while(wCol != Color.black) 
     {   
      //add pixel to WE[] and repeat 
      m_WestEast.Add(w); 

      //get new w 
      w = new Point(w.X + 1, w.Y); 

      //get colour of w 
      wCol = new Color(_tex.GetPixel(w.X, w.Y).r, _tex.GetPixel(w.X, w.Y).g, _tex.GetPixel(w.X, w.Y).b);  

      //else if colour is boundary colour 
       //go to next step 
     } 

     //get pixel 1 to right (e) of Q[n] 
     Point e = new Point(node.X - 1, node.Y); 
     //get colour of w 
     Color eCol = new Color(_tex.GetPixel(e.X, e.Y).r, _tex.GetPixel(e.X, e.Y).g, _tex.GetPixel(e.X, e.Y).b);  

     while(eCol != Color.black) 
     {   
      //add pixel to WE[] and repeat 
      m_WestEast.Add(e); 

      //get new e 
      e = new Point(e.X - 1, e.Y); 

      //get colour of e 
      eCol = new Color(_tex.GetPixel(e.X, e.Y).r, _tex.GetPixel(e.X, e.Y).g, _tex.GetPixel(e.X, e.Y).b);  

      //else if colour is boundary colour 
       //go to next step 
     } 

     //for each pixel in WE[] 
     for(int j=0; j<m_WestEast.Count; j++) 
     { 
      //set the pixel to replacement colour 
      _tex.SetPixel(m_WestEast[j].X, m_WestEast[j].Y, m_fillColour); 

      //get pixel 1 to north (n) of Q[n] 
      Point n = new Point(m_WestEast[j].X, m_WestEast[j].Y - 1);  

      //get colour of n 
      Color nCol = new Color(_tex.GetPixel(n.X, n.Y).r, _tex.GetPixel(n.X, n.Y).g, _tex.GetPixel(n.X, n.Y).b); 

      //if colour is not boundary colour 
      if(nCol != Color.black) 
      { 
       //add pixel to Q[] 
       m_List.Add(n); 
      } 

      //get pixel 1 to south (s) of Q[n] 
      Point s = new Point(m_WestEast[j].X, m_WestEast[j].Y + 1);  

      //get colour of s 
      Color sCol = new Color(_tex.GetPixel(s.X, s.Y).r, _tex.GetPixel(s.X, s.Y).g, _tex.GetPixel(s.X, s.Y).b); 

      //if colour is not boundary colour 
      if(sCol != Color.black) 
      { 
       //add pixel to Q[] 
       m_List.Add(s); 
      } 
     } 

    } 

    // ---------- 

} 

답변

1

귀하의 알고리즘이 또 다시 같은 픽셀을 추가 유지 . 그것은 여러 가지 다른 문제를 가지고 있지만, 이것이 영원히 달리고 당신의 모든 기억을 다 먹어 가고 있습니다. 난 당신이 여기에 세 번째 알고리즘을 구현하려는 생각 : http://en.wikipedia.org/wiki/Flood_fill

당신이 명백한 차이는 위키 백과 알고리즘을 가지고 있다는 것입니다 :

11 N의 북쪽에 노드의 색이 목표 인 경우 색, 그러나, 당신이에 대해 테스트 ..., N의 남쪽에 노드의 색상 대상 색상 인 경우 해당 노드가
(12)를 Q로 추가

를 Q로 해당 노드를 추가 타겟의 색이 아닌 경계의 색. 알고리즘은 경계 픽셀과 다른 픽셀을 계속해서 반복해서 찾아냅니다.

당신은 너무 다른 문제가 : 당신은 마지막에 추가하여, 큐으로 목록을 사용하려는

  1. . 이것은 그것이 전체 시간을 성장하고 좋은 이유없이 많은 기억을 먹을 것을 의미합니다. Wikipedia의 알고리즘은 대기열을 사용한다고 가정하고 루프가 매번 한 항목을 대기열에서 제외합니다. 이렇게하면 알고리즘 작동이 멈추지 않아야하지만, 많은 용도로 사용하기 전에 수정해야 할 수 있습니다.
  2. 코드 복제가 많아서 알고리즘을 불필요하게 읽기 어렵게 만들고 나중에 한 곳에서 변경 한 다음 다른 곳으로 복제하는 것을 잊어 버리면 문제가 발생합니다.
관련 문제