Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting cell co ordinates on Honeycomb pattern

I have to draw a honeycomb pattern and recognize each cell(row,column) on mousemove. Honeycomb graph description

this is how i am generating the graph.

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;
    }

and this what i am doing to get the coordinates of the graph. but the problem is i am able to get the column perfectly. but for the row i think there is a small difference in calculation. for eg. on the 99 row, for the (1/4) circle it say {row 98} and for the remaining circle it says {row 99}. the deviation increases as the number of rows increases.

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;
    }

hope i was clear in explaining my problem.

EDIT: the VERTICAL_PIXEL_OFFSET is 1 and the circle size is 16

like image 365
Naveed Quadri Avatar asked Nov 04 '22 18:11

Naveed Quadri


1 Answers

I also posted this on msdn, Stefan Hoffmann was kind enough to post an SSCCE of how to do that. Basically the idea was to precalculate the honeycombs, as @usr suggested in the comments section. Here is the link to MSDN post.

like image 138
Naveed Quadri Avatar answered Nov 09 '22 23:11

Naveed Quadri