2012-08-05 42 views
5

我必須繪製蜂窩圖案並識別mousemove上的每個細胞(行,列)。 Honeycomb graph description在蜂窩狀圖案上獲取細胞座標

這就是我如何生成圖。

protected override void GenerateGridBitmap() 
    { 
     if (_circleGrid != null) 
     { 
      _circleGrid.Dispose(); 
      _circleGrid = null; 
     } 
     Bitmap _texture = new Bitmap(circleSize, circleSize); 
     using (Graphics g = Graphics.FromImage(_texture)) 
     { 
      g.SmoothingMode = SmoothingMode.HighQuality; 
      g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      g.PixelOffsetMode = PixelOffsetMode.HighQuality; 
      Rectangle r = new Rectangle(0, 0, circleSize, circleSize); 
      g.DrawEllipse(Pens.Black, r); 
     } 

     Bitmap rowBlock = new Bitmap(CanvasSize.Width - (circleSize/ 2), circleSize); 

     using (Brush b = new TextureBrush(_texture)) 
     { 
      using (Graphics g = Graphics.FromImage(rowBlock)) 
      { 
       g.CompositingQuality = CompositingQuality.HighQuality; 
       g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
       g.SmoothingMode = SmoothingMode.HighQuality; 
       g.FillRectangle(b, new Rectangle(new Point(0, 0), rowBlock.Size)); 
      } 
     } 
     //rowBlock.Save("rowblock.bmp"); 
     _circleGrid = new Bitmap(CanvasSize.Width, CanvasSize.Height); 
     using (Graphics g = Graphics.FromImage(_circleGrid)) 
     { 
      g.CompositingQuality = CompositingQuality.HighQuality; 
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
      g.SmoothingMode = SmoothingMode.HighQuality; 
      int x, y; 
      for (int i = 0; i < rows; i++) 
      { 
       x = 0; 
       if (i % 2 != 0) 
        x = (circleSize/ 2); 

       y = (i * circleSize); 
       if (i != 0) 
       { 
        y -= (VERTICAL_PIXEL_OFFSET * i); 
       } 
       g.DrawImage(rowBlock, x, y); 
       //g.DrawImage(DrawCodedCrystal(i,rowBlock), x, y); 
       Console.WriteLine(i); 
      } 
     } 
     _circleGrid.Save("grid.bmp"); 
     Console.WriteLine(_circleGrid.Size); 
     _texture.Dispose(); 
     _texture = null; 
     rowBlock.Dispose(); 
     rowBlock = null; 
    } 

和這是我正在做的事情來獲得圖的座標。但問題是我能夠完美地獲得專欄。但對於我認爲在計算中有一個小的差異。例如。在99行上,(1/4)圈表示{行98},其餘的圈表示{行99}。隨着行數的增加,偏差也隨之增加。

protected override CanvasCell GetCanvasCellAt(int x, int y) 
    { 

     Rectangle rect = GetImageViewPort(); 
     Point pt = new Point(x, y); 

     CanvasCell c = new CanvasCell() { Row = -1, Column = -1 }; 
     if (rect.Contains(pt)) 
     { 
      double zoomedCircleSize = CircleSize * ZoomFactor; 
      Point p = pt;// PointToClient(new Point(x, y)); 
      p.X -= (int)(rect.X + (AutoScrollPosition.X)); 
      p.Y -= (int)(rect.Y + (AutoScrollPosition.Y)); 

      int row = (int)((p.Y)/(zoomedCircleSize)); 
      //row = (int)((p.Y + (row * ZoomFactor))/zoomedCircleSize); 
      int col; 
      if (row % 2 != 0) 
      { 
       if (p.X >= 0 && p.X < (zoomedCircleSize/2)) 
       { 
        col = -1; 
       } 
       else 
        col = (int)((p.X - (zoomedCircleSize/2))/zoomedCircleSize); 
      } 
      else 
      { 
       if (p.X > (zoomedCircleSize * cols)) 
       { 
        col = -1; 
       } 
       else 
       { 
        col = (int)((p.X)/zoomedCircleSize); 

       } 
      } 
      //if (!GetRectangle(row, col).ContainsWithInBoundingCircle(p)) 
      //{ 
      // c.Column = -1; 
      // c.Row = -1; 
      //} 
      //else 
      { 
       c.Column = col; 
       c.Row = row; 
      } 
     } 
     // 

     return c; 
    } 

希望我清楚地解釋我的問題。

編輯: 的VERTICAL_PIXEL_OFFSET爲1和圓大小爲16

+0

也許是因爲您正在使用位圖。您可以單獨繪製圓圈,這可能有助於提高準確性。 – usr 2012-08-05 23:31:16

+0

@usr可能是,但是我將要工作的網格可以高達500行和500列(250000個圓圈),那麼這不會有太多的開銷維護許多圈子的列表,並且遍歷它們以獲得一個鼠標移動? – 2012-08-05 23:56:05

+0

「行」是用「zoomedCircleSize」除以「double」來計算的,但結果會轉換回「int」。你可能在這裏失去一些準確性。 – Slagh 2012-08-09 21:53:37

回答

2

我還張貼了這個在MSDN上,斯蒂芬·霍夫曼還跟張貼怎麼做的SSCCE。基本上這個想法是預先計算蜂窩,正如@usr在評論部分中所建議的那樣。 這裏是MSDN的帖子的鏈接。

0

快速觀察:你必須使用圓圈 - 六邊形是否可以簡化問題?

+0

是的,我必須使用圓圈。 – 2012-08-10 01:05:04